PHP: Операторы
Автор: | Артемьев Сергей Игоревич |
ICQ: | 438856621 |
email: | _spin_@bk.ru |
Оператор - это описание некоторого действия, которое интерпретатор должен сделать с указанными переменными. Операторы входят в большинство выражений и позволяют изменять или сравнивать значения переменных. Переменные, с которыми связан оператор, называются операндами. В предыдущем уроке мы уже использовали 3 оператора: присвоения "=", сравнения ">" и конкатенации (объединения) строк ".";
Не надо путать выражения и операторы. Оператор лишь определяет необходимое действие, а выражение - это законченный маленький фрагмент программы, в который могут входить операторы, переменные, константы и т.п.
Важное свойство операторов - приоритет (иначе называется "старшинство" или "вес"). Это свойство определяет в какой последовательности будут выполняться фрагменты одного выражения. В предыдущем уроке мы немного коснулись этой темы, когда рассматривали вложенность выражений.
Второе важное свойство - ассоциативность. Свойство определяет в каком направлении вычисляются пременные, к которым применяется оператор. Оператор может быть "ассоциативным слева", "ассоциативным справа" или не ассоциативным. Левая ассоциативность означает что значения операндов вычисляются слева направо, а правая ассоциативность - наоборот. Пример "левого" оператора - сложение, пример правого - присвоение.
В таблице перечислены операторы в порядке убывания приоритета. Операторы, стоящие на одной строке, вычисляются с учётом ассоциативности.
Ассоциативность | Операторы |
---|---|
нет | new |
левая | [ |
нет | ++ -- |
нет | ~ - (int) (float) (string) (array) (object) @ |
нет | instanceof |
правая | ! |
левая | * / % |
левая | + - . |
левая | << >> |
нет | < <= > >= |
нет | == != === !== |
левая | & |
левая | ^ |
левая | | |
левая | && |
левая | || |
левая | ? : (тернарный оператор) |
правая | = += -= *= /= .= %= &= |= ^= <<= >>= |
левая | and |
левая | xor |
левая | or |
левая | , |
Рассмотрим пример:
<?php $assoc = 3 * 3 % 5; ?>
В строке "$assoc = 3 * 3 % 5;" используется сразу 3 оператора: присвоение "=", умножение "*" и деление по модулю "%". Из таблицы видно, первый оператор в выражении (считается слева-направо) - присвоение. Это "правый" и наименее приоритетный оператор , значит в первую очередь надо вычислить правый операнд ("3 * 3 % 5"). Правый операнд - выражение с двумя "левые" операторами равного приоритета. Поэтому вычисление производится просто последовательно слева направо. Результат вычисления правого операнда становится операндом оператора присоения. Результат выполнения всех операций - переменная $assoc получает значение 4.
Типы операторов
Все операторы разделяются на 11 групп:
- Арифметические
- Присвоения
- Битовые
- Сравнения
- Контроля ошибок
- Выполнения
- Инкремента/декремента
- Логические
- Строковые
- Операторы массивов
- Операторы типов
Арифметические операторы
Название | Пример | Результат |
Отрицание | -$a | Значение с противоположным знаком |
Сложение | $a + $b | Сумма двух операндов |
Вычитание | $a - $b | Разность двух операндов |
Умножение | $a * $b | Произведение двух чисел |
Деление | $a / $b | Частное двух чисел |
Деление по модулю | $a % $b | Остаток от целочисленного деления |
В следующих уроках мы неоднократно будет использовать оператор %, поэтому остановлюсь на нём подробнее. Результат деления по модулю - это минимальная разница между исходным значением и значения, равного делителю, умноженному на целую часть обычного частного. Например, 12 % 5 = 2, т.к. 12 % 5 = 12 - (5 * [12/5]) = 12 - (5 * [2.4]) = 12 - (5*2) = 12 - 10 = 2.
На практике деление $a по модулю $b вручную делается так:
- Делим $a на $b, получаем $c
- Если $c равно нулю, значит $a % $b = 0
- Если $c не равно нулю, откидываем от $c дробную часть, получаем $d
- Умножаем $b на $d и полученное значение вычитаем из $a
- Результат вычитания - это и есть результат деления $a по модулю $b
Операторы присвоения
Оператор присвоения "=" мы уже поясняли и использовали несколько раньше. Но кроме обычного присвоения в PHP есть ещё несколько расширенных операторов присвоения. Расширенный оператор состоит из оператора присвоения и стоящего перед ним модифицирующего оператора. Например, в операторе "+=" модифицирующим оператором будем "+" суммирование.
Логика работы составного оператора проста: модифицирующий оператор применяется к операндам, после чего результат присваивается левому операнду. Например:
<?php $str = 'город '; $str .= 'Хабаровск'; // аналогично $str = $str . 'Хабаровск'; echo $str; // выведет 'город Хабаровск' $int = 123; $int .= 11; echo $int; // выведет 134; ?>
Битовые операторы
Битовые операции предназначены для изменения значений отдельных битов переменных. Эти операторы работают по тем же принципам, что и обычные логические операторы, только результат - значение бита (0 или 1), а не TRUE или FALSE.
Название | Пример | Результат |
AND (И) | $a & $b | Устанавливаются в "1" только биты, одновременно установленные в "1" в обоих операндах |
OR (ИЛИ) | $a | $b | Устанавливаются в "1" биты, установленные в "1" хотя бы в одном операнде |
XOP (ИЛИ-НЕ) | $a ^ $b | Устанавливаются в "1" биты, установленные в "1" в одном операнде, но не обоих сразу |
NOT (Отрицание) | ~ $a | Устанавливаются в "1" биты, ранее имевшие значение "0" и наоборот. |
Сдвиг влево | $a << $b | Биты сдвигаются влево на $b бит, "освобождённые" биты заполняются нулями |
Сдвиг вправо | $a >> $b | Биты сдвигаются вправо на $b бит, "освобождённые" биты заполняются нулями |
<?php $a = 170; // 10101010 в бинарном виде $b = 240; // 11110000 в бинарном виде $and = $a & $b; // $and = 10100000 $or = $a | $b; // $or = 11111010 $xor = $a ^ $b; // $xor = 01011010 $not = ~$a; // $not = 01010101 $L = $b << 1; // $L = 11100000 $R = $b >> 1; // $R = 01111000 ?>
Стоит взять на заметку, что сдвиг влево на 1 бит равносилен умножению числа на 2, а сдвиг на 1 бит вправо - равносилен целочисленному делению на 2. Если ваш скрипт делает очень много умножений/вычитаний на числа, являющиеся степенями двойки, то производительность можно существенно повысить, заменив деление/умножение на битовый сдвиг.
Операторы сравнения
PHP может сравнивать переменных двумя способами: сравнением по значению и сравнением по значению и типу.
Название | Пример | Результат |
Равено | $a == $b | TRUE если $a равно $b |
Идентично | $a === $b | TRUE если $a равно $b и тип данных $a равен типу данных $b |
Не равно | $a != $b или $a <> $b | TRUE если $a не равно $b |
Не идентично | $a !== $b | TRUE если $a не равно $b и/или тип данных $a не равен типу данных $b |
Меньше | $a < $b | TRUE если $a меньше $b |
Больше | $a > $b | TRUE если $a больше $b |
Меньше или равно | $a <= $b | TRUE если $a меньше или равно $b |
Больше или равно | $a >= $b | TRUE если $a больше или равно $b |
<?php $a = 100; // целочисленная $b = '100'; // строковая var_dump($a == $b); // выведет bool(true) var_dump($a === $b); // выведет bool(false) ?>
При использовании операций сравнения следует помнить, что PHP неявно делает преобразование типов. Например, если сравнивается числовое значение со строкой, то строка конвертируется в число, а если сравниваются две строки, состоящие только из цифр - они обе конвертируются в числа и сравниваются в числовом виде.
Ещё один оператор сравнения - тернарный оператор "? :". Смысл его в том, что возвращается одно из значений в зависимости от условия. В общем виде тернарный оператор записывается так:
[lvalue] = (условие)? выражение, если условие истинно : выражение, если условие ложно ;
Например:
<?php ... $a = ($b > 100)? 'Больше сотни' : 'Меньше или равно 100'; echo $a; ?>
Если $b больше 100 - выведется "Больше сотни", а если меньше - 'Меньше или равно 100';
Операторы контроля ошибок
При выполнении скрипта все ошибки, предупреждения и замечания выводятся на экран. Отключить эту опцию можно, изменив INI-файл PHP, либо вызвав специальную функцию. Но эти изменения затронут сразу все скрипты на сервере. Для отключения вывода ошибок в одном выражении используется оператор контроля ошибок "@" (собака).
В нижеследующем примере, если файл 'counter.dat' отсутствует, то выполнение первой строки приведёт к выводу предупреждения, а вторая - нет.
<?php $file1 = file_get_contents('counter.dat'); $file2 = @file_get_contents('counter.dat'); ?>
Оператор подавления ошибок очень полезен при вызове функций, которые могут выдать ошибку независимо от стараний программиста. Пример такой функции - imagecreatefromjpeg(). Это функция открывает файлы формата jpeg, но если файлы приходят от пользователей, то могут быть и "битыми", а на таких файлах imagecreatefromjpeg() выдаёт ошибку.
Оператор выполнения
Оператор выполнения "``" (обратные кавычки) позволяет выполнять команды операционной системы и получать результат их выполнения. Однако у большинства провайдеров этот оператор отключен и его использование не даст никакого результата - возвращаемые данные будут всегда пусты.
<?php $output = `ipconfig /all`; echo "$output"; ?>
При запуске на ОС Windows этот скрипт выведет результаты работы утилиты ipconfig. Однако если PHP работает в безопасном режиме - скрипт не выведет ничего.
Операторы инкремента и декремента
Операторы инкремента "++" и декремента "--" применяются для изменения значения переменной на "1".
Название | Пример | Результат |
Пре-инкремент | ++$a | значение сначала увеличивается на "1", потом используется в выражении |
Пост-инкремент | $a++ | значение сначала используется в выражении, а потом увеличивается на "1" |
Пре-декремент | --$a | значение сначала уменьшается на "1", потом используется в выражении |
Пост-декремент | $a-- | значение сначала используется в выражении, а потом уменьшается на "1" |
Сравните эти два примера и разница между пост- и пре- операторами будет очевидной:
<?php // Пост-инкремент/пост-декремент // $a сначала выводится, потом изменяется $a = 1000; echo $a++; // выведет 1000 echo $a++; // выведет 1001 echo $a--; // выведет 1002 ?>
<?php // Пре-инкремент/пре-декремент // $a сначала изменяется, потом выводится $a = 1000; echo ++$a; // выведет 1001 echo ++$a; // выведет 1002 echo --$a; // выведет 1001 ?>
Интересно, что операция инкремента применима не только к числовым, но и к строковым переменным, а вот инкремент и декремент логических переменных никакого эффекта не даст.
Логические операторы
Логические операторы схожи с битовыми по принципу действия. Не надо забывать, что битовые операции И/ИЛИ обозначается одним символом, а логическая - двумя или специальным словом.
Название | Пример | Результат |
AND (И) | $a && $b или $a and $b | TRUE если оба операнда TRUE |
OR (ИЛИ) | $a || $b или $a or $b | TRUE, если хотя бы один оператор TRUE |
XOP (ИЛИ-НЕ) | $a xor $b | TRUE, когда только один из операторов TRUE |
NOT (Отрицание) | !$a | TRUE, когда операнд FALSE |
<?php $a = true; $b = false; $and = $a && $b; // $and = FALSE $or = $a || $b; // $or = TRUE $xor = $a xor $b; // $xor = TRUE $not = ~$a; // $not = FALSE ?>
На заметку: операция присвоения даёт TRUE если присвоение прошло успешно и присвоенное значение не равно FALSE. Поэтому следующий код выполняется без ошибок, но выполняется некорректно:
<?php $a = 'первое значение'; if($b = 200) $a = 'второе значение'; echo $a; ?>
Скрипт всегда будет выводить 'второе значение' при любом значении $b, т.к. выражение "$b = 200" всегда истинно. Это очень распространённая ошибка, которую достаточно сложно отловить и исправить. Поэтому при написании кода надо быть внимательным и аккуратным.
Строковые операторы
Единственный строковый оператор - оператор конкатенации "." (точка). Мы уже сталкивались с этим оператором ранее. Здесь лишь дополнительно отметим, что оператор "." достаточно интеллектуален и сам корректно производит большинство приведений типов. Это очень удобно, т.к. можно запросто одним выражением "склеить" несколько переменных разного типа.
<?php $year = 100; // целочисленная $name = ' Васе '; // строковая $result = 'Дяде ' . $name . ' ' . $year . ' лет.'; echo $result; // выведет "Дяде Васе 100 лет." ?>
Операторы массивов
Название | Пример | Результат |
Объединение | $a + $b или $a and $b | Объединение двух массивов |
Эквивалентность | $a == $b или $a or $b | TRUE, если массивы имеют одинаковый набор пар "ключ/значение" |
Идентичность | $a === $b | TRUE, если массивы имеют одинаковый набор пар "ключ/значение", в одинаковом порядке и одинакого типа |
Неэквивалентность | $a != $b или $a <> $b | TRUE, если массивы имеют различный набор пар "ключ/значение" |
Неидентичность | $a !== $b | TRUE, если массивы имеют различный набор пар "ключ/значение", в одинаковом порядке и одинакого типа |
Оператор объединения "+" добавляет элементы правого операнда к списку элементов левого операнда. При этом совпадающие пары "ключ/значение" не перезаписываются, а пропускаются.
Подробно мы рассмотрим операторы работы с массивами в соответствущей главе.
Оператор проверки типа
Единственный оператор проверки типа "instanceof" позволяет проверить, является ли данная переменная экземпляром того или иного класса.
<?php class FirstClass { } class SecondClass { } $a = new FirstClass(); var_dump($a instanceof FirstClass); // выведет bool(true) var_dump($a instanceof SecondClass); // выведет bool(false) ?>
При рассмотрении классов мы рассмотрим эту инструкцию более подробно.