Выражения

В PHP почти весь код, который пишется, это выражения. Наверное самое простое определение выражения - это то, что может иметь значение (переменные, функции и тд). Операция это выражение, заканчивающееся точкой с запятой. В операции $b = $a = 5;, $a = 5 - верное выражение, но оно еще не является операцией само по себе. Однако $b = $a = 5; уже является операцией.

Операторы

Оператором называется нечто, принимающее одно или более значений (или выражений, если говорить на жаргоне программирования), и вычисляющее новое значение (таким образом, вся конструкция может рассматриваться как выражение).

Операторы можно сгруппировать по количеству принимаемых ими значений. Унарные операторы принимают только одно значение, например, ! (оператор логического отрицания) или ++ (инкремент). Бинарные операторы принимают два значения; это, например, знакомые всем арифметические операторы + (плюс) и - (минус), большинство поддерживаемых в PHP операторов входят именно в эту категорию. Ну и, наконец, есть всего один тернарный оператор, ? :, принимающий три значения, обычно его так и называют -- "тернарный оператор" (хотя, возможно, более точным названием было бы "условный оператор").

Приоритет оператора

Приоритет оператора определяет, насколько "тесно" он связывает между собой два выражения. Например, выражение 1 + 5 * 3 вычисляется как 16, а не 18, поскольку оператор умножения ("*") имеет более высокий приоритет, чем оператор сложения ("+"). Круглые скобки могут использоваться для принудительного указания порядка выполнения операторов. Например, выражение (1 + 5) * 3 вычисляется как 18.

Если операторы имеют равный приоритет, то их группирование определяется их ассоциативностью. Например "-" имеет левую ассоциативность, поэтому 1 - 2 - 3 группируется как (1 - 2) - 3 и равно -4. С другой стороны, "=" имеет правую ассоциативность, поэтому $a = $b = $c группируется как $a = ($b = $c).

Операторы с равным приоритетом, но не имеющие ассоциативность, не могут использоваться вслед друг за другом, например 1 < 2 > 1 недопустимо в PHP. С другой стороны, выражение 1 <= 1 == 1 вполне допустимо, так как оператор == имеет меньший приоритет чем оператор <=.

Используйте скобки, даже если они не обязательны. Чаще всего это повышает читаемость кода, непосредственно определяя порядок группировки, не полагаясь на конкретные приоритет или ассоциативность оператора.

Арифметические операторы

Работают так же как и в реальном мире:

<?php

echo 2 + 2; // Addition. Will print 4
echo 3 - 2; // Subtraction. will print 1
echo 1 * 2; // Multiplication. Will print 2
echo 4 / 2; // Division . Will print 2
echo -2; // Negation. Will print -2
echo 3 % -2 // Modulus. Will print 1
echo -3 % 2 // Modulus. Will print -1
echo 0x8A + 3 // Will print 141 (0x8A = 8x16 + 10 = 138), note always returns the decimal values

?>

Операция деления ("/") возвращает число с плавающей точкой, кроме случая, когда оба значения являются целыми числами (или строками, которые преобразуются в целые числа), которые делятся нацело - в этом случае возвращается целое значение.

При делении по модулю операнды преобразуются в целые числа (удалением дробной части) до начала операции.

Результат операции остатка от деления % будет иметь тот же знак, что и делимое — то есть, результат $a % $b будет иметь тот же знак, что и $a. Например:

<?php

echo (5 % 3)."\n";           // выводит 2
echo (5 % -3)."\n";          // выводит 2
echo (-5 % 3)."\n";          // выводит -2
echo (-5 % -3)."\n";         // выводит -2

?>

Оператор точка ( . )

$a = 1;
$a .= 2;
echo $a; // 12

Оператор присваивания

Базовый оператор присваивания обозначается как "=". Оператор присваивания означает, что левый операнд получает значение правого выражения, (т.е. устанавливается значением).

Результатом выполнения оператора присваивания является само присвоенное значение. Таким образом, результат выполнения $a = 3 будет равен 3. Это позволяет делать трюки наподобие:

<?php
$a = ($b = 4) + 5; // $a теперь равно 9, а $b было присвоено 4.

Для массивов (array), присвоение значения именованному ключу происходит с помощью оператора "=>". Приоритет этого оператора такой же, как и у остальных операторов присваивания.

Следует обратить внимание на то, что присваивание копирует оригинальное значение в новное (присваивание по значению), так что изменения одного не затронут другое.

В дополнение к базовому оператору присваивания имеются "комбинированные операторы" для всех бинарных арифметических операций, операций объединения массивов и строковых операций, которые позволяют использовать некоторое значение в выражении, а затем установить его как результат данного выражения. Например:

<?php

$a = 3;
$a += 5; // устанавливает $a в 8, как если бы мы написали: $a = $a + 5;
$b = "Hello ";
$b .= "There!"; // устанавливает $b в "Hello There!",  как и $b = $b . "There!";

