Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Самоучитель по PHP 4

.pdf
Скачиваний:
82
Добавлен:
02.05.2014
Размер:
4.36 Mб
Скачать

Глава 7. Переменные, константы, выражения

131

Посмотрим еще раз на этот пример. Помните, я говорил, что практически все, из чего мы составляем программу — это выражения? Так вот, $b=$a —тоже выражение! (Впрочем, это не будет сюрпризом для знатоков Си или Perl). Нетрудно догадаться, какое оно имеет значение: 5 (тут просто не может быть никаких других вариантов, не правда ли?). А это значит, что мы можем написать что-то типа следующих команд:

$a=($b=10); // или просто $a=$b=10

При этом переменным $a и $b присвоится значение 10. А вот еще пример, уже менее тривиальный:

$a=3*sin($b=$c+10)+$d;

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

$b=$c+10; $a=3*sin($c+10)+$d;

Мы видим, что в PHP при вычислении сложного выражения можно (если какая-то его часть понадобится нам впоследствии) задавать переменным значения этой части прямо внутри оператора присваивания. Этот прием может действительно сильно упростить жизнь и сократить код программы, "читабельность" которой сохранится на прежнем уровне, так что советую им иногда пользоваться.

Совершенно точно можно сказать, что у любого выражения есть тип его значения. Например:

$a=10*20; $b="".(123*3);

echo "$a:",gettype($a)," $b:",gettype($b); // выведет "200:integer 200:string"

Чтобы преобразовать одно значение в другое (например, нам может не понравиться, что $b — типа string, хотя содержит целое число), используются операторы преобразования типов. Эти операторы доступны как в функциональной, так и в префиксной операторной форме. Например, следующие две инструкции эквивалентны:

$a = intval($b); $a = (int)$b;

Итак, вот эти операторы:

r$b=intval(выражение) или $b=(int)(выражение)

Переводит значение выражения в целое число и присваивает его $b.

r$b=doubleval(выражение) или $b=(double)(выражение)

Переводит значение в действительное число и присваивает его $b.

r$b=strval(выражение) или $b=(string)(выражение)

132

Часть III. Основы языка PHP

Переводит значение выражения в строку.

r$b=(bool)(выражение)

Преобразует значение выражения в логический тип. То есть, после выполнения этого оператора в $b окажется либо true, либо false.

Вообще-то, есть еще два хитроумных оператора (array) и (object), но эти операторы мы рассматривать не будем в силу их крайне слабой распространенности.

Логические выражения

Логические выражения — это выражения, у которых могут быть только два значения: ложь и истина (или, что почти то же самое, 0 и 1). Что, поверили? Напрасно — на самом деле абсолютно любое выражение может рассматриваться как логическое в "логическом" же контексте (например, как условие для конструкции if-else). Ведь, как уже говорилось, в качестве истины может выступать любое ненулевое число, непустая строка и т. д., а под ложью подразумевается все остальное.

Для логических выражений справедливы все те выводы, которые мы сделали насчет логических переменных. Эти выражения чаще всего возникают при применении операторов >, < и == (равно), || (логическое ИЛИ), && (логическое И), ! (логическое НЕ) и других. Например:

$a = 10<5;

// $a=false

$a = $b==1;

// $a=true, åñëè $b=5

$a = $b>=1&&$b<=10

// $a=true, если $b в пределах от 1 до 10

$a = !($b||$c)&&$d;

// $a=true, если $b и $c ложны, а $d — истинно

Как осуществляется проверка истинности той или иной логической переменной? Да точно так же, как и любого логического выражения:

$b = $a>=1&&$a<=10; // присваиваем $b значение логического выражения if($b) echo "a в нужном диапазоне значений";

Строковые выражения

Строки в PHP — одни из самых основных объектов. Как мы уже говорили, они могут содержать текст вместе с символами форматирования или даже бинарные данные. Определение строки в кавычках или апострофах может начинаться на одной строке, а завершаться — на другой. Вот пример, который синтаксически совершенно корректен:

$a="Это текст, начинающийся на одной строке и продолжающийся на другой, третьей и т. д.";

