Что в php является представлением отсутствия значения
Note: empty array is converted to null by non-strict equal ‘==’ comparison. Use is_null() or ‘===’ if there is possible of getting empty array.
5 years ago
NULL is supposed to indicate the absence of a value, rather than being thought of as a value itself. It’s the empty slot, it’s the missing information, it’s the unanswered question. It’s not a jumped-up zero or empty set.
This is why a variable containing a NULL is considered to be unset: it doesn’t have a value. Setting a variable to NULL is telling it to forget its value without providing a replacement value to remember instead. The variable remains so that you can give it a proper value to remember later; this is especially important when the variable is an array element or object property.
It’s a bit of semantic awkwardness to speak of a «null value», but if a variable can exist without having a value, the language and implementation have to have something to represent that situation. Because someone will ask. If only to see if the slot has been filled.
2 years ago
I would like to add for clarification that:
—$x;
// $x is still NULL.
// Decrementing NULL, using Decrement Operator, gives NULL.
$x-=1;
// $x is now int(-1).
// This actually decrements value by 1.
On the other hand, Incrementation works simply as expected.
Hope this helps 🙂
5 years ago
Note: Non Strict Comparison ‘==’ returns bool(true) for
Use Strict Comparison Instead
Типы данных
Во всех языках программирования предусмотрена та или иная система типов, которая регламентирует все возможные разновидности значений, применяемых в программах. Разнообразие типов часто отражает наличие разных форматов представления данных в памяти компьютера на уровне битов, хотя во многих случаях программисты избавлены от необходимости учитывать, какое битовое представление имеют данные (или даже лишены возможности обращаться к таким битовым представлениям).
Система типов языка PHP является простой, изящной и гибкой; к тому же она избавляет программиста от необходимости учитывать подробности реализации средств хранения данных на низком уровне. Язык PHP позволяет программисту снять с себя основную часть забот, связанных с определением типов переменных и значений, во-первых, потому, что не требует типизации переменных, а во-вторых, в связи с тем, что выполняет значительную часть преобразований типов автоматически, от имени программиста.
Общие сведения о типах
В языке PHP предусмотрено всего восемь типов: целые числа, числа с плавающей точкой двойной точности, логические значения, строковые значения, массивы, объекты, значения NULL и ресурсы.
- Целочисленные значения представляют собой целые числа без десятичной точки, такие как 495.
- Числа с плавающей точкой двойной точности — это числа с плавающей точкой наподобие 3.14159 или 49.0, имеющие наибольший возможный формат представления.
- Логические значения принимают только два возможных значения: TRUE и FALSE.
- Значение NULL — это специальный тип, который имеет только одно значение: NULL.
- Строки — это последовательности символов, например ‘PHP поддерживает работу со строками’.
- Массивы представляют собой именованные и индексированные коллекции других значений.
- Объекты — это экземпляры определяемых программистом классов, которые могут включать не только значения других типов, но и функции, относящиеся к соответствующему классу.
- Ресурсами называют специальные переменные, которые хранят ссылки на ресурсы, внешние по отношению к интерпретатору PHP (такие как соединения с базой данных).
Первые пять из этих типов являются простыми типами, а следующие два типа (массивы и объекты) — составными. Различия между простыми и составными типами заключаются в том, что составные типы могут применяться для представления произвольных значений произвольных типов, а простые типы этого не позволяют. В этой статье кратко рассматриваются только простые типы.
Отсутствие объявлений типов переменных
Тип переменной не требуется объявлять заранее. Вместо этого программист может перейти непосредственно к выполнению операции присваивания и дать возможность интерпретатору PHP заняться определением типа присваиваемого значения выражения, как показано в следующем примере:
$pi = 3.14159; $str = 'PHP поддерживает работу со строками';
Автоматическое преобразование типов
В языке PHP предусмотрены удобные способы автоматического преобразования типов в случае необходимости. Как и в большинстве других современных языков программирования, в языке PHP выполняются правильные действия, например, при вычислении математических выражений со смешанными числовыми типами. В частности, результатом выполнения выражения:
$pi = 3 + 0.14159;
является число с плавающей точкой (двойной точности), причем целое число 3 неявно преобразуется в число с плавающей точкой перед выполнением операции сложения.
Типизация с учетом контекста
В языке PHP предусмотрены средства автоматического преобразования типов, намного более удобные по сравнению с большинством других языков. Рассмотрим такой пример:
$sub = substr(12345, 2, 2); print("\$sub = $sub");
Функция substr предназначена для выделения подстроки из строки символов. В качестве первого параметра эта функция принимает строку символов и возвращает подстроку этой строки, начальная позиция которой и длина определяются следующими двумя входными параметрами функции. Но в данном случае функции substr вместо символьной строки передано целое число 12345. Что при этом происходит? Как оказалось, ошибка не возникает, а в окне браузера появляются следующие выходные данные:

Поскольку для функции substr требуется символьная строка, а не целое число, интерпретатор PHP преобразует число 12345 в символьную строку «12345» которая затем поступает на обработку в функцию substr.
Поскольку в языке PHP предусмотрено такое автоматическое преобразование типов, ошибки из-за несовместимости типов активизируются интерпретатором PHP очень редко. В действительности иногда программисту, работающему на языке PHP, приходится проявлять некоторую осмотрительность, для того чтобы путаница с типами не приводила к получению вырабатываемых без ошибок, но и не предусмотренных программистом результатов.

