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

Самоучитель PHP 4 - Котеров Д. В

..pdf
Скачиваний:
92
Добавлен:
24.05.2014
Размер:
4.38 Mб
Скачать

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 не инициализирована". Ну не отключать же из-за такой мелочи контроль ошибок во всем сценарии, не правда ли? Как бы нам временно блокировать проверку ошибок, чтобы она не действовала только в одном месте, не влияя на остальной код?

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

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

141

На самом деле текст предупреждения сохраняется в переменной PHP $php_errormsg, которая может быть в будущем проанализирована. Эта воз- можность доступна, если в настройках PHP включен параметр track_errors (по умолчанию он как раз и установлен в yes).

Вот теперь мы можем переписать наш пример, грамотно отключив надоедливое предупреждение (листинг 7.5).

Листинг 7.5. Отключение навязчивого предупреждения

<form action=test.php>

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

<?

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

Как можно заметить, листинг 7.5 отличается от листинга 7.4 всего лишь наличием оператора @ внутри скобок инструкции if.

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

Глава 8

Работа с данными формы

Дойдя до этого места, я столкнулся с проблемой непростого выбора: продолжать и дальше рассказывать о самом языке PHP или же чуть-чуть уйти в сторону и рассмотреть более прикладные задачи. Я остановился на последнем. Как-никак, Webпрограммирование в большей части (или хотя бы наполовину) представляет собой как раз обработку различных данных, введенных пользователем — т. е., обработку форм.

Пожалуй, нет другого такого языка, как PHP, который бы настолько облегчил нам задачу обработки и разбора форм, поступивших из браузера. Дело в том, что в язык на самом нижнем уровне встроены все необходимые возможности, так что нам не придется даже и задумываться над особенностями протокола HTTP и размышлять, как же происходит отправка и прием POST-форм или даже загрузка файлов. Разработчики PHP все предусмотрели.

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

Передача данных командной строки

Вначале хочу вас поздравить: сейчас мы уже знаем достаточно, чтобы начать писать простейшие сценарии на PHP типа "Hello world, сейчас 10 часов утра". Однако нашим сценариям будет недоставать одного — интерактивного взаимодействия с пользователем.

Зададимся задачей написать сценарий, который принимает в параметрах имя и возраст пользователя и выводит: "Привет, <имя>! Я знаю, вам <возраст> лет!".

Сначала рассмотрим наиболее простой способ передачи имени и возраста сценарию — непосредственный набор их в URL после знака ? — например, в формате name=имя&age=возраст (мы рассматривали этот прием в первой части книги). Правда, даже программисту довольно утомительно набирать эту строку вручную.

144

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

Всякие там ?, &, %... К счастью, существуют удобные возможности языка HTML, которые, конечно, поддерживаются всеми браузерами.

Итак, пусть у нас на сервере в корневом каталоге есть сценарий на PHP под названием hello.php. Наш сценарий распознает 2 параметра: name и age. Он должен отработать и вывести следующую HTML-страницу:

<html><body>

Привет, name! Я знаю, Вам age лет! </body></html>

Разумеется, нужно name и age заменить на соответствующие значения. Таким образом, если задать в адресной строке браузера

http://www.somehost.com/script.cgi?name=Vasya&age=20

мы должны получить страницу с требуемым результатом.

Как только задача осознана, можно приступать к ее решению. Но прежде бывает полезно решить аналогичную, но более простую задачу. Итак, как же нам в сценарии получить строку параметров, переданную после знака вопроса в URL при обращении к сценарию? Как было указано в первой части книги, для этого можно проанализировать переменную окружения QUERY_STRING, которая в PHP доступна под именем $QUERY_STRING. Напишем небольшой пример, чтобы это проиллюстрировать (лис-

тинг 8.1).

Листинг 8.1. Вывод параметров командной строки

<html><body>

<?

echo "Данные из командной строки: $QUERY_STRING"; ?>

</body></html>

Если теперь мы запустим этот сценарий из браузера (перед этим сохранив его в файле test.php в корневом каталоге сервера) примерно вот таким образом:

http://www.myhost.com/test.php?aaa+bbb+ccc+ddd

то получим документ следующего содержания:

Данные из командной строки: aaa+bbb+ccc+ddd

Обратите внимание на то, что URL-декодирование символов не произошло: строка $QUERY_STRING, как и одноименная переменная окружения, всегда приходит в той же самой форме, в какой она была послана браузером. Давайте запомним этот небольшой пример — он еще послужит нам в будущем.

Так как PHP изначально создавался именно как язык для Web-программирования, то он дополнительно проводит некоторую работу с переменной $QUERY_STRING перед

Глава 8. Работа с данными формы

 

 

145

тем,

как

управление

будет

передано

сценарию.

А именно, он разбивает ее по пробельным символам (в нашем примере пробелов нет, их заменяют символы +, но эти символы PHP также понимает правильно) и помещает полученные кусочки в массив-список $argv, который впоследствии может быть проанализирован в программе. Заметьте, что здесь действует точно такая же техника, которая принята в Си, с точностью до названия массива с аргументами.

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

Формы