Глава 7. Переменные, константы, выражения

133

Я уже много раз использовал в примерах строковые константы, заключенные как в кавычки, так и в апострофы. Настало время поговорить о том, чем эти представления отличаются.

Строка в апострофах

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

rпоследовательность \' трактуется PHP как апостроф и предназначена для вставки апострофа в строку, заключенную в апострофы;

rпоследовательность \\ трактуется как один обратный слэш и позволяет вставлять в строку этот символ.

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

Строка в кавычках

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

r\n обозначает символ новой строки;

r\r обозначает символ возврата каретки;

r\t обозначает символ табуляции;

r\$ обозначает символ $, чтобы следующий за ним текст случайно не был интерполирован, как переменная;

r\" обозначает кавычку;

r\\ обозначает обратный слэш;

r\xNN обозначает символ с шестнадцатеричным кодом NN.

Переменные в строках интерполируются. Например:

$a="Hello"; echo "$a world!"

Этот фрагмент выведет Hello world!, т. е. $a в строке была заменена на значение переменной $a (этому поспособствовал знак доллара, предваряющий любую переменную).

Давайте рассмотрим еще один пример. $a="Hell"; // слово Hello без буквы "o" echo "$ao world!";

134

Часть III. Основы языка PHP

Мы ожидаем, что выведется опять та же самая строка. Но задумаемся: как PHP узнает, имели ли мы в виду переменную $a или же переменную $ao? Очевидно, никак. Запустив фрагмент, убеждаемся, что он генерирует сообщение о том, что переменная $ao не определена. Как же быть? А вот как:

$a="Hell"; // слово Hello без буквы "o" echo $a."o world!"; // один способ echo "{$a}o world!"; // другой способ echo "${a}o world!"; // третий способ!

Мы видим, что существует целых три способа преодолеть проблему. Каким из них воспользоваться — дело ваше. Мне больше нравится вариант с {$a}, хотя он и введен в PHP лишь недавно.

Последний пример показывает, что в некоторых контекстах и фигурные скобки могут трактоваться как спецсимволы.

Here-документ

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

$a=<<<MARKER

Далее идет какой-то текст, возможно, с переменными, которые интерполируются:

например, $name будет интерполирована здесь. MARKER;

Строка MARKER может быть любым алфавитно-цифровым идентификатором, не встречающимся в тексте here-документа в виде отдельной строки. Синтаксис накладывает 2 ограничения на here-документы:

rпосле <<<MARKER и до конца строки не должны идти никакие непробельные символы;

rзавершающая строка MARKER; должна оканчиваться точкой с запятой, после которой до конца строки не должно быть никаких инструкций.

Эти ограничения настолько стесняют свободу при использовании here-документов, так что, думаю, вам стоит совсем от них отказаться. Например, следующий код работать не будет, как бы нам этого ни хотелось (функция strip_tags() удаляет тэги из строки):

echo strip_tags(<<<EOD);

Глава 7. Переменные, константы, выражения

135

Какой-то текст с <b>тэгами </b> — этот пример НЕ работает! EOD;

Надеюсь, в будущем разработчики PHP изменят ситуацию к лучшему, но пока они этого не сделали.

Вызов внешней программы

Последняя строковая "константа" — строка в обратных апострофах (например, `команда`), заставляет PHP выполнить команду операционной системы и то, что она вывела, подставить на место строки в обратных апострофах. Вот так, например, мы можем в системе Windows узнать содержимое текущего каталога, которое выдает команда dir:

$st=`dir`;

echo "<pre>$st</pre>";

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

Операции

На самом деле, к этому моменту вы уже знакомы практически со всеми операциями над переменными и выражениями в PHP. И все же я приведу здесь их полный список с краткими комментариями, заменяя выражения-операнды буквами a и b.

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

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

ra + b — сложение

ra — b — вычитание

ra * b — умножение

ra / b — деление

ra % b — остаток от деления a на b

136

Часть III. Основы языка PHP

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

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

ra.b — слияние строк a и b

ra[n] — символ строки в позиции n

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

Операции присваивания