Простые типы
Простые типы, применяемые в языке PHP (целые числа, числа с плавающей точкой двойной точности, логические значения, значения NULL и строковые значения), должны быть в основном знакомы тем, кто имеет опыт в программировании (но мы не предполагаем наличие у читателя такого опыта, поэтому дадим подробное описание простых типов). Единственным, что может удивить программистов, работающих на языке C, является то, насколько мало количество типов в языке PHP.
Во многих языках программирования применяются числовые типы с несколькими форматами представления, с учетом того, что числовые типы, имеющие более крупные форматы, обеспечивают представление более широкого диапазона значений, но требуют также больше места в памяти.
Например, в языке C предусмотрены тип short (для относительно небольших целых чисел), тип long (для чисел, которые могут оказаться весьма большими) и тип int (который может быть промежуточным между этими двумя типами, но на практике иногда рассматривается как идентичный либо типу short, либо long). Имеются также разные типы данных с плавающей точкой, которые отличаются по своей точности. Такого рода разнообразие типов имело смысл в то время, когда приходилось часто принимать очень жесткие компромиссные решения, выбирая между требованиями уменьшения объема используемой памяти и сохранения функциональных возможностей. По нашему мнению, проектировщики языка PHP приняли разумное решение по упрощению системы типов, предусмотрев только два числовых типа, соответствующих одному целочисленному типу и одному типу с плавающей точкой языка C (с наибольшими форматами представления).
Целые числа
Целочисленные значения относятся к самому простому типу — соответствуют простым целым числам, как положительным, так и отрицательным. Целочисленные значения могут присваиваться переменным или использоваться в выражениях, как показано в следующем примере:
$int_var = 12345; $another_int = -12345 + 12345; // Результат будет равен нулю
Форматы чтения
Целые числа фактически могут считываться в трех форматах, которые соответствуют основаниям систем счисления: десятичной (с основанием 10), восьмеричной (с основанием 8) и шестнадцатеричной (с основанием 16). Десятичный формат применяется по умолчанию, восьмеричные целые числа задаются с помощью ведущей цифры 0, а шестнадцатеричные — с помощью префикса 0x. Любой из этих форматов предусматривает возможность применения в качестве префикса знака минуса (-), который позволяет указать, что целое число является отрицательным. Рассмотрим следующий пример:
$integer_10 = 1000; $integer_8 = -01000; $integer_16 = 0x1000; print("integer_10: $integer_10
"); print("integer_8: $integer_8
"); print("integer_16: $integer_16
");
Выполнение этого кода приводит к выводу в окне браузера такого текста:

Следует отметить, что от формата чтения зависит только то, каким образом осуществляется преобразование целого числа при чтении этого числа интерпретатором PHP, поэтому значение, хранящееся в переменной $integer_8, не содержит информации о том, что было первоначально представлено по основанию 8. Разумеется, форматом внутреннего представления этих чисел является двоичный формат, поэтому в приведенном выше выводе значения этих переменных показаны в виде чисел, преобразованных в десятичные числа, поскольку такое преобразование применяется по умолчанию при выводе и включении переменных со значениями типа int в строки.
Диапазон представления
Насколько большие (или малые) значения могут принимать целочисленные данные? На этот вопрос трудно дать однозначный ответ, поскольку тип целых чисел PHP соответствует типу long языка C, который, в свою очередь, зависит от размера машинного слова компьютера. Но на большинстве широко используемых платформ наибольшее целое число равно 2 31 — 1 (или 2 147 483 647), а наименьшее равно — (2 31 — 1) (или -2 147 483 647).
Чтобы узнать, каковым является наибольшее целое число для конкретной реализации, можно воспользоваться константой PHP_INT_MAX языка PHP. Если в программе действительно требуются целые числа, которые больше или меньше тех значений, которые приведены выше, то в языке PHP предусмотрены некоторые функции для работы с числами произвольной точности (подробнее об этом речь пойдет в одной из следующих статей).
Числа с плавающей точкой двойной точности
Примеры чисел с плавающей точкой двойной точности приведены ниже:
$first_double = 123.456; $second_double = 0.456; $even_double = 2.0;
Следует отметить, что присваивание переменной $even_double числового значения без значащих цифр после точки не влечет за собой то, что вместо числа с плавающей точкой присваивается целое число. Целые числа и числа с плавающей точкой двойной точности записываются в память с помощью разных форматов представления, поэтому результатом выполнения следующего примера становится присваивание числа с плавающей точкой, а не целого числа, даже несмотря на то, что это значение выводится как 5:
$five = $even_double +3;
Но почти в любых ситуациях пользователь может применять в математических выражениях произвольные сочетания чисел с плавающей точкой двойной точности и целых чисел и предоставлять возможность решать проблемы, связанные с определением типов для соответствующих значений, интерпретатору PHP.
Форматы чтения
Типичным форматом чтения для чисел с плавающей точкой двойной точности является формат -X.Y, в котором необязательный символ «-» определяет отрицательное число, а компоненты X и Y представляют собой последовательности цифр от 0 до 9. Если число находится в пределах от -1.0 до 1.0, то часть X может быть исключена; может быть также исключена и часть Y. Ведущие и заключительные нули игнорируются. Все приведенные ниже числа с плавающей точкой являются допустимыми:
$small_positive = 0.12345; $small_negative = -.12345; $even_double = 2.00000; $still_double = 2.;
Кроме того, числа с плавающей точкой двойной точности можно задавать в экспоненциальном формате, добавляя в конце приведенного выше формата с плавающей точкой (который рассматривается в экспоненциальном формате как мантисса) букву «e» и требуемое целочисленное значение степени 10 (показатель степени). Например, обозначение 2.2e-3 в экспоненциальном формате соответствует значению 0.0022.
Логические значения
Логическими называют истинностные значения, которые используются в таких конструкциях, позволяющих управлять ходом выполнения программы, как часть оператора if, в которой происходит проверка условия. Логические значения могут комбинироваться с применением логических операций для получения более сложных логических выражений.
Логические константы
В языке PHP предусмотрена пара констант, специально предназначенных для использования в качестве логических констант. Это — константы TRUE и FALSE, которые могут применяться примерно следующим образом:
if (TRUE) print("Этот текст всегда будет печататься
"); else print("Этот текст никогда не будет напечатан
");
Интерпретация значений других типов как логических значений
Ниже приведены правила определения истинности любого значения, которое еще не является логическим:
- Если значение является числовым и точно равно нулю, то рассматривается как ложное, все прочие числовые значения считаются истинными.
- Если значение является строковым, то рассматривается как ложное, если строка пуста (имеет длину, равную нулю) или представляет собой строку «0», и как истинное в противном случае.
- Значения NULL всегда являются ложными.
- Если значение имеет составной тип (представляет собой массив или объект), то рассматривается как ложное, если не содержит других значений, и как истинное в противном случае. Объект считается содержащим значение, если в его состав входит переменная экземпляра, которой было присвоено значение.
- Действительные ресурсы рассматриваются как истинные (хотя некоторые функции, в случае успешного выполнения возвращающие ресурсы, после неудачного завершения работы возвращают значение FALSE).
Ниже приведены переменные, в именах которых указано истинностное значение (true — истина, false — ложь), принимаемое этими переменными при использовании в логическом контексте:
$true_num = 3 + 0.14159; $true_str = "Строка true."; $true_array[49] = "Элемент массива"; $false_array = array(); $false_null = NULL; $false_num = 999 - 999; $false_str = ""; // Строка нулевой длины
Безусловно, из первого приведенного выше правила следует, что число с плавающей точкой двойной точности (0.0) преобразуется в ложное логическое значение. Но необходимо учитывать, что выражения с плавающей точкой опасно использовать в качестве логических выражений из-за возможных ошибок округления. Рассмотрим следующий пример:
$floatbool = sqrt(2.0) * sqrt(2.0) - 2.0; // Должен быть 0, // но из-за ошибок округления $floatbool не равно 0 if ($floatbool) print("Приведение дробных чисел к логическому значению опасно из-за ошибок округления
"); else print("Все работает правильно
"); print("\$floatbool = $floatbool");
Переменной $floatbool присваивается результат вычитания числа 2 из произведения квадратных корней числа 2, результат этого вычисления должен быть равен нулю, а это означает, что переменная $floatbool должна принимать ложное значение. Вместо этого в окне браузера появляется следующий вывод:

Значение переменной $floatbool очень близко к 0.0, но отличается от нуля и поэтому, вопреки ожиданиям, является истинным. Для использования в качестве логических значений гораздо безопаснее применять целые числа. Поскольку в арифметических операциях с целыми числами участвуют только целые числа и дробные значения не возникают, то в результате выполнения таких операций не могут появляться ошибки округления.
Значение null
На первый взгляд мир логических значений может показаться малым, поскольку для переменных логического типа предусмотрены только два возможных значения. А тип NULL сужает пространство значений до крайнего предела: данные типа NULL могут иметь только одно возможное значение, которым является значение NULL. Чтобы присвоить переменной значение NULL, достаточно применить к переменной примерно такую операцию присваивания:
$my_var = NULL;
Специальная константа NULL записывается прописными буквами в соответствии с общепринятым соглашением, но фактически имя этой константы не чувствительно к регистру, приведенный выше оператор вполне можно было бы записать следующим образом:
$my_var = null;
Так чем же отличаются значения NULL? Значение NULL представляет отсутствие значения (значение NULL можно рассматривать как недостающее или незаданное значение). Переменная, которой присвоено значение NULL, почти неотличима от переменной, которой вообще не было присвоено значение. В частности, переменная, которой присвоено значение NULL, обладает описанными ниже свойствами:
- В логическом контексте вычисления, проведенные с этой переменной, приводят к получению значения FALSE.
- Применение к этой переменной проверки с помощью функции IsSet() приводит к получению значения FALSE. (Таким свойством не обладают переменные каких-либо других типов.)
- Интерпретатор PHP не выводит предупреждающее сообщение при передаче такой переменной в функцию и возврате из функции, тогда как передача переменной, значение которой еще не было присвоено, иногда приводит к активизации предупреждающих сообщений.
Переменные со значением NULL в основном предназначены для использования в таких ситуациях, когда требуется преднамеренно применить переменную, не имеющую значения, и разработчик хочет, чтобы об этом узнал и читатель созданного им кода, и интерпретатор PHP. Последнее соображение становится особенно важным, если приходится передавать значения переменных в функции.
Строки
Как показано ниже, строки представляют собой символьные последовательности:
$string_1 = "Это строка в двойных кавычках."; $string_2 = 'Это строка в одинарных кавычках'; $string_26 = "В этой строке 26 символов."; $string_0 = ""; // Строка, количество символов в которой равно нулю
Строки могут быть заключены в одинарные или двойные кавычки. От применяемых ограничительных символов зависит то, как будут обрабатываться строки во время чтения интерпретатором. Строки в одинарных кавычках остаются почти неизменными. С другой стороны, строки в двойных кавычках подвергаются более интенсивной обработке: переменные, заданные в таких строках, заменяются своими значениями, а некоторые символьные последовательности интерпретируются особым образом.
Строки в одинарных кавычках
Если не учитывать, что происходит интерпретация особым образом нескольких символьных последовательностей, чтение и сохранение в памяти строк в одинарных кавычках осуществляется без каких-либо изменений. Например, обработка интерпретатором следующего кода:
$var = 12345; $literally = 'Переменная var = $var.\\nOk'; print($literally);
приводит к получению в окне браузера следующего вывода:

Строки в одинарных кавычках подчиняются также такому общему правилу, что кавычки другого типа не приводят к разрыву строки, заключенной в кавычки. Например, следующий оператор является допустимым:
$singly_quoted = 'В этой переменной двойные кавычки: " не приводят к нарушению в работе';
Чтобы ввести одинарную кавычку (применяемую в качестве апострофа) в строку, заключенную в одинарные кавычки, необходимо обозначить одинарную кавычку с помощью знака переключения (на другой режим обработки символов) в виде обратной косой черты, как показано ниже:
$singly_quoted = 'Вводим \'одинарную кавычку\' в строку';
Хотя в большинстве контекстов символы обратной косой черты в строках с одинарными кавычками интерпретируются буквально, можно также использовать два символа обратной косой черты (в качестве управляющей последовательности для обозначения одного символа обратной косой черты, не применяемого в составе управляющей последовательности). Это удобно, если символ обратной косой черты должен быть задан в качестве последнего символа в строке, как в следующем примере:
// Получается строка 'C:\Windows\System32\' $win_path = ' С:\\Windows\\System32\\';
Подводя итог, отметим, что строки в одинарных кавычках сохраняются в памяти в неизменном виде и единственными исключениями являются две указанные управляющие последовательности (\\ и \’).
Строки в двойных кавычках
Строки, заключенные в двойные кавычки (например, «this»), подвергаются предварительной обработке интерпретатором PHP двумя приведенными ниже способами:
- Некоторые символьные последовательности, начинающиеся с обратной косой черты (\), заменяются специальными символами.
- Имена переменных (начинающиеся со знака $) заменяются строковыми представлениями их значений.
Ниже описано, какие замены происходят при обработке некоторых управляющих последовательностей:
- Последовательность \n заменяется символом обозначения конца строки.
- Последовательность \r заменяется символом возврата каретки (переноса).
- Последовательность \t заменяется символом табуляции.
- Последовательность \$ заменяется самим знаком доллара ($).
- Последовательность \» заменяется одной двойной кавычкой («).
- Последовательность \\ заменяется одной наклонной чертой влево (\).
Первые три из этих замен позволяют упростить задачу по включению в строку некоторых пробельных символов, предоставляя возможность визуально контролировать расстановку таких символов. Последовательность \$ позволяет включить в строку символ $, если он должен появиться в непосредственном виде, а не интерпретироваться как начало имени переменной. Последовательность \» предназначена для того, чтобы можно было включить в строку в двойных кавычках символ двойной кавычки, не разрывая эту строку. Наконец, поскольку символ \ обозначает начало всех этих последовательностей, то необходим способ включения данного символа в непосредственном виде, а не в качестве начального символа управляющей последовательности; для этого перед символом обратной косой черты достаточно поставить еще один такой символ.
Как и в случае строк в одинарных кавычках, в строки в двойных кавычках можно свободно включать кавычки другого типа, без символа управляющей последовательности:
$has_apostrophe = "There's no problem here";
Подстановка значений переменных
После обнаружения в строке, заключенной в двойные кавычки, каждого символа $, не обозначенного как относящийся к управляющей последовательности, интерпретатор PHP пытается трактовать текст, который следует за этим символом, как имя переменной и подставить текущее значение соответствующей переменной в строку. При этом замена имени переменной значением этой переменной может осуществляться с помощью различных описанных ниже способов, в зависимости от того, какое значение присвоено этой переменной:
- Если переменной в настоящее время присвоено строковое значение, то оно заменяет в строке с двойными кавычками имя соответствующей переменной (иными словами, выполняется подстановка значения переменной вместо имени переменной).
- Если переменной в настоящее время присвоено значение, отличное от строкового, то данное значение преобразуется в строковое, а затем осуществляется замена имени переменной строковым значением.
- Если переменной в настоящее время не присвоено значение, то интерпретатор PHP заменяет имя переменной пустым значением (или, если применить эквивалентную формулировку, интерпретатор PHP подставляет вместо имени переменной пустую строку).
Ресурсы
представляют собой специальные значения, которые ссылаются на информацию об адресах памяти или о состояниях, внешнюю по отношению к самой системе PHP. Тем читателям, которые не занимаются программированием на языке PHP на постоянной основе, не нужны слишком подробные сведения о ресурсах. В следующем подразделе кратко описано общее назначение ресурсов.
Общее определение понятия ресурса
Ресурс представляет собой тип данных, который требуется для обеспечения взаимодействия интерпретатора PHP с той или иной внешней программой (например, с базой данных или графической программой), выделяющей память в ответ на запросы, полученные от интерпретатора PHP. Вообще говоря, программистам PHP не приходится заниматься освобождением памяти, распределенной самим интерпретатором PHP. В частности, после создания какой-то строки в сценарии PHP (а эта строка, разумеется, занимает место в памяти) можно полностью забыть о том, что необходимо освободить место, занятое этой строкой, поскольку такая операция выполняется автоматически после завершения выполнения сценария. Интерпретатор PHP (или веб-сервер, к которому он подключен) освобождает всю память, связанную с выполняемым сценарием, после его завершения или даже раньше.
Но может оказаться, что во внешних программах, с которыми взаимодействует интерпретатор PHP (в системах управления базами данных и т.д.), такая отмена распределения памяти не предусмотрена. Это означает, что в памяти программы, которая управляет базой данных, будет долго оставаться место, зарезервированное для сценария, даже после завершения этого сценария.
В интерпретаторе PHP для решения такой проблемы используется подход, предусматривающий вызов специальных функций, которые запрашивают память из подобных внешних программ и возвращают ресурсы, после чего интерпретатор PHP следит за тем, чтобы не возникала такая ситуация, что эти ресурсы больше не применяются в сценарии. Если к ресурсам никто не обращается, то интерпретатор PHP обеспечивает выполнение внешней программой требуемой операции очистки памяти. Такая задача решается интерпретатором PHP путем подсчета ссылок на ресурс. Если количество ссылок достигает нуля, то ресурс может быть освобожден.
Способы обработки ресурсов
Как правило, программисты, работающие на языке PHP, не создают ресурсы самостоятельно, а вызывают специальные функции, которые возвращают значения типа resource, а затем передают эти значения в другие функции, для которых требуются ресурсы. Например, в программе можно вызвать функцию mysql_connect() (которая возвращает значение ресурса, ссылающееся на соединение с базой данных MySQL), сохранить полученный результат в переменной, а затем передать значение ресурса в функцию mysql_query() (которая использует ресурс соединения для передачи запроса в базу данных).
По сути, все, что должен сделать программист с таким ресурсом соединения — это сохранить его в переменной, чтобы в дальнейшем иметь возможность передавать значение переменной в функции, для которых требуется этот ресурс. Задача по очистке занимаемой ресурсом памяти после окончания работы сценария может быть возложена на интерпретатор PHP. Но если по каким-то признакам пользователь обнаружит, что для хранения ресурса в ходе выполнения сценария расходуется большой объем памяти, то может быть принято решение освободить эту память еще до окончания выполнения сценария. Такая операция обычно выполняется примерно таким образом:
// Сохранение ресурса в переменной $my_resource = mysql_connect(. ); // . Код, в котором используется ресурс соединения . // Переменная больше не ссылается на ресурс освобождая память $my_resource = NULL;
Присваивание переменной $my_resource неопределенного значения вынуждает интерпретатор PHP проверить, нет ли другого фрагмента кода, в котором используется этот ресурс MySQL, и в случае отрицательного ответа освободить этот ресурс. Еще один вариант состоит в том, что большинство функций открытия ресурса имеет противоположные по своему назначению функции закрытия ресурса. В качестве примера можно привести функцию mysql_close().

Проверка типа
Во время выполнения программы иногда возникает необходимость узнать, к какому типу относится то или иное значение. Такая задача становится особенно важной в связи с тем, что тип переменной может быть изменен в результате присваивания этой переменной другого значения. В языке PHP, во-первых, предусмотрена общая функция проверки типа gettype(), а во-вторых, имеются отдельные булевы функции для каждого из пяти основных типов. Итоговые сведения об этих функциях приведены в таблице ниже. Следует учитывать, что некоторые из этих функций имеют альтернативные имена:
| Функция | Описание |
|---|---|
| gettype(arg) | Возвращает строку, представляющую тип arg: integer (целое число), float (число с плавающей точкой), string (строковое значение), array (массив), object (объект) или unknown (неизвестный тип) |
| is_int(arg), is_integer(arg), is_long(arg) | Возвращает значение true, если arg — целое число, в противном случае — false |
| is_double(arg), is_float(arg), is_real(arg) | Возвращает значение true, если arg — число с плавающей точкой, в противном случае — false |
| is_bool(arg) | Возвращает значение true, если arg — булево значение (true или false), в противном случае — false |
| is_null(arg) | Возвращает значение true, если arg имеет тип null, в противном случае — false |
| is_string(arg) | Возвращает значение true, если arg — строка, в противном случае — false |
| is_array(arg) | Возвращает значение true, если arg — массив, в противном случае — false |
| is_object(arg) | Возвращает значение true, если arg — объект, в противном случае — false |
| is_resource(arg) | Возвращает значение true, если arg — ресурс, в противном случае — false |
| is_binary(arg) | Возвращает значение true, если arg — двоичная строка, в противном случае — false |
| is_buffer(arg) | Возвращает значение true, если arg — строка в Юникоде или двоичная строка, в противном случае — false |
| is_scalar(arg) | Возвращает значение true, если arg — скалярная переменная, в противном случае — false |
| is_unicode(arg) | Возвращает значение true, если arg — строка в Юникоде, в противном случае — false |
| is_numeric(arg) | Возвращает значение true, если arg — числовое значение, в противном случае — false |

Присваивание и приведение типа
Как уже было сказано, интерпретатор PHP часто автоматически преобразует данные из одного типа в другой, если этого требует контекст. Кроме того, в случае необходимости такие преобразования могут быть выполнены принудительно, по указанию программиста, разрабатывающего программу на языке PHP. Но программист должен знать, какие действия происходят в той и другой ситуации.
Правила преобразования типов
Ниже приведены некоторые общие правила, по которым выполняется преобразование данных из одного типа в другой интерпретатором PHP.
- Целое число — в число с плавающей точкой: создается число с плавающей точкой, полностью соответствующее исходному (например, int 4 становится равным float 4.0).
- Число с плавающей точкой — в целое число: дробная часть отбрасывается, т.е. число округляется в сторону нуля.
- Число — в булево значение: FALSE, если число точно равно 0, в противном случае TRUE.
- Число — в строку: создается строка, которая выглядит точно так же, как выглядело бы число после вывода его значения. Вывод целых чисел осуществляется в виде последовательности цифр, а числа с плавающей точкой выводятся с минимально необходимой точностью. Достаточно высокие или низкие значения с плавающей точкой преобразуются в экспоненциальный формат.
- Булево значение — в число: 1, если TRUE; 0, если FALSE.
- Булево значение — в строку: ‘1’, если TRUE, пустая строка, если FALSE.
- Значение NULL — в число: 0.
- Значение NULL — в булево значение: FALSE.
- Строка — в число: преобразование эквивалентно чтению числа из строки с последующим преобразованием в требуемый тип. Если число не может быть считано успешно, то полученное значение является нулевым. Для того чтобы операция чтения считалась выполненной успешно, не обязательно требуется считывать всю строку.
- Строка — в булево значение: FALSE, если это — пустая строка или строка, равная ‘0’, TRUE в противном случае.
- Простой тип (число или строка) — в массив: преобразование эквивалентно созданию нового массива с одним элементом, имеющим индекс нуль.
- Массив — в число: преобразование не определено.
- Массив — в булево значение: FALSE, если массив не имеет элементов, TRUE в противном случае.
- Массив — в строку: ‘Array’.
- Объект — в число: преобразование не определено.
- Объект — в булево значение: TRUE, если объект содержит любые переменные экземпляра, имеющие ненулевое значение, и FALSE в противном случае.
- Объект — в строку: ‘Object’.
- Ресурс — в булево значение: FALSE.
- Ресурс — в число: преобразование не определено.
- Ресурс — в строку: строка, которая обычно принимает вид ‘Resource id #1’ (но этого нельзя гарантировать).
В приведенном выше списке было отмечено, что значения некоторых типов после преобразования в числовые значения имеют неопределенный результат. В данном контексте под словом «неопределенный» подразумевается, что разработчики PHP еще не пришли к согласию в отношении того, по каким правилам должно осуществляться такое преобразование в текущей и будущих версиях PHP, поэтому в коде не следует осуществлять преобразование подобного рода. Может оказаться, что в какой-то конкретной версии PHP подобные преобразования значений указанных типов в числовые значения осуществляются в программе успешно, но не следует рассчитывать на то, что в следующей версии соответствующее преобразование приведет к получению полезного результата.
Явные преобразования
В языке PHP предусмотрены три способа, с помощью которых программист может манипулировать данными, имеющими разные типы: применение функций преобразования, операторов приведения типа (подобные используемым в языке C) и вызов функции settype() с параметрами в виде переменных. Эти способы кратко описаны ниже:
- Функции intval(), floatval () и strval() преобразуют свои параметры соответственно в целые числа, числа с плавающей точкой или строковые значения.
- Любому выражению может предшествовать оператор приведения типа (имя типа в круглых скобках), который преобразует результат выражения в значение требуемого типа.
- В качестве первого параметра функции settype() можно задать любую переменную, а эта функция преобразует значение переменной из текущего типа в тот тип, который задан в виде второго строкового параметра.
В следующем примере продемонстрированы все 3 версии приведения типов:
$str = "101 далматинец"; // Преобразуем строку в целое число $count = intval($str); echo $count; // 101 // Преобразуем строку в булево значение $bool = (bool)$str; echo ($bool) ? "TRUE" : "FALSE"; // 'TRUE', т.к. строка не пустая и не '0' // Преобразуем строку в число с плавающей точкой settype($str, "float"); echo gettype($str); // 'double'
Ключевые слова с именами шести основных типов (integer, float, boolean, string, array и object) являются допустимыми компонентами в операторах приведения типа, а также допустимыми строковыми параметрами функции settype(). Кроме того, в операторах приведения типа допускается использование некоторых альтернативных ключевых слов, обозначающих имена типов: (int) вместо (integer), (double) или (real) вместо (float) и (bool) вместо (boolean). Приведение типа resource не допускается, а приведение к типу NULL является бессмысленным (дело в том, что результатом такого приведения может быть только значение NULL, поэтому можно вместо этого присвоить переменной такое значение.)
Целочисленное переполнение
Относительно недавно в языке PHP был реализован еще один остроумный способ автоматического преобразования типа. Он состоит в том, что при переполнении целочисленных значений (в случае присваивания целочисленной переменной значения, формат представления которого больше по сравнению с тем, который допускает эта переменная) последние присваиваются переменным с плавающей точкой. Такой подход не лишен смысла, поскольку числа с плавающей точкой позволяют представить более широкий диапазон значений по сравнению с целыми числами. Рассмотрим пример:
$too_big = 268; for ($i = 0; $i < 5; $i++) < // С каждой итерацией цикла увеличиваем число в 1000 раз, // чтобы достичь целочисленного переполнения $too_big *= 1000; echo "$too_big: тип переменной ".gettype($too_big)."
"; >

Показанный в этом примере переход от литеральных целочисленных значений к значениям в экспоненциальном формате соответствует преобразованию типа переменной $too_big из типа integer в тип float (double). Безусловно, переход к типу float может привести к потере некоторой информации, поскольку точность чисел с плавающей точкой ограничена, но сам этот подход полностью соответствует принципам, заложенным в языке PHP, согласно которым интерпретатор должен в любых условиях делать все от него зависящее, а не просто формировать сообщение об ошибке.
Python: Возврат значений
В этом уроке подробнее разберем, как работать с созданными функциями, чтобы они были полезны.
Когда мы определяем функцию, она печатает на экран какие-то данные:
def greeting(): print('Hello, Hexlet!')
Пользы от таких функций немного, так как результатом нельзя воспользоваться внутри программы. Рассмотрим на примере.
Возьмем задачу обработки электронной почты. Когда пользователь регистрируется на сайте, то он может ввести email любым способом:
- Добавить случайно пробелы в начале или в конце: _support@hexlet.io__
- Использовать буквы в разном регистре: SUPPORT@hexlet.io
Если мы сохраним его в таком виде в базу данных, то пользователь не войдет на сайт. Чтобы этого не произошло, email нужно подготовить к записи в базу: привести его к нижнему регистру и обрезать пробелы по краям строки. Такая задача решается в пару строчек:
def save_email(): # Email приходит из формы email = ' SuppORT@hexlet.IO' # Обрезаем пробельные символы trimmed_email = email.strip() prepared_email = trimmed_email.lower() print(prepared_email) # Здесь будет запись в базу данных
Этот код стал возможен благодаря тому, что значение вернулось. Методы strip() и lower() ничего не печатают на экран, они возвращают результат своей работы. Поэтому мы можем записать его в переменные. Если бы они печатали на экран, мы бы не могли присвоить результат переменной. Например, так мы не можем сделать с функцией greeting() :
message = greeting() # в действительности, функция print() возвращает None # None — специальный объект, используемый для представления отсутствия значения print(message) # => None
Теперь изменим функцию greeting() так, чтобы она возвращала данные. Для этого выполним возврат вместо печати на экран:
def greeting(): return 'Hello, Hexlet!'
return — это инструкция. Она берет записанное справа выражение и отдает его тому коду, который вызвал метод. Здесь выполнение функции завершается.
# Теперь мы можем использовать результат работы функции message = greeting() print(message) # => Hello, Hexlet! # И даже выполнить какие-то действия над результатом print(message.upper()) # => HELLO, HEXLET!
Любой код после return не выполняется:
def greeting_with_code_after_return(): return 'Hello, Hexlet!' print('Я никогда не выполнюсь')
Даже если функция возвращает данные, это не ограничивает ее в том, что она печатает. Кроме возврата данных мы можем и печатать:
def greeting_with_return_and_printing(): print('Я появлюсь в консоли') return 'Hello, Hexlet!' # И напечатает текст на экран, и вернет значение message = greeting_with_return_and_printing()
Возвращать можно не только конкретное значение. Так как return работает с выражениями, то справа от него может быть что угодно. Здесь нужно руководствоваться принципами читаемости кода:
def greeting(): message = 'Hello, Hexlet!' return message
Здесь мы не возвращаем переменную. Возвращается всегда значение, которое находится в этой переменной. Ниже пример с вычислениями:
def double_five(): # или return 5 + 5 result = 5 + 5 return result
Определить функцию мало. Еще важно, чтобы она была полезна, и результатом можно было воспользоваться. А теперь подумайте, что вернет вызов, определенной ниже функции run() ?
# Определение def run(): return 5 return 10 # Что будет выведено на экран? print(run())
Задание
Реализуйте функцию say_hurray_three_times() , которая возвращает строку ‘hurray! hurray! hurray!’.
hurray = say_hurray_three_times() print(hurray) # => hurray! hurray! hurray!
Упражнение не проходит проверку — что делать?
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя
Это нормально , в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
День 3: Модель данных
Все, кто уже жаждет открыть текстовый редактор и написать немного PHP кода, сегодня будут счастливы узнать, что в сегодняшнем уроке мы наконец-то займёмся разработкой. Мы определим модель данных Jobeet, начнём использовать ORM для общения с базой данных и построим первый модуль нашего приложения. Но так как symfony делает за нас огромную часть работы, то мы получим полнофункциональный модуль, почти не притронувшись PHP коду.
Реляционная модель.
Пользовательские истории, которые мы вчера написали, описывают основные объекты нашего проекта: вакансии, партнёров и категории. Вот диаграмма, связывающая это всё воедино:

В дополнение к полям, описанным в историях, мы так же добавим поля created_at для некоторых таблиц. Symfony замечает такие поля и устанавливает их значение равное системному времени в момент создания записи. Тоже самое верно и для полей updated_at : их значения становятся равными системному времени, каждый раз, когда обновляется запись.
Схема
Для того чтобы хранить вакансии, партнёров и категории, нам понадобится реляционная база данных.
Но раз symfony — это объекто-ориентированный фреймворк, то мы хотим управлять объектами. Например, вместо того, чтобы писать SQL запросы для получения записи из базы данных, лучше воспользуемся объектами.
Информация о реляционной базе данных должна быть связана с объектной моделью. Это можно сделать при помощи ORM инструмента и, к счастью, symfony поставляется с двумя из них: Propel и Doctrine. В данной главе мы будем использовать Propel.
ORM потребует от вас описания таблиц и связей между ними для создания связанных классов. Есть 2 пути для создания описательной схемы: из уже созданной базы данных или же написать схемы вручную.
Существуют инструменты, при помощи которых можно создать базу данных графически (например Fabforce’s Dbdesigner) и сгенерировать schema.xml (при помощи DB Designer 4 TO Propel Schema Converter).
Базы данных у нас пока нет, так что займёмся созданием файла схемы вручную, а для этого воспользуемся файлом config/schema.yml :
# config/schema.yml propel: jobeet_category: id: ~ name: < type: varchar(255), required: true, index: unique >jobeet_job: id: ~ category_id: < type: integer, foreignTable: jobeet_category, foreignReference: id, required: true >type: < type: varchar(255) >company: < type: varchar(255), required: true >logo: < type: varchar(255) >url: < type: varchar(255) >position: < type: varchar(255), required: true >location: < type: varchar(255), required: true >description: < type: longvarchar, required: true >how_to_apply: < type: longvarchar, required: true >token: < type: varchar(255), required: true, index: unique >is_public: < type: boolean, required: true, default: 1 >is_activated: < type: boolean, required: true, default: 0 >email: < type: varchar(255), required: true >expires_at: < type: timestamp, required: true >created_at: ~ updated_at: ~ jobeet_affiliate: id: ~ url: < type: varchar(255), required: true >email: < type: varchar(255), required: true, index: unique >token: < type: varchar(255), required: true >is_active: < type: boolean, required: true, default: 0 >created_at: ~ jobeet_category_affiliate: category_id: < type: integer, foreignTable: jobeet_category, foreignReference: id, required: true, primaryKey: true, onDelete: cascade >affiliate_id:
Если Вы решили создать таблицы при помощи sql выражений, то в последствии вы сможете сгенерировать файл schema.yml при помощи команды propel:build-schema .
Схема — это зеркальное отражение диаграммы связей, но в формате YAML.
Согласно официальному сайту YAML, YAML это «дружественный стандарт сериализации данных для всех языков программирования»
Другими словами, YAML это простой язык для описания данных (строки, числа, даты, массивы и хэши)
В YAML структура показана через метки, циклы определяются дефисом, а пары ключ/значение раскиданы по колонками. YAML так же имеет сокращённый синтакис для описания одной и той же структуры меньшим количеством строк, в котором массивы отображаются при помощи структуры [] , а хэши при помощи <>
Если вы ещё ничего не знаете про YAML, то самое время его изучить, так как symfony активно пользуется им в конфигурационных файлах. Хорошей отправной точкой будет документация по YAML компоненту Symfony.
Файл schema.yml содержит описание всех таблиц и их полей. Каждое описание поля даёт нам следующую информацию:
- type : Тип поля ( boolean , tinyint , smallint , integer , bigint , double , float , real , decimal , char , varchar(size) , longvarchar , date , time , timestamp , blob и clob )
- required : Установите в true , если хотите чтобы поле было обязательным.
- index : Установите в true если вы хотите создать индекс на данном поле, или unique , если хотите, чтобы на поле был создан уникальный индекс.
Если поле определено как ~ ( id , created_at , and updated_at ), symfony подберёт лучшую конфигурацию (primary key для id и timestamp для created_at и updated_at )
Атрибут onDelete определяет поведение ON DELETE для внешних ключей. Propel поддерживает CASCADE , SETNULL и RESTRICT . Например, если запись job удаляется, то все связанные с ней записи jobeet_category_affiliate будут автоматически удалены базой данных или самим Propel, если данный движок не поддерживает такой функционал.
База данных
Symfony поддерживает все базы данных, которые есть в PDO (MySQL, PostgreSQL, SQLite, Oracle, MSSQL, . ). PDO это абстрактный слой баз данных, поставляемый с PHP.
В данном учебнике мы будет использовать MySQL:
$ mysqladmin -uroot -pmYsEcret create jobeet
Будьте свободны в выборе баз данных. Будет весьма нетрудно адаптировать код, создаваемый нами, так как вместо SQL мы используем возможности ORM для создания запросов.
Теперь укажем symfony на базу данных, используемую в проекте Jobeet:
$ php symfony configure:database "mysql:host=localhost;dbname=jobeet" root mYsEcret
Команда configure:database принимает 3 аргумента: PDO DSN, имя пользователя и пароль для доступа к БД. Если у вас нет пароля на сервере для разработок, просто не пишите третий аргумент.
Команда configure:database сохраняет настройки БД в файл config/databases.yml . Данные настройки можно изменить и вручную, без использования команды.
ORM
Используя описание БД в файле schema.yml Вы можете при помощи встроенных в Propel команд сгенерировать SQL, необходимый для создания таблиц в БД:
$ php symfony propel:build --sql
Команда propel:build —sql создаёт SQL в каталоге data/sql , оптимизированный под ту БД, которую мы указали в конфигурации.
# Фрагмент файла data/sql/lib.model.schema.sql CREATE TABLE `jobeet_category` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NOT NULL, PRIMARY KEY (`id`) )Type=InnoDB;
Для создания таблиц в БД, нужно запустить команду propel:insert-sql :
$ php symfony propel:insert-sql
Как и любое приложение командной строки, команды symfony принимают аргументы и опции. Каждая команда идёт со встроенной подсказкой, которая отображается при использовании команды help :
$ php symfony help propel:insert-sql
Подсказка показывает все возможные аргументы и флаги, показывает их стандартные значения и приводит полезные примеры.
ORM так же генерирует PHP классы, которые связывают записи таблицы и объекты:
$ php symfony propel:build --model
Команда propel:build —model генерирует PHP файлы в каталоге lib/model . Данные файлы используются для работы с базой данных.
Просматривая созданные файлы, Вы наверное заметили, что для Propel генерируется 4 класса для каждой из таблиц. Для таблицы jobeet_job имеем:
- JobeetJob : Объект данного класса представляет собой запись таблицы jobeet_job . Класс изначально пуст.
- BaseJobeetJob : Родительский класс JobeetJob . Каждый раз когда вы запускаете propel:build —model , данный класс перезаписывается, поэтому все изменения должны вноситься в класс JobeetJob .
- JobeetJobPeer : Класс определяет static методы, которые в основном возвращают коллекцию объектов JobeetJob . Класс изначально пуст.
- BaseJobeetJobPeer : Корневой класс JobeetJobPeer . Каждый раз когда вы запускаете propel:build —model , данный класс перезаписывается, поэтому все изменения должны вноситься в класс JobeetJobPeer . Значениями полей записи можно управлять при помощи акцессоров (методы get*() ) и мутаторов (методы set*() ) [php] $job = new JobeetJob(); $job->setPosition(‘Web developer’); $job->save(); echo $job->getPosition(); $job->delete();
Вы так же можете определить внешние ключи напрямую, связывая объекты:
$category = new JobeetCategory(); $category->setName('Programming'); $job = new JobeetJob(); $job->setCategory($category);
Команда propel:build —all это ярлык для всех команд, которые мы уже запустили в данной части, а так же некоторых других. Запустите данную команду, для того чтобы сгенерировать все формы и валидаторы для классов моделей Jobeet:
$ php symfony propel:build --all
В конце дня вы увидите валидаторы в действии, а о формах пойдёт речь на 10ый день нашего учебника.
Загрузка данных
Таблицы в базе данных у нас появились, но вот самих данных в них нет. Любое веб-приложение имеет 3 вида данных:
- Начальные данные: Начальные данные нужны для того, чтобы приложение работало. Например, Jobeet нужны для начала категории. Если их нет — никто не сможет добавить вакансию. Нам также нужен администратор в таблице пользователей, чтобы иметь возможность попасть в бэкенд.
- Тестовые данные: Тестовые данные необходимы для тестирования приложения. Как разработчик, Вы должны быть уверены, что Jobeet работает так, как это описано в пользовательских историях, а лучшим способом для этого является создание автоматических тестов. Так что каждый раз, когда Вы запускаете тесты, Вам будет нужна чистая БД со свежими данными для тестированияю
- Пользовательские данные: Пользовательские данные создаются пользователями во время обычного жизненного цикла приложения.
Каждый раз когда Symfony создаёт таблицы в базе данных, все данные теряются. Для наполнения БД начальными данными мы могли бы воспользоваться PHP скриптом или же запустить SQL запрос при помощи программы mysql . Но данная вещь является общей, поэтому есть путь лучше при помощи Symfony: создать YAML файлы в каталоге data/fixtures/ и использовать propel:data-load для загрузки их в БД.
# data/fixtures/010_categories.yml JobeetCategory: design: < name: Design >programming: < name: Programming >manager: < name: Manager >administrator: < name: Administrator ># data/fixtures/020_jobs.yml JobeetJob: job_sensio_labs: category_id: programming type: full-time company: Sensio Labs logo: sensio_labs.png url: http://www.sensiolabs.com/ position: Web Developer location: Paris, France description: | You've already developed websites with symfony and you want to work with Open-Source technologies. You have a minimum of 3 years experience in web development with PHP or Java and you wish to participate to development of Web 2.0 sites using the best frameworks available. how_to_apply: | Send your resume to fabien.potencier [at] sensio.com is_public: true is_activated: true token: job_sensio_labs email: job@example.com expires_at: 2010-10-10 job_extreme_sensio: category_id: design type: part-time company: Extreme Sensio logo: extreme_sensio.png url: http://www.extreme-sensio.com/ position: Web Designer location: Paris, France description: | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in. Voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. how_to_apply: | Send your resume to fabien.potencier [at] sensio.com is_public: true is_activated: true token: job_extreme_sensio email: job@example.com expires_at: 2010-10-10
Файлы данных пишутся в формате YAML и определяют экземпляры объектов, обозначенные уникальным именем. Данное обозначение полезно при создании ссылок на связанные объекты без определения ключей (которые, обычно, устанавливаются при помощи auto-increment и не могут быть изменены). Например категория для вакансии job_sensio_labs — programming , которая является определением для категории ‘Programming’.
Файл данные может содержать как один, так и несколько объектов.
Обратите внимание на цифры перед именами файлов. Это самый простой путь контролировать очерёдность загрузки данных. Далее в нашем проекте, если нам понадобится внедрить новый файл данных, сделать это будет легко, так как у нас есть несколько свободных чисел между текущими.
В файле данных совсем не обязательно определять значения всех полей. Если значения нет — Symfony подставит стандартное значение, определённое в схеме БД. А раз Symfony использует Propel для загрузки данных в БД, то все встроенные способы подстановки (такие как для полей created_at и updated_at ) или собственные подстановки, которые Вы добавите к модели, будут активны.
Загрузить начальные данные в БД можно при помощи команды propel:data-load :
$ php symfony propel:data-load
Задача propel:build —all —and-load — это ярлык для задач propel:build —all и propel:data-load , выполняемых последовательно.
Проверка на рабоспособность в браузере
Что-то мы много пользуемся командной строкой и это не сильно-то привлекательно, особенно для веб-проекта. У нас уже есть всё, для того чтобы создать веб-страницы, работающие с БД.
Посмотрим, как можно вывести список вакансий, как редактировать текущую вакансию и как удалить её. Как и говорилось в первом дне, проект на Symfony состоит из приложений. Каждое приложение состоит из модулей. Модуль это набор PHP кода, который отвечает за возможности приложения (например модуль API) или же за манипуляции, которые пользователь может совершить над проектом (например модуль вакансий).
Symfony может автоматически сгенерировать модуль для данной модели, который будет отвечать за базовые функции управления:
$ php symfony propel:generate-module --with-show --non-verbose-templates frontend job JobeetJob
Команда propel:generate-module создаёт модуль job в приложении frontend для модели JobeetJob . Как и для многих других команд, были созданы файлы и папки в каталоге apps/frontend/modules/job :
| Каталог | Описание |
|---|---|
| actions/ | Действия модуля |
| templates/ | Шаблоны модуля |
Файл actions/actions.class.php определяет все возможные действия для модуля job :
| Действие | Описание |
|---|---|
| index | Отображает все записи таблицы |
| show | Отображает поля одной записи |
| new | Отображает форму для создания новой записи |
| create | Создает новую запись |
| edit | Отображает форму для редактирования текущей записи |
| update | Обновляет запись, согласно присланным пользователем данным |
| delete | Удаляет данную запись из таблицы |
Теперь вы можете протестировать модуль «Вакансии» по адресу:
http://www.jobeet.com.localhost/frontend_dev.php/job

При попытке редактирования вакансии, Вы получите исключение, потому что Symfony нужно текстовое представление категории. Данное представление для объекта можно получить при помощи метода __toString() . Текстовое представление категории должно быть определно в классе JobeetCategory :
// lib/model/JobeetCategory.php class JobeetCategory extends BaseJobeetCategory { public function __toString() { return $this->getName(); } }
Теперь, каждый раз когда Вам нужно текстовое представление, будет происходить вызов метода __toString() , которые возвращает название категории. Так как нам пригодится текстовое представление в любой момент, то стоит определить метод __toString() для всех классов моделей:
// lib/model/JobeetJob.php class JobeetJob extends BaseJobeetJob { public function __toString() { return sprintf('%s at %s (%s)', $this->getPosition(), $this->getCompany(), $this->getLocation()); } } // lib/model/JobeetAffiliate.php class JobeetAffiliate extends BaseJobeetAffiliate { public function __toString() { return $this->getUrl(); } }
Теперь Вы можете создавать и редактировать вакансии. Попробуйте оставить обязательные полями незаполненными или попробуйте ввести неверную дату. Всё верно, Symfony создает базовые правила проверки (валидации), просмотрев схему базы данных.

Увидимся завтра!
На сегодня всё. Я вас предупреждал во вступлении. Сегодня мы немного написали PHP кода, но у нас уже есть рабочий модуль для модели вакансий, готовый к изменениям. Помните — отсутствие PHP кода означает отсутствие багов.
Если у вас ещё осталось немного сил, то можете поизучать код для модуля и моделей и попробовать понять, как это всё работает. Если нет — можете не беспокоиться и спать спокойно, а завтра мы поговорим об одной и самых важных парадигм фреймворков — шаблоне проектирования MVC.
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.