Вернемся к поставленной задаче. Как нам сделать, чтобы пользователь мог в удобной форме ввести свое имя и возраст? Очевидно, нам придется создать что-нибудь типа диалогового окна Windows, только в браузере. Итак, нам понадобится обычный HTML-документ (например, по имени form.html в корневом каталоге) с элементами этого диалога — текстовыми полями — и кнопкой. Давайте возьмем ту же самую форму, которую я уже приводил в примере в первой части книги, только теперь мы уже будем не просто разбирать, как и куда поступают данные, а напишем сценарий, который эти данные будет обрабатывать (листинг 8.2).

Листинг 8.2. form.html: страница с формой

<html><body>

<form action=hello.php>

Введите имя: <input type=text name="name" value="Неизвестный"><br> Введите возраст: <input type=text name="age" value="неопределенный"><br> <input type=submit value="Нажмите кнопку, чтобы запустить сценарий!"> </form>

</body></html>

Загрузим наш документ в браузер. Теперь, если ввести в поле с именем свое имя, а в поле для возраста — свой возраст и нажать кнопку, браузер автоматически обратится к сценарию hello.php и передаст через ? все атрибуты, расположенные внутри тэгов <input> в форме и разделенные символом & в строке параметров. Заметьте, что в атрибуте action тэга <form> мы задали относительный путь, т. е. сценарий hello.php будет искаться браузером в том же самом каталоге, что и файл form.html.

Как мы знаем, все перекодирования и преобразования, которые нужны для URLкодирования данных, осуществляются браузером автоматически. В частности, буквы

146

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

кириллицы превратятся в %XX, где XX — некоторое шестнадцатеричное число, обозначающее код символа.

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

Листинг 8.3. hello.php — модель простого PHP-сценария

<html><body>

<?

получаем в $name имя из параметров, а в $age — возраст echo "Привет, $name!<br> Я знаю, Вам $age лет!";

?>

</html></body>

Осталось теперь только определиться, как мы можем извлечь $name и $age из строки параметров. Конечно, мы можем попытаться разобрать ее "вручную" при помощи стандартных функций работы со строками (которых в PHP великое множество), и этот прием действительно будет работать. Однако, прежде чем браться за ненужное дело, давайте посмотрим, что нам предлагает сам язык.

Трансляция полей формы в переменные

Итак, мы не хотим заниматься прямым разбором переменной окружения QUERY_STRING, в которой хранятся параметры сценария. И правильно не хотим — интерпретатор перед запуском сценария делает все сам. Причем независимо от того, каким методом — GET или POST — воспользовался "браузер". То есть, PHP сам определяет, какой метод был задействован (благо, информация об этом доступна через переменную окружения REQUEST_METHOD), и получает данные либо из QUERY_STRING, либо из стандартного входного потока. Это крайне удобно и достойно подражания, вообще говоря, в любых CGI-сценариях.

А именно, интерпретатор все данные из полей формы преобразует в глобальные од- ноименные переменные. В нашем случае значение поля name после начала работы программы будет храниться в переменной $name, а значение поля age — в переменной $age. То есть, не надо ничего ниоткуда "получать" — все уже установлено и распаковано из URL-кодировки. Максимум удобств, минимум затрат, не правда ли? К тому же, еще и работает быстрее, чем аналогичный кустарный код, написанный на PHP, потому что разработчики PHP предусмотрели функцию разбора командной строки на Си.

Глава 8. Работа с данными формы

147

Вот наш окончательный сценарий hello.php (листинг 8.4). Как видите, он сжался до неприличных размеров:

Листинг 8.4. hello.php: окончательная версия

<html><body>

<? echo "Привет, $name!<br> Я знаю, Вам $age лет!" ?> </html></body>

Давайте теперь его усовершенствуем — сделаем так, чтобы при запуске без параметров сценарий выдавал документ с формой, а при нажатии кнопки — выводил нужный текст. Самый простой способ определить, был ли сценарий запущен без параметров — проверить, существует ли переменная с именем, совпадающим с именем кнопки отправки. Если такая переменная существует, то, очевидно, что пользователь запустил программу, нажав на кнопку. Здесь мы применим инструкцию if, которая нами еще не рассматривалась, но, думаю, читатель простит мне этот огрех (лис-

тинг 8.5).

Листинг 8.5. hello.php: усовершенствованная версия

<html><body> <?if($doGo) {?>

<form action="<?=$SCRIPT_NAME?>">

Введите имя: <input type=text name="name"><br> Введите возраст: <input type=text name="age"><br>

<input type=submit name="doGo" value="Нажмите кнопку!"> </form>

<?} else {?>

Привет, <?=$name?>!<br>

Я знаю, Вам <?=$age?> лет!" <?}?>

</html></body>

Из этого примера мы можем почерпнуть еще один удобный прием, который нами пока не рассматривался. Это конструкция <?=выражение?>. Она является ничем иным, как просто более коротким обозначением для <?echo(выражение)?>, и предназначена для того, чтобы вставлять величины прямо в HTML-страницу.

Помните наши рассуждения о том, что же первично в PHP: текст или програм- ма? Конструкция <?= применяется обычно в тот момент, когда выгодно счи-