Основным из этой группы операций является оператор присваивания =. Еще раз напомню, что он не обозначает "равенство", а говорит интерпретатору, что значение правого выражения должно быть присвоено переменной слева. Например:

$a = ($b = 4) + 5;

После этого $a равно 9, а $b равно 4.

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

Помимо этого основного оператора, существует еще множество комбинированных — по одному на каждую арифметическую, строковую и другую операцию. Например:

$a = 10;

$a += 4; // прибавить к $a 4 $s = "Hello";

$s .= " world!"; // теперь в $s "Hello world!"

Думаю, не стоит особо на них задерживаться.

Операции инкремента и декремента

Для операций $a+=1 и $b-=1 в связи с их чрезвычайной распространенностью в PHP ввели, как и в Си, специальные операторы. Итак:

r$a++ — увеличение переменной $a на 1;

r$a-- — уменьшение переменной $a на 1.

Как и в языке Си, эти операторы увеличивают или уменьшают значение переменной, а в выражении возвращают значение переменной $a до изменения. Например:

Глава 7. Переменные, константы, выражения

137

$a=10; $b=$a++;

echo "a=$a, b=$b"; // выведет a=11, b=10

Как видите, сначала переменной $b присвоилось значение переменной $a, а уж затем последняя была инкрементирована. Впрочем, выражение, значение которого присваивается переменной $b, может быть и сложнее — в любом случае, инкремент $a произойдет только после его вычисления.

Существуют также парные рассмотренным операторы, которые указываются до, а не после имени переменной. Соответственно, и возвращают они значение переменной уже после изменения. Вот пример:

$a=10; $b=--$a;

echo "a=$a, b=$b"; // выведет a=9, b=9

Операторы инкремента и декремента на практике применяются очень часто. Например, они встречаются практически в любом цикле for.

Битовые операции

Эти операции предназначены для работы (установки/снятия/проверки) групп битов в целой переменной. Биты целого числа — это не что иное, как отдельные разряды того же самого числа, записанного в двоичной системе счисления. Например, в двоичной системе число 12 будет выглядеть как 1100, а 2 — как 10, так что выражение 12|2 вернет нам число 14 (1110 в двоичной записи). Если переменная не целая, то она вначале округляется, а уж затем к ней применяются перечисленные ниже операторы.

ra & b — результат — число, у которого установлены только те биты, которые установлены и у a, и у b одновременно.

ra | b — результат — число, у которого установлены только те биты, которые установлены либо в a, либо в b (либо одновременно).

r~ a — результат, у которого на месте единиц в a стоят нули, и наоборот.

ra << b — результат — число, полученное поразрядным сдвигом a на b битов влево.

ra >> b — аналогично, только вправо.

Операции сравнения

Это в своем роде уникальные операции, потому что независимо от типов своих аргументов они всегда возвращают одно из двух: false или true. Операции сравнения позволяют сравнивать два значения между собой и, если условие выполнено, возвращают true, а если нет — false.

r a == b — истина, если a равно b.

138

Часть III. Основы языка PHP

ra != b — истина, если a не равно b.

ra < b — истина, если a меньше b.

ra > b — аналогично больше.

ra <= b — истина, если a меньше либо равно b.

ra >= b — аналогично больше либо равно.

Следует отметить, что в PHP сравнивать можно только скалярные (то есть строки и числа) переменные. Для массивов и объектов этого делать нельзя. Их даже нельзя сравнивать на равенство (при помощи оператора ==), но при выполнении такой операции PHP не выдает предупреждения. Так что удивившись как-то раз, почему это два совершенно разных массива при сравнении их с помощью == оказываются вдруг одинаковыми, вспомните, что перед сравнением оба операнда преобразуются в слово array, которое потом и сравнивается.

Операции эквивалентности

В PHP версии 4 появился новый оператор сравнения — тройной знак равенства ===, или оператор проверки на эквивалентность. Как мы уже замечали ранее, PHP довольно терпимо относится к тому, что строки неявно преобразуются в числа, и наоборот. Например, следующий код выведет, что значения переменных равны:

$a=10; $b="10";