?>

Присваивание по ссылке

Присваивание по ссылке также поддерживается, для него используется синтаксис $var = &$othervar;. Присваивание по ссылке означает, что обе переменные указывают на одни и те же данные и никакого копирования не происходит.

<?php
$a = 3;
$b = &$a; // or a space in-between & $a // $b is a reference to $a
$b = 50;
print "$a\n"; // prints 50
print "$b\n"; // prints 50
?>

Начиная с версии PHP 5, оператор new автоматически возвращает ссылку, поэтому присваивание результата операции new по ссылке начиная с версии PHP 5.3 генерирует ошибку уровня E_DEPRECATED, а в более ранних версиях - ошибку уровня E_STRICT.

Побитовые операторы

Побитовые операторы позволяют считывать и устанавливать конкретные биты целых чисел.

  • $a & $b (И) - Устанавливаются только те биты, которые установлены и в $a, и в $b.
  • $a | $b (Или) - Устанавливаются те биты, которые установлены в $a или в $b.
  • $a ^ $b (Исключающее или) - Устанавливаются только те биты, которые установлены либо только в $a, либо только в $b, но не в обоих одновременно.
  • ~ $a (Отрицание) - Устанавливаются те биты, которые не установлены в $a, и наоборот.
  • $a << $b (Сдвиг влево) - Все биты переменной $a сдвигаются на $b позиций влево (каждая позиция подразумевает "умножение на 2")
  • $a >> $b (Сдвиг вправо) - Все биты переменной $a сдвигаются на $b позиций вправо (каждая позиция подразумевает "деление на 2")

Побитовый сдвиг в PHP - это арифметическая операция. Биты, сдвинутые за границы числа, отбрасываются. Сдвиг влево дополняет число нулями справа, сдвигая в то же время знаковый бит числа влево, что означает что знак операнда не сохраняется. Сдвиг вправо сохраняет копию сдвинутого знакового бита слева, что означает что знак операнда сохраняется.

Используйте скобки для обеспечения необходимого приоритета операторов. Например, $a & $b == TRUE сначала проверяет на равенство, а потом выполняет побитовое и; тогда как ($a & $b) == TRUE сначала выполняет побитовое и, а потом выполняет проверку на равенство.

Операторы сравнения

Операторы сравнения, как это видно из их названия, позволяют сравнивать между собой два значения.

$a == $b (Equivalence) — TRUE if $a is equal to $b after type juggling.
$a === $b (Identity) — TRUE if $a is equal to $b, and they are of the same type.
$a != $b $a <> $b (Non-equivalent) — TRUE if $a is not equal to $b after type juggling.
$a !== $b (Non-identical) — TRUE if $a is not equal to $b, or they are not of the same type
$a < $b (Less than) — TRUE if $a is strictly less than $b.
$a > $b (Greater than) — TRUE if $a is strictly greater than $b.
$a <= $b (Less than or equal to) — TRUE if $a is less than or equal to $b.
$a >= $b (Greater than or equal to) — TRUE if $a is greater than or equal to $b.

В случае, если вы сравниваете число со строкой или две строки, содержащие числа, каждая строка будет преобразована в число, и сравниваться они будут как числа. Эти правила также распространяются на оператор switch. Преобразование типов не происходит при использовании === или !== так как в этом случае кроме самих значений сравниваются еще и типы. Для различных типов сравнение происходит в соответствии со следующей таблицей (по порядку):

Сравнение различных типов

Тип операнда 1 Тип операнда 2 Результат
null или string string NULL преобразуется в "", числовое или лексическое сравнение
bool или null что угодно Оба операнда преобразуются в bool, FALSE < TRUE
object object При использовании оператора сравнения (==), свойства объектов просто сравниваются друг с другом, а именно: два объекта равны, если они содержат одинаковые свойства и одинаковые значения, и являются экземплярами одного и того же класса. При использовании оператора идентичности (===), переменные объектов считаются идентичными тогда и только тогда, когда они ссылаются на один и тот же экземпляр одного и того же класса.
string, resource или number string, resource или number Строки и ресурсы переводятся в числа, обычная математика.
array array Массивы с меньшим числом элементов считаются меньше, если ключ из первого операнда не найден во втором операнде - массивы не могут сравниваться, иначе идет сравнение соответствующих значений.
object что угодно object всегда больше
array что угодно array всегда больше

Тернарный оператор

Выражение (expr1) ? (expr2) : (expr3) интерпретируется как expr2, если expr1 имеет значение TRUE, или как expr3 если expr1 имеет значение FALSE. Начиная с версии PHP 5.3 также стало возможным не писать среднюю часть тернарного оператора. Выражение expr1 ?: expr3 возвращает expr1 если expr1 имеет значение TRUE, и expr3 в другом случае.