if($a==$b) echo "a и b равны";

И это несмотря на то, что переменная $a представляет собой число, а $b — строку. Впрочем, данный пример показывает, каким PHP может быть услужливым, когда нужно. Давайте теперь посмотрим, какой казус может породить эта "услужливость".

$a=0; // ноль

$b=""; // пустая строка if($a==$b) echo "a и b равны";

Хотя $a и $b явно не равны даже в обычном понимании этого слова, программа заявит, что они совпадают. Почему так происходит? Дело в том, что если один из операндов логического оператора может трактоваться как число, то оба операнда трактуются как числа. При этом пустая строка превращается в 0, который затем и сравнивается с нулем. Неудивительно, что оператор echo срабатывает.

Проблему решает оператор эквивалентности === (тройное равенство). Он не только сравнивает два выражения, но также их типы. Перепишем наш пример с использованием этого оператора:

$a=0; // ноль

$b=""; // пустая строка if($a===$b) echo "a и b равны";

Глава 7. Переменные, константы, выражения

139

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

$a=array(’a’=>’aaa’); $b=array(’b’=>’bbb’);

if($a==$b) echo "С использованием == a=b<br>"; if($a===$b) echo "С использованием === a=b<br>";

Если запустить представленный код, то выведется первое сообщение, но не второе. Произойдет это по той причине, что, как мы уже говорили, операнды-массивы преобразуются в строки array, которые затем и будут сравниваться. Оператор === лишен этого недостатка, поэтому работает верно.

Разумеется, для оператора === существует и его антипод — оператор !=== (он состоит из целых четырех символов!). Думаю, что не нужно объяснять, как он работает.

Логические операции

Эти операции предназначены исключительно для работы с логическими выражениями и также возвращают false или true.

r! a — истина, если a ложно, и наоборот.

ra && b — истина, если истинны и a, и b.

ra || b — истина, если истинны или a, или b, или они оба.

Следует заметить, что вычисление логических выражений, содержащих такие операции, идет всегда слева направо, при этом, если результат уже очевиден (например, false&&что-то всегда дает false), то вычисления обрываются, даже если в выражении присутствуют вызовы функций. Например, в операторе

$logic = 0&&(time()>100);

стандартная функция time() никогда не будет вызвана.

Будьте осторожны с логическими операциями — не забывайте про удваивание символа. Обратите внимание, что, например, | и || — два совершенно разных оператора, один из которых может потенциально возвращать любое число, а второй — толь-

ко false и true.

Оператор отключения предупреждений

Выдаче ясных и адекватных сообщений о возникших во время выполнения сценария ошибках разработчики PHP заслуженно уделили особое внимание. Наверное, вы уже запускали несколько простых PHP-программ из браузера и имели удовольствие ви-

140

Часть III. Основы языка PHP

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

К сожалению, PHP — чуть ли не первый язык, который выводит предупрежде- ния в браузер, а не в файлы журналов. Если вы работали некоторое время с таким языком, как Perl, то, наверное, уже успели устать от бесконечных вере- ниц "500-х ошибок", которые Perl выдает при малейшей оплошности в сцена- рии. Теперь можете вздохнуть с облегчением: PHP никогда не выдаст сообще- ние о 500-й ошибке, что бы ни произошло.

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

Однако не всегда это бывает удобно. Более того, иногда предупреждения со стороны интерпретатора просто недопустимы. Рассмотрим, например, такой сценарий (лис-

тинг 7.4):

Листинг 7.4. Навязчивые предупреждения

<form action=test.php>

<input type=submit name="doGo" value="Click!"> </form>

<?

if($doGo) echo "Вы нажали кнопку!"; ?>

Мы хотели сделать так, чтобы при нажатии на кнопку выдавалось соответствующее сообщение, но вот беда: теперь при первом запуске сценария PHP выдаст предупреждение о том, что "переменная $doCliсk не инициализирована". Ну не отключать же из-за такой мелочи контроль ошибок во всем сценарии, не правда ли? Как бы нам временно блокировать проверку ошибок, чтобы она не действовала только в одном месте, не влияя на остальной код?

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