Тернарный оператор является выражением и трактуется не как переменная, а как результат выражения. Это важно знать, если вы хотите вернуть переменную по ссылке. Выражение return $var == 42 ? $a : $b; не будет работать в функции, возвращающей значение по ссылке, а в более поздних версиях PHP также будет выдано предупреждение.

Замечание: Рекомендуется избегать "нагромождения" тернарных выражений. Поведение PHP неочевидно при использовании нескольких тернарных операторов в одном выражении:

<?php
// на первый взгляд, следующий код должен вывести 'true'
echo (true?'true':false?'t':'f');

// однако, он выводит 't'
// это происходит потому, что тернарные выражения вычисляются слева направо

// это намного более очевидная версия вышеприведенного кода
echo ((true ? 'true' : false) ? 't' : 'f');

// здесь вы можете видеть, что первое выражение вычисляется в 'true', которое
// в свою очередь вычисляется в (bool)true, таким образом возвращая истинную ветвь
// второго тернарного выражения.
?>

Оператор управления ошибками

PHP поддерживает один оператор управления ошибками: знак (@). В случае, если он предшествует какому-либо выражению в PHP-коде, любые сообщения об ошибках, генерируемые этим выражением, будут проигнорированы.

Операторы исполнения

PHP поддерживает один оператор исполнения: обратные кавычки (``). Обратите внимание, что это не одинарные кавычки! PHP попытается выполнить строку, заключенную в обратные кавычки, как консольную команду, и вернет полученный вывод (т.е. он не просто выводится на экран, а, например, может быть присвоен переменной). Использование обратных кавычек аналогично использованию функции shell_exec().

<?php
$output = `ls -al`;
echo "<pre>$output</pre>";
?>

Замечание: В отличие от некоторых других языков, обратные кавычки не будут работать внутри строк в двойных кавычках. Использование обратных кавычек аналогично использованию функции shell_exec(). Не будет работать, если функция shell_exec() отключена.

Операторы инкремента и декремента

PHP поддерживает префиксные и постфиксные операторы инкремента и декремента.

Замечание: Операторы инкремента/декремента влияют только на строки и числа. Массивы, объекты и ресурсы не трогаются. Декремент NULL также не даст никакого эффекта, однако инкремент даст значение 1.

Операторы инкремента и декремента

Пример Название Действие
++$a Префиксный инкремент Увеличивает $a на единицу, затем возвращает значение $a.
$a++ Постфиксный инкремент Возвращает значение $a, затем увеличивает $a на единицу.
--$a Префиксный декремент Уменьшает $a на единицу, затем возвращает значение $a.
$a-- Постфиксный декремент Возвращает значение $a, затем уменьшает $a на единицу.

Строковые операторы

В PHP есть два оператора для работы со строками (string). Первый - оператор конкатенации ( '.' ), который возвращает строку, представляющую собой соединение левого и правого аргумента. Второй - оператор присваивания с конкатенацией ( '.=' ), который присоединяет правый аргумент к левому.

<?php
$a = "Hello ";
$b = $a . "World!"; // $b теперь содержит строку "Hello World!"

$a = "Hello ";
$a .= "World!";     // $a теперь содержит строку "Hello World!"
?>

Операторы, работающие с массивами

Операторы, работающие с массивами

Пример Название Результат
$a + $b Объединение Объединение массива $a и массива $b.
$a == $b Равно TRUE в случае, если $a и $b содержат одни и те же пары ключ/значение.
$a === $b Тождественно равно TRUE в случае, если $a и $b содержат одни и те же пары ключ/значение в том же самом порядке и того же типа.
$a != $b Не равно TRUE, если массив $a не равен массиву $b.
$a <> $b Не равно TRUE, если массив $a не равен массиву $b.
$a !== $b Тождественно не равно TRUE, если массив $a не равен тождественно массиву $b.

Оператор + возвращает левый массив, к которому был присоединен правый массив. Для ключей, которые существуют в обоих массивах, будут использованы значения из левого массива, а соответствующие им элементы из правого массива будут проигнорированы.

Замечание: оператор + в отличии от функции array_merge() учитывает и числовые ключи.

При сравнении элементы массива считаются идентичными, если совпадает и ключ, и соответствующее ему значение.

Оператор проверки типа

Оператор instanceof используется для определения того, является ли текущий объект экземпляром указанного класса. Оператор instanceof также может быть использован для определения, наследует ли определенный объект какому-либо классу. Ну и наконец, instanceof может быть также использован для проверки реализации объектом некоторого интерфейса.

Замечание: нельзя проверить использует ли класс трейт. Для этого есть функция class_uses(), которая возвращает список трейтов, которые используются в классе. В этот массив однако не попадут трейты, которые используются в классе родителе.

Оператор instanceof не генерирует никаких ошибок, если проверяемая переменная не является объектом. В этом случае он просто возвращает FALSE. Константы, тем не менее, не допускаются.