Текст
                    PHP в примерах
.* a


spiring into PHP 5 Steven Holzner A Addison-Wesley Upper Saddle River, NJ • Boston • Indianapolis • San Francisco New York • Toronto • Montreal • London • Munich • Paris • Madrid Capetown • Sydney • Tokyo • Singapore • Mexico City
Стивеи Хольцнер PHP в примера! Перевод с английского под редакцией Банникова С.Н. Москва Издательство БИНОМ 2007
УДК 004.43 ББК 32.973.26-018.1 Х75 Стивен Холыднер РНР в примерах. Пер. с англ. 352 с: ил. М.: 0 0 0 «Бином-Пресс», 2007 г. Вашему вниманию предлагается один из мировых бестселлеров, посвященных программированию на РНР. В рамках одной книги автору удалось, начав с основ языка РНР, охватить весьма широкий круг вопросов — от объектно-ориентированного программирования до сложной обработки web-форм, от сохранения данных сеанса работы до формирования e-mail. Теоретический материал излагается в компактной и сжатой форме, и основное место отдано практическим примерам использования богатых возможностей РНР. Книга предназначена в основном для начинающих разработчиков на РНР, но и про- фессионат может найти в ней немало интересных моментов. Authorized translation from the English language edition, entitled Spring into PHP 5, First Edition by Holzner, Steven, published by Pearson Education, Inc, publishing as Addison Wesley Professional, Copyright © 2005 byAddison-Wesley. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc. Russian language edition published by Binom Publishers. Copyright © 2007 by Binom Publishers. Все права защищены. Никакая часть этой книги не может быть воспроизведена в любой форме или любыми средствами, электронными или механическими, включая фотографирование, магнитную запись или иные средства копирования или сохранения информации без письменного разрешения издательства. ISBN 978-5-9518-0188-3 (русск.) ISBN 0-13-149862-2 (англ.) Authorized translation from the English language edition © Original Copyright. Addison-Wesley, 2005 0ИЗД шнешрус С" ° * « з " к е , Издательство Бином, 2007
Содержание Введение 9 Об авторе 10 Глава 1. Введение в РНР 11 Доступ к РНР. 12 Локальная установка РНР 12 Настройка среды разработки 14 Первый скрипт. 16 Запуск первого скрипта 17 Возможные проблемы 18 РНР и HTML 19 Отображение текста 21 Возможности отображения текста 23 Синтаксис heredoc 25 Запуск РНР в командной строке 25 Комментарии в скриптах 28 Переменные 29 Создание переменных 30 Интерполяция переменных в строках 31 Переменные, содержащие имена переменных 34 Константы 35 Типы данных 38 Итоги 39 Глава 2. Операторы 41 Математические операторы .41 Математические функции 43 Операторы присваивания 44 Увеличение и уменьшение 45 Приоритет операторов .47 Оператор исполнения .49 Строковые операторы 51 Битовые операторы 51 Условный оператор IF. 53 Операторы сравнения 55 Логические операторы 56 Оператор ELSE. 57 Оператор ELSEIF. 58 Тернарный оператор 59 Оператор SWITCH 60 Циклы КЖ. 62 Циклы\\НПЕ. 65 Циклы DO. . .WHILE. 66 Циклы FOREACH 67
6 PHP в примерах Оператор BREAK 68 Оператор CONTINUE. 69 Альтернативный синтаксис 70 Итоги 71 Глава 3. Строки и массивы 73 Функции обработки строк 73 Использование строковых функций 76 Форматирование строк 77 Преобразование в строки и из строк 78 Создание массивов 79 Модификация элементов массива 81 Удаление элементов массива 83 Перебор элементов массива 84 Функции для работы с массивами 85 Сортировка массивов 88 Навигация по массивам 89 Преобразование строк в массивы и наоборот. 91 Извлечение переменных из массивов 92 Слияние и разделение массивов 95 Сравнение массивов 96 Обработка данных в массивах 97 Многомерные массивы 99 Многомерные массивы и циклы 102 Операторы над массивами 104 Итоги 105 Глава 4. Функции 107 Создание функции 107 Передача данных в функцию 110 Передача массивов в функцию. 112 Значения аргументов по умолчанию 113 Передача аргумента по ссылке 115 Функции с переменным количеством аргументов 117 Функции, возвращающие значение 119 Функция, возвращающая массив. 121 Использование списков 123 Функция, возвращающая ссылки 125 Локальные переменные 125 Глобальные переменные 127 Статические переменные 129 Переменные, ссылающиеся на функции 132 Условное описание функций 134 Вложенные функции 136 Вложенные файлы 136 Обработка ошибок 139 Итоги 141 Глава 5. Элементы управления HTML 143 Создание web-форм 144 Текстовые поля 146 Получение данных из текстовых полей 147 Многострочные поля 149 Выключатели (checkboxes) 151 Переключатели (radio buttons) 153 Списки 156 Скрытые поля 159 Поля для паролей 161
Содержание 7 Кнопка-изображение 162 Загрузка файлов 165 Обработка загруженного файла 167 Кнопки: вариант 1 168 Кнопки: вариант 2 172 Кнопки: вариант 3 173 Итоги 175 Глава 6. Web-приложения. 177 Отображение данных формы 178 Переменные сервера 180 Заголовки HTTP. 182 Определение типа браузера 183 Перенаправление 185 Организация полей форм в массивы 188 Приложение из одной страницы 190 Проверка данных 193 Обязательное для заполнение поле 194 Проверка числовых полей 196 Проверка строковых полей 199 Удаление тегов HTML 200 Кодирование тегов HTML 204 Сохранение данных 208 Использование JavaScript для проверки данных 210 HTTP-аутентификация 211 Итоги 213 Глава 7. ООП и файлы 215 Классы и объекты 215 Создание класса 216 Создание объекта 218 Управление доступом к свойствам и методам 219 Конструкторы объектов 220 Наследование классов 222 Наследование и защищенные методы 224 Перекрытие методов 227 Доступ к методам базового класса 229 Открытие файла: fopen. 231 Чтение строк текста: fgeta 233 Чтение символов: fgetc. 234 Двоичное чтение файла: fread 236 Чтение файла целиком: filegetcontenta 238 Синтаксический разбор файла: fscanf 239 Запись в файл: fwrite 242 Добавление к файлу: fwrite 243 Запись файла целиком: fileputcontenta 245 Итоги 247 Глава 8. Базы данных 249 Базы данных 250 Основы SQL 251 Настройка РНР для работы с базами данных 252 Создание базы данных в MySQL 253 Добавление данных 255 Доступ к базе MySQL 256 Создание базы данных 258 Создание новой таблицы 259 Добавление данных 261
8 PHP в примерах Отображение данных 262 Изменение данных 264 Сортировка данных 266 Удаление данных 268 Установка модуля DB 270 Отображение данных при помощи DB 271 Добавление данных при помощи DB 273 Изменение данных при помощи DB 275 Итоги 277 Глава 9. Cookie, сеансы, FTP, e-mail 279 Установка cookie 279 Чтение cookie 282 Срок действия cookie 283 Удаление cookie 286 Использование FTP 286 Список файлов каталога 288 Загрузка файла с FTP-сервера 289 Загрузка файла на FTP-сервер 291 Отправка e-mail 294 E-mail с дополнительными заголовками 296 E-mail с вложенными файлами 298 Сеансы 300 Сохранение данных сеансов 303 Создание счетчика посещений 305 Сеансы без cookie 308 Удаление данных сеанса 310 Итоги 313 Приложение А. Справочник по языку. 315 Создание скриптов 315 Типы данных 316 Переменные 318 Предопределенные переменные 318 Массивы 319 Операторы 320 Оператор if 322 Оператор else 322 Оператор else if 323 Оператор switch. 323 Оператор while 325 Оператор do . . .while 326 Оператор for. 327 Оператор foreach. 327 Функции 328 Классы и объекты 329 Приложение Б. Справочник функций. 333
Введение Добро пожаловать в мир РНР! Эта книга написана на доступном и понятном языке и представляет собой введение в программирование на РНР. Лучшим способом научиться программировать — это начать программировать, и книга содержит огромное количество практического материала — фрагментов кода и законченных примеров. Книга предназначена для тех, кто хочет разрабатывать свои собственные приложения для использования в Интернет. Книга специально написана так, что не требует специальных знаний для ее освоения. Главным и единственным требованием является знакомство с HTML. Книга состоит из девяти глав: • Глава 1 содержит базовые сведения о РНР. • Глава 2 содержит описание операторов и управляющих структур языка. • Глава 3 посвящена обработке строк и массивов. • Глава 4 рассказывает о функциях. • Глава 5 описывает использование элементов управления HTML и онлайновых форм. • Глава 6 показывает порядок разработки типичного web-приложения. • Глава 7 демонстрирует преимущества объектно-ориентированного программирования, а также описывает средства для работы с файлами. • Глава 8 посвящена работе с базами данных на примере MySQL. • Глава 9 описывает различные полезные технологии - cookies, сеансы, FTP, электронную почту и др. Все, что нужно для освоения книги — базовые знания HTML. Можно ничего не знать о программировании — вся необходимая информация содержится внутри этой книги В книге описывается РНР 5.1.x, который свободно доступен для загрузки из Интернета. Установка его достаточно проста, в отличие от многих коммерческих пакетов. Книга содержит основные сведения по установке и настрой- кеРНР. Для изучения РНР не требуется доступ в Интернет. При необходимости возможно заниматься разработкой web-приложений локально, на своем собственном компьютере. Но для размещения созданного приложения в Интернете придется воспользоваться услугами хостинг-провайдера, который поддерживает РНР. В настоящее время РНР поддерживает практически каждый уважающий себя коммерческий провайдер, существуют и бесплатные хостинги с поддерж- койРНР. Каждая тема книги раскрыта в небольшом разделе, который занимает од- ну-две страницы. Каждый раздел основан на предыдущем разделе. Большинство разделов содержат один-два примера использования описываемых понятий и технологий. Примеры представляют собой законченные скрипты, которые можно запускать и сразу же увидеть результат их выполнения.
10 Об авторе Об авторе Стивен Хольцнер (Steven Holzner) писал о программировании в Интернете с его возникновения. Он обладает громадным опытом в использовании РНР и других языков разработки, используемых в Интернете, и является автором 88 книг по программированию. Среди них несколько бестселлеров суммарным тиражом свыше двух миллионов экземпляров, его книги переведены на 18 языков. Он также является постоянным автором PC Magazine. Его специальностью является программирование для Интернета, включая использование РНР, Perl, JavaServer и т.п.
Введение в РНР Добро пожаловать в мир РНР! РНР официально расшифровывается1 как «РНР: Hypertext Preprocessor», но первоначальный вариант звучал как «Personal Home Page», что напоминает о том, для чего появился этот продукт — для создания интерактивных личных сайтов. С приходом РНР можно было не ограничивать себя статичными, неизменными HTML-страницами. Теперь содержимое сайта можно формировать по запросу в реальном времени. Можно обрабатывать нажатия кнопок, заполнения разнообразных форм, хранить информацию в базах данных и даже динамически формировать графические изображения. Все эти возможности предоставляет одно и то же средство, имя которому — РНР. В данной книге описывается РНР 5-й версии (на момент выхода последним официальным вышедшим релизом является 5.1.6). Версия РНР 6.0 находится в состоянии разработки, но ее уже реализованные особенности описаны в книге. Официальный сайт РНР — www.php.net. Данная книга начинается с вопроса установки РНР на web-сервер. При использование статических HTML-страниц web-сервер только передает запрошенные пользователем файлы браузеру на стороне клиента, где пользователь видит текст и графические изображения, но этим всё и ограничивается. Если же используются программы на РНР (они называются скриптами), которые исполняются на стороне сервера, то становится возможным формировать страницы в ответ на различные действия пользователя, с учетом данных, вводимых в текстовые поля, положений выключателей и переключателей и т.п. В этом и состоит квинтэссенция динамической генерации HTML-страниц. В настоящее время РНР используется на более чем 15 миллионах web-серверов. В следующем разделе рассказывается о порядке установки РНР на web-сервер. Рекурсивная расшифровка сокращений (когда исходное сокращение включается в текст расшифровки) достаточно популярна в среде специалистов по UNIX, стоит вспомнить, например «GNU's not Unix». — Прим.ред.
12 Глава 1. Введение в РНР Доступ к РНР Первым шагом в создании собственных интерактивных web-страниц является получение доступа к web-серверу, на котором установлен РНР. Возможно, ваш хостинг-провайдер уже поддерживает РНР, Этот факт можно уточнить в его службе технической поддержки, или же можно проверить это самостоятельно одним из двух способов. Во-первых, если вы имеете доступ к командной строке web-сервера при помощи telnet, SSH или SSH2 (если эти слова ничего вам не говорят, не страшно — в рамках данной книги знание этих технологий не требуется), можно попытаться набрать команду php - v в командной строке (в данной книге символ « % » используется как приглашение командной строки операционной системы). Если РНР установлен, то на экране будет отображен текст следующего вида (конкретное его содержание зависит от операционной системы и версии РНР): %php -v РНР 5.1.5 (cli) (built: Aug 15 2006 23:54:56) Copyright (с) 1997-2006 The PHP Group Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies Другим способом определения наличия РНР является попытка запуска какого-либо PHP-скрипта. Для этого следует обратиться к разделу «Первый скрипт» ниже в этой главе. Если тестовый скрипт работает, то РНР установлен и может быть использован. Замечание " , Список некоторых хостинг-провайдеров, которые предоставляют своим клиентам £ РНР, находится по следующей ссылке: www.php.net/links.phpffhosti. В настоящее время подавляющее большинство коммерческихпровайдеровпредоставляютсвоим клиентам РНР, существуюттакже и некоторые бесплатныехостинги с подобной услугой. Локальная установка РНР Весьма полезно установить РНР на собственный локальный компьютер для того, чтобы иметь возможность эффективно разрабатывать и тестировать PHP-скрипты. В этом случае нет необходимости постоянно загружать их на web-сервер, что существенно повышает эффективность работы программиста. Некоторые операционные системы, например, Linux и многие версии UNIX, уже имеют в своем составе РНР. В других, например, в Windows и Мае OS, требуется загрузить и установить РНР вручную. Первым шагом является проверка наличия РНР при помощи запуска php -v в командной строке операционной системы. Если на экран выводится текущая версия РНР, то все уже установлено. Если же РНР отсутствует, его следует установить. Для многих операционных систем - Windows, Mac OS, Novell NetWare, OS/2, RISC OS, SGI IRIX 6.5.x и AS/400 — существуют скомпилированные бинарные пакеты для установки. Все они перечислены в Интернете на странице www.php.net/downloads.php.
Локальная установка РНР 13 Для операционных систем UNIX и Linux бинарные установочные пакеты больше не распространяются, так как обычно РНРуже входитв поставку операционной системы. Длятого, чтобы осуществить компиляцию РНРсамостоятельно, можно воспользоваться исходными кодами, доступными настранице www.php.nef/down/oads.php. Инструкцию по установке РНР можно найти в документации, которая доступна в онлайне по адресу www.php.net/docs.php. Документацию также можно выкачать для просмотра в оффлайне со страницы www.php.net/down- load-docs, php. Кроме того, установка РНР описана в файле install.txt, который содержится в каталоге, создаваемом при разархивации установочного пакета РНР. Так как для каждой версии РНР эти инструкции слегка различны, и к тому же они отличаются в зависимости от версии web-сервера, которая будет использована, нет смысла приводить их здесь — они всё равно уже устареют, когда книга выйдет в печать. Следует ознакомиться с инструкцией к конкретной версии продукта и аккуратно ее исполнить. Но для Windows XP ниже приведена примерная последовательность действий. Для начала потребуется работающий web-сервер, например, Apache или Microsoft Internet Information Server (IIS). Установочный пакет сервера Apache1 (например, apache_2.0.59-win32-x86-no_ssl.msi) можно закачать с сайта httpd.apache.org/download.cgi. При выполнении данного файла будет запущен процесс установки web-сервера. Microsoft IIS устанавливается при помощи Панели управления, пункт «Установка и удаление программ | Добавление и удаление компонентов Windows». Следует выбрать пункт «Internet Information Services (IIS)» и нажать кнопку «Далее» для начала процесса установки. Для установки РНР требуется загрузить соответствующий архив со страницы www.php.net/downloads.php. После загрузки архив следует распаковать, например, в каталог C:\PHP. В архив включена и инструкция по дальнейшей установке и настройке. Следующим шагом является подключение РНР к web-серверу. РНР может быть подключен к web-серверу двумя способами — как внешнее приложение РНР.ЕХЕ (так называемый CGI-вызов) и как встраиваемый модуль (обычно в виде библиотеки DLL). При использовании РНР в режиме внешнего приложения недоступны некоторые полезные его функции (например, использование механизма аутентификации), кроме того, в данном случае снижается производительность. Поэтому рекомендуется использовать РНР в режиме модуля web-сервера (этот режим доступен не для всех web-серверов). Если используется Apache, следует отредактировать его конфигурационный файл http.conf в соответствии с инструкцией по установке РНР. Например, для Apache 2.0 и РНР в режиме модуля требуется добавить следующие команды: LoadModulephp5_module "с: /php/php5apache2 . dll" AddType application/x-httpd-php .php Microsoft IIS настраивается при помощи Панели управления, раздел «Администрирование | Internet Information Services», в соответствии с инструкцией по установке. На момент верстки книги существует Apache 2.2, но длянего еще невышел соответствующий модуль РНР, поэтому рекомендуется использовать версию 2.0 или 1.3. —Прим.ред.
14 Глава 1. Введение в РНР Настройка среды разработки Для создания PHP-скриптов требуется текстовый редактор, который в состоянии работать и с HTML, и с Р НР. Для этого может быть использован практически любой текстовый редактор, которых имеется достаточное количество для любой операционной системы. В их числе vi, emacs, pico, Macintosh's BBEdit, SimpleText, Windows Notepad, WordPad. По умолчанию для скриптов РНР используется расширение .php (например, sample.php). Для создания скриптов обычно используется смесь HTML и Р Н Р, как показано на рис. 1.1. Для создания подобного скрипта необходимо всего лишь ввести этот текст в любом текстовом редакторе и сохранить результат в файле с расширением . php. Как видно, текст преимущественно состоит из HTML; собственно код на РНР заключен между тегами < ?php и ? >. Когда web-сервер обрабатывает подобный документ, он выделяет все фрагменты <?php ... ?> и передает их РНР, помещая обратно результат выполнения программы. В данном случае код состоит из единственной строчки phpinf о (), которая отображает справочную таблицу с разнообразной информацией о конфигурации РНР и web-сервера (см. разд. «Первый скрипт» ниже). Ш phphtml.php - WordPad айл Правка Вид Вставка Формат "правка • с* а ш а « ; "А «а '-> ^ fzmm <HTML> <HEAD> <TITLE> Использование HIML и РНР в одном файле </ТПХЕ> </HEAD> <BODY> <Н1> Использование HIML и РНР в одном файле </Н1> <?php phpinfo (); ?> | </body> </НТН1> Для вывода справки нажмите <F1 >_ http://all-ebooks.com Рис. 1.1. Создание PHP-скрипта, содержащего HTML-код
Настройка среды разработки 15 Замечание Щ р Программа Windows WordPad автоматически добавляет расширение «.txt» при со- / хранении любого файла, еслионане может распознать его расширение. Еслипопы- таться сохранить файл срасширением«.рпр», то на самом деле будетсоздан файл с расширением «.php.txt», что несколько неожиданно. Длятого, чтобы предотвратить подобное поведение, следует заключить имя файла при сохранении в кавычки, например «sample.php». Крометого, следуетобратить внимание нало, что WordPad по умолчанию сохраняет файлы в формате RTF или Microsoft Word (в зависимости отверсииоперационнойсистемы).Дг№того,чтобыфайлысохранялисьвпростомтек- стовом формате, для их сохранения следует использовать команду «Сохранить как» и выбрать формат файла «Текст». Для создания PHP-скриптов можно даже использовать текстовый процессор, например, Microsoft Word, но при этом следует сохранять файлы в текстовом формате (для Word это режим «Только текст» при вызове команды «Файл | Сохранить как»). Но лучше все-таки использовать простой текстовый редактор, так как текстовый процессор при неаккуратном обращении способен переформатировать всю программу по своему вкусу, что может повлечь за собой неприятные последствия. Можно также использовать интегрированную среду разработки (IDE, integrated development environment). IDE помимо собственно текстового редактора включает в себя множество дополнительных возможностей — проверку синтаксиса по мере ввода текста, выделение синтаксических элементов различными цветами и начертаниями шрифта, а также автоматическую загрузку разработанных скриптов на web-сервер. Ниже приведен краткий перечень наиболее распространенных IDE для РНР. Большинство из них содержат много полезных функций, но являются коммерческими продуктами. • Komodo (www.activestate.com/Products/Komodo) — существует под Linux и Windows. • Maguma (www.maguma.com) — существует только под Windows. PHPEdit (www.phpedit.com/products/PHPEdit) — существует только под Windows, программный пакет бесплатен. • Zend Studio (www.zend.com/store/products/zend-studio.php) — существует под Windows и Linux. Эта IDE создана той же самой командой программистов, которые разработали программный движок Zend, являющийся ядром самого РНР. После разработки готового сайта с использованием РНР его следует разместить в Интернете на хостинге. Для этого обычно используется передача файлов при помощи протокола FTP (File Transfer Protocol — протокол передачи файлов). Хостинг-провайдер может также предоставлять собственный web-интерфейс для закачки файлов. PHP-скрипты с точки зрения закачки их на сервер ничем не отличаются от обычных HTML-страниц.
16 Глава 1. Введение в РНР Первый скрипт Первый скрипт на РНР будет достаточно простым, но уже он продемонстрирует совместное использование HTML и РНР. Для выделения РНР-кода в HTML-документе используются специальные теги <?php и ?>: <?php код на РНР. Замечание ' У Для выделения РНР-кода можно использовать также сокращенную форму <?... ?>, / для чего в конфигурационном файле php.iniследует включить режим shortopentag. Использование данного режима, однако, не рекомендуется, ток как разные web-серверы могут быть сконфигурированы по-разному, поэтому создаваемый таким обра- зомкоднеявляетсяполностьюпереносимым.Крометого.данныйсинтаксисможет конфликтоватьсдругимискрмптовыммязыками. *-Г-*У**^1*1+™г<?^*£^г*&гч?гк&1Щ1ЮГ1Ь*ХЧ^ Между этими тегами и размещается код на РНР. Код состоит из отдельных операторов, каждый из которых завершается точкой с запятой. Использование точки с запятой в конце оператора является обязательным, ее отсутствие вызовет сообщение об ошибке. В других языках, например, в JavaScript, точка с запятой не является обязательной в конце строки, но в РНР это строгое требование. Наш первый скрипт состоит из единственного оператора phpinfo (). Ниже будет показано, что в РНР предусмотрена самые разнообразные операторы на все случаи жизни. В данном случае используется функция phpinfo для отображения сведений о версии и конфигурации используемого варианта РНР. Функция представляет собой последовательность операторов, иногда достаточно длинную, которая обозначена определенным именем, по которой она может быть вызвана в любом месте программы. Функция phpinfo является одной из многих встроенных функций РНР. Ниже приведен пример вызова данной функции: <?php phpinfo (); ?> Данный текст следует ввести в любом текстовом редакторе, например, в WordPad (см. рис. 1.2), и сохранить под именем phpinfo. php. Следует убедиться, что файл сохранен в текстовом формате, в противном случае он не будет корректно обработан РНР. Одним из способов проверить правильность сохранения файла является его вывод при помощи команды TYPE в командной строке Windows. После создания файла его следует загрузить на хостинг при помощи FTP или web-интерфейса. В случае локальной работы необходимо скопировать его в каталог документов web-сервера. Для Apache это подкаталог htdocs (если в настройках не указано иное), для IIS по умолчанию это каталог inetpub/wwwroot, в операционной системе Linux этот каталог может называться /var/www/html. После чего можно переходить непосредственно к запуску скрипта.
Запуск первого скрипта 17 ОЙ® файл Оравка Й1Д Вставка Фориат Справка <?php I» phpinfo (); Для вывода справки нажмите <F1 > Рис. 1.2. Создание РНР-скрипта Запускпервогоскрипта Для запуска скрипта следует ввести полный путь к нему в адресной строке браузера. При работе с хостингом адрес может выглядеть примерно так: http: //www. oursite. com/phpinfo. php. В случае локальной установки адрес будет наподобие следующего: http: //localhost /phpinfo. php. Замечание и^«ХЦ.<дцх*г»овч«И эдуук 1Я&*ХХ****1ЯК*С*: ГЛ #Ж/ЛЛ«**ГЛ1М|В.% #^^ *&■**{% • X «fe^HM JJHHHjVJU- *> V Не следует открывать файл phpinfo.php в браузере при помощи команды «Файл \ Открыть», так как в этому случае скрипт не будет выполнен, а вместо него будет отображено его содержимое в виде текстового файла. Для запуска скрипта следует использовать корректный URL в адресной строке браузера. ЛЮ&ЛЯГГ-Г S4 ММде*7*аЖ(* » ttrt-CnOOw w* м-*ь TTfpww;; .4 Если все настроено и выполнено корректно, на экране будут отображено множество таблиц с настройками РНР, как показано на рис. 1.3. Если используется хостинг, то эта страница окажет существенную помощь в выяснении конкретных настроек РНР у данного провайдера.
18 Q!253 ^ ■ ?.ве,а!£|1ие в ^P Файл Правка Вид Избранное Сервис Справка ;jpf ■■■.}■ ••.'i,¥ Й 'Si f i ' 'j-,n°"c.K, ^Избранное "Э> ;% [В Адрес: .EJ} http://localhost/php/oi/phpin1o,php V;; Q Порожу; Секта » Рис. 1.3. Результатзапускапервогоскрипта Возможныепроблемы При запуске первого скрипта может возникнуть множество проблем. Результатом выполнения скрипта может явиться сообщение об ошибке, пустая страница или еще что-либо непонятное, в любом случае проблема может быть решена. Прежде всего следует убедиться в том, что РНР запускается. В случае локальной установки все просто — следует перейти в каталог, где установлен РНР, и выполнить команду php -v. Если на экране отображается версия продукта, все в порядке. Если хостинг-провайдер предоставляет консольный доступ к web-серверу при помощи Telnet или SSH2, такую же проверку можно выполнить и удаленно. Следующей, и наиболее часто встречаемой проблемой, является некорректная интеграция РНР и web-сервера. В этом случае вместо результата отображается чистая страница, а при просмотре HTML-кода в браузере виден исходный PHP-код. Для устранения этой проблемы следует еще раз пройти по всей инструкции по установке РНР от начала до конца — возможно, какой-то важный шаг не был выполнен. Следует иметь в виду, что после некоторых настроек может потребоваться перезапуск системной службы или всего компьютера (такие вещи не всегда указывают в документации). Наконец, следует убедиться в том, что файл размещен именно в том каталоге, который предназначен для хранения HTML-документов web-сервера. Некоторые хостинг-провайдеры используют нестандартное расширение для PHP-скриптов, например, .php5.
PHP И HTML 19 Замечание <ф р В операционных системах UNIX не требуется использование специальных режимов / файлов для PHP-скриптов. Их не следует помечать как исполняемые файлы, для них достаточно использовать режим 644 (не 755). При использовании Microsoft Internet Information Server (IIS) следует убедиться в наличии в конфигурационном файле php.ini строки «cgi . forceredirect = 0». Если такая строка отсутствует, следует добавить ее в файл. Наконец, имеет смысл обратиться к соответствующему разделу документации, в котором описаны возможные проблемы и методы их решения. Можно также обратиться к PHP FAQ (Frequently Asked Questions — частые вопросы и ответы) по адресу www.php.net/faq.php, раздел, посвященный установке, находится по адресу www.php.net/manual/faq.installation. Если ничего не помогает, можно попробовать задать вопрос экспертам в новостных группах alt .php или comp . lang . php. PHP и HTML PHP-файлы обычно представляют собой смесь HTML и РНР. Это не создает проблем, так как РНР-код всегда заключается внутри тегов <?php ... ?>, что позволяет серверу легко идентифицировать его. При использовании обычного HTML-кода все достаточно просто — web-сервер посылает текст страницы браузеру, который интерпретирует HTML-теги и отображает результат на экране. С РНР всё становится немного сложнее. РНР-код выполняется при помощи РНР, и если этот код формирует какой-либо текст для отображения, он вставляется на то место, где размещался РНР-код. В любом случае РНР-код удаляется перед отправкой готовой странице клиентскому браузеру. Пример 1.1 демонстрирует эту технологию в действии. Текст примера содержит несколько HTML-тегов, например, тег HI, который предназначен для формирования заголовка. Пример 1.1. Совместное использование РНР и HTML, phphtml.php <HTML> <HEAD> <TITLE> Использование HTML и РНР в одном файле </TITLE> </HEAD> <BODY> <Hl> Использование HTML и РНР в одном файле </Н1> <?php
20 Глава 1. Введение в РНР phpinfо (); </3 0DY> </HTML> :-—-.-.-^-г^сч- После тега <Н1> расположен PHP-код, который выполняется, а его результат — сформированная таблица с параметрами настройки РНР — размещается после заголовка. Результат выполнения примера представлен на 1.4. '• Использование HTML и РНР в одном файле Использование HTML н РНР в одном файле - Microsoft Internet Explorer с£пйп Прави э .Вид JjlSpaHHi1^ CepEm: ипрэнь:и ч* ■'"''• - Г '• ПотК- " " '■'* И"рзннпе £2l ' ■/■ f^t ГГЮЛ?! 4ii http://localbo*r:/fhppiliphpht-ml, php ■ Д]_ Переход System Build Date Configure Command Server API Virtual Directory Support Configuration File (php.ini) Path PHP API PHP Extension Windows NT HOME 5 .1 build 2600 Aug 15 2006 2350:22 escript/nologo cqnflgurejs "-enable-snapshot-build" "-■ wtth-gd=shared" Apactie 2,0 Handler enabled .;' CVWINXP 20041225 20050922 ■Ч"-'->,:-.;>;- ■'"' Рис. 1.4. Совместное использование РНР и HTML Для того, чтобы PHP-страница выглядела более строго, можно добавить один из логотипов, доступных для закачки по адресу www. php. net/down- load-logos, php. После загрузки логотипа (например, РНР.GIF) его можно использовать в коде при помощи тега <IMG>: <HTML> <HEAD> <TITLE> Использование HTML и РНР в одном файле <7TITLE> </HEAD> <BODY> <H1> Использование HTML и РНР в одном файле
Отображение текста 21 </Н1> <?php phpinfо () ; ?> <IMG SRC= " PHP. GIFn> </BODY> </HTML> Результат выполнения этого кода показан на рис. 1.5. файл Правка £ид ^эбражое Сервис Справка 0~;;:1 О iilii г^:>-пои« fins»*** 0 .£ Апрес;, i"sj http:MocaJhost/php/01/phphtml.php ■vj. j£j Переход „ENVT-vrindtrn .ENVrAPjSWENT.Pip'l C:\WINXP 1156 PHP License ;This program lsfree'software4;yducahfedtsttb of fte£>HP License as published by frie PHP Group and included ifrthe distribution in Щ(Щ LICENSE 0:0W:-- this program is dfstributed in trie hope that it will be useful, but WITHOUT ANY WARRAMiYpwithout even the implied warranty of MERCHANTABILITY;dr: FITNESS FOR A P. ARTJCULAR PURPOSE. ....,: Ui ^-:ЩШЩ*>; IfyoudidAotreceiye^copy, of the PHP license, behave:an^qu.^iprisabbutPHP licensing, please cbntact'licenseQphp.net. ■ •' : ■■'' ;t;!'?'%'^y^;V- Рис. 1.5. Добавление логотипа PHP Отображение текста Оператор echo, который предназначен для отображения произвольного текста на web-странице, является, пожалуй, самым гибким и наиболее употребительным оператором РНР. Простейшее его использование выглядит следующим образом: после ключевого слова echo следует поместить строку в кавычках, например: <HTML> <HEAD> <TITLE> Использование оператора echo </ТТТЬЕ> </HEAD>
22 Глава 1. Введение в PHP <BODY> <Н1> Отображение текста </Н1> <?php echo "Привет от РНР! PHP-код может располагаться в произвольном месте и многократно включаться в HTML-страницу, что видно из примера 1.2. Пример 1.2. Использование оператора echo, phpecho.php ■ '.>..*» 2-ry\t.+iiti*z:±i*m .ши. 1Ж*л*.<ли>ь*М'ЖЛ<кч*<м&шжш**гшжш ыжлли.1Лшшшлшт}.1^шф>*а<ш0т*>1Л***>^ штяттл-ЛА&НЛлтт&ШМмЛ'ЦЛитю i&W**mv*x*cx**A- <HTML> <HEAD> <TITLE> Использование оператора echo </TITLE> </HEAD> <BODY> <H1> Отображение текста </Н1> <?php echo "Привет от РНР!"; ?> <Н1> Отображение дополнительного текста </Н1> <?php echo "Снова привет от РНР!"; ?> <IMG SRC="PHP.GIF"> </BODY> </HTML> Рис. 1.6 показывает результат выполнения этого примера. Текст может быть заключен как в простые кавычки (апострофы), так и в двойные кавычки. Для отображения чисел кавычки не являются необходимыми, например: echo 111555; Так как любой вывод оператора echo (за исключением запуска РНР в командной строке) передаются браузеру, с его помощью можно также формировать и HTML-теги, например, ниже используется тег <BR> для перехода на новую строку: echo "Hello<BR>from<BR>PHP.";
Возможности отображения текста 23 файл [Травка Г^ид убранное Сервис ^правка ■..■ -,: lf ■v '' i "' ■ ' ST. ' .г ' Поиск "^':' Избранное > Л " ^-'^ |.^'f J -*-йй.": ;.'£] http: //locaihost/php/01 /phpecho.php ** ■ be' 3 Переход Отображение текста Привет от РНР! Отображение дополнительного текста Снова привет от РНР! Рис. 1.6. Отображение текста при помощи оператора echo Возможности отображения текста Между отображением текста в командной строке и в окне браузера имеются отличия. В браузере для форматирования текста используются HTML-теги, например, <BR> или <Р>. Если используется командная строка, то для форматирования применяются специальные символы, для использования которых строку следует заключать в двойные кавычки. Они перечислены ниже: \п Перевод строки (LF), код символа ASCII — 10 (ОхОА). \г Возврат каретки (CR), код символа ASCII — 13 (OxOD). \t Табуляция (НТ), код символа ASCII 9 @x09). \\ Обратный слеш. \$ Знак доллара. \" Двойная кавычка. \0 . . . \77 7 Символ, код которого задан восьмеричным числом. \хО . . . \xFF Символ, код которого задан шестнадцатеричным числом.
24 Глава 1. Введение" PHP Например, оператор echo "Line l\nLine 2" при выполнении в командной строке выведет "Line 1" на одной строке и "Line 2" — на другой. В браузере символ «\п» будет рассматриваться точно так же, как и пробел. Для достижения того же самого результата при формировании HTML-страницы следует использовать оператор echo "Line KBR>Line 2". Замечание •Л!Л^Ю "•**/'. Л-v -ф » При отображении тексте, сформированного при помощи скрипта, в браузере следу- / ет иметь ввиду, что его следует форматировать с использованием HTML-тегов. Использование простых переводов строки не приведет кжелаемому эффекту, так как браузер не отличает переводы строки отпростых пробелов, точнотакже каки в простом НТМ/.-документе. Только использование корректных ИГЛ 11.-тегов (например, <БЯ>^позволитдобитьсяжелаемогорезультата. я « к>а к*. ь ■ -:■** c*s& жг.'. a itj<xj r» - -VjV4.v. При необходимости длинная строковая константа может быть размещена на нескольких строках в тексте скрипта, и при выводе текста в командной строке переводы строк будут сохранены. При формировании аналогичного текста для браузера переводы строк будут игнорироваться: <?php echo "Этот текст занимает несколько строк."; ?> Отдельные строки могут разделяться запятыми, например: echo "Привет,", "это", " Р Н Р . " ; Все эти строки будут отображены слитно, без разрывов: Привет,этоРНР. Если требуется отделить строки друг от друга пробелами, их следует включить внутри кавычек: echo "Привет, ", "это ", "Р Н Р . "; В результате будет выведено: Привет, это РНР. Строки также могут объединяться при помощи оператора конкатенации («.»). В результате образуется выражение, которое вычисляется и передается оператору echo как единственный аргумент, например: echo "Привет, "."это "."РНР."; Для отображения кавычки, которая обычно используется для завершения строки, следует разместить перед ней обратный слеш, например: echo "Она сказала: \ "Я люблю мороженое . \ "" ; Вместо оператора echo можно использовать функцию print, которая используется точно так же. Единственная разница между echo и print состоит в том, что print является функцией и возвращает значение (см. гл. 4). Значение, возвращаемое функцией print, всегда равно 1. С точки зрения практической применимости различий между echo и print нет.
Синтаксис heredoc 25 Синтаксис heredoc Для отображения большого объема текста можно использовать т.н. синтаксис heredoc. Он начинается с символов <<<, после которых следует произвольный идентификатор. Далее располагается текст, в конце которого начиная с первого символа строки размещается тот же самый идентификатор. Использование данной возможности демонстрирует пример 1.3. Пример 1.3. ИспользованиесинтаксисаМегес1ос, phphere.php. *,mum>£HJ*jt**.\Mii:*: :•*■*:•* <HTML> <HEAD> <TITLE> Использование синтаксиса heredoc </ТТТЬЕ> </HEAD> <BODY> <Hl> Использование синтаксиса heredoc </Н1> <?php echo <«END ~ Этот пример демонстрирует использование синтаксиса "heredoc" для отображения текста большого объема до тех пор, пока не будет найден маркер окончания текста. END; ?> </BODY> </HTML> На рис .1.7 приведен результат выполнения данного примера . Запуск РНР в командной строке Помимо того, что РНР интегрируется с web-сервером так, что web-сервер становится способным запускать скрипты, РНР может быть использован как отдельное консольное приложение в командной строке операционной системы. Этот способ запуска может оказаться полезным для тестирования скриптов перед загрузкой их на сервер.
26 Глава 1. Введение в РНР й^)епол! Использование синтаксиса heredoc Этот пример демонстрирует использование синтаксиса "heredoc" для отображения текста большого объема до тех пор. пока не будет найден маркер окончания текста. 1еполкювание синтаксиса heredoc -Microsoft Internet Explorer файл Правка Вод Избранное Сервис Справка .-.- *1 Т*3 ГН у-""" Щвкв Jt*., чг С 1 •'•дот.. ■jgjhttp://localhost/php/01/phphere.php Г-№№\ J Переход С'-) Рис. 1.7. Отображение текста, заданного синтаксисом heredoc РНР является интерпретируемым языком. Это означает, что скрипт читается последовательно, оператор за оператором, и каждый оператор преобразуется в ту форму, в которой компьютер может его выполнить, и сразу же исполняется. В РНР программа, которая запускается в командной строке и выполняет интерпретацию скриптов, называется php. Программа, которая предназначена для вызова из web-сервера, называется php-cgi. РНР может быть запущен в командной строке операционной системы путем простого ввода команды php. При этом для того, чтобы операционная система нашла этот файл, следует либо добавить путь к нему в список путей, по которому осуществляется поиск исполняемых файлов (в Windows это переменная среды операционной системы PATH), либо указать полный путь к файлу. Например, пусть имеется следующий скрипт echo . php: <?php echo ?> "Доброе утро!"; Для исполнения этого скрипта необходимо ввести следующую команду (считаем, что путь к РНР добавлен в список путей для поиска, а сам файл echo, php размещен в текущем каталоге). Знаком % обозначено приглашение операционной системы. %php echo.php
Запуск РНР в командной строке 27 Если всё в порядке, на экран будет выведена соответствующая строчка: Доброе утро! Если РНР не найден, то следует ввести полный путь к нему. В операционных системах Unix или Linux команда может выглядеть следующим образом: S/usr/local/bin/php echo.php При использовании Windows команда может иметь следующий вид: С:\>С:\php\php echo.php Интерпретатор РНР имеет много разнообразных опций, которые можно задать в его командной строке. При запуске команды php -h выводится полный список этих опций1: %php -h Usage: php[options][-f]<file>[ — ] [args... ] php [options]-r <code> [—] [args...] php[options][-B <begin code>]-R <code> [-E <end_code>] [ — ][args...] php[options][-B <begin code>]-F <file> [-E <end_code>] [ — ][args...] php[options]--[args. . . ] Интерактивный запуск Задать расположение конфигурационного файла php.ini Не использовать конфигурационный файл php.ini Описание константы Формирование дополнительной информации для отладчика Задание файла скрипта Вывод справки по опциям Вывод информации о РНР Выполнение только синтаксического анализа файла Вывести список подключенных модулей Выполнение PHP-кода без тегов <?...?> Выполнение заданного кода перед обработкой скрипта Выголнение заданного кода для каждой строки исходного файла Выголнение заданного скрипта для каждой строки исходного файла Выполнение заданного кода после обработки скрипта Скрыть переданные аргументы от внешних средств Вывести исходный текст с выделением синтаксиса цветом Отображение версии РНР Вывод исходного текста без комментариев и лишних пробелов Загрузить файл расширения Zend Например, для вывода справочной информации о РНР (текстовый аналог того, что формирует функция phpinfo) используется опция -i. Как уже было сказано выше, для отображения версии РНР используется опция -v: %php -v РНР 5.1.5 (cli) (built: Aug 15 2006 23:54:56) Copyright (с) 1997-2006 The PHP Group Zend Engine v2 .1 . 0 , Copyright (c) 1998-2006 Zend Technologies -a с -n -d -e -f ■h -i -1 -Ш -r В R <path> I <file> foo[ = bar] <file> <code> <begin code> <code> -F <file> -E H -s V -w -z <end code> <file> Здесь приведен перевод описаний опций. При настоящем запуске РНР описание опций будет отображено по-английски. — Прим. ред.
28 Глава 1. Введение в РНР В операционных системах Linux и Unix PHP-скрипт может быть запущен просто по имени, набранному в командной строке, если в первой строке скрипта присутствует команда запуска РНР (с префиксом #!), и файл помечен как исполняемый: #! /usr/bin/php <?php echo "Доброе утро!" ; ?> Комментарии в скриптах Содержание PHP-скрипта представляет собой код на РНР или на HTML, который предназначен для обработки компьютером. Но есть также разделы, которые предназначены только для человека — комментарии. Комментарии предназначены для описания скрипта. Они весьма важны, так как если разработка продолжается длительное время или ведется несколькими людьми, то невозможно запомнить всю структуру программы, не разрабатывая хотя бы минимальную документацию, которая обычно содержится в комментариях. В РНР существует три типа комментариев. Первый тип позволяет располагать комментарии в нескольких строках, начиная их символами / * и заканчивая символами */, например: <?php /*Скрипт начинается с вывода приветственного сообщения для пользователя */ echo "Доброе утро! " ; ?> Для повышения выразительности можно заключить в /*...*/ каждую строку комментария, например: <?php /*Скрипт начинается с вывода */ /* приветственного сообщения для пользователя */ echo "Доброе утро!" ; ?> Следует иметь ввиду, что вложенные комментарии недопустимы. Следующий код является ошибочным: <?php /* Скрипт начинается с вывода /* приветственного сообщения */ для пользователя */ echo "Доброе утро!" ; ?> Ошибка заключается в том, что после начала комментария РНР ищет последовательность символов * /, закрывающую комментарий, не обращая внимание на символы / *, даже если они встретятся. Остальные два типа комментариев являются однострочными. Они начинаются с символов / / или # и продолжаются до конца строки:
Переменные 29 <?php // Скрипт начинается с вывода # приветственного сообщения для пользователя echo "Доброе утро!"; ?> Этот тип комментариев удобен тем, что их можно размещать справа от кода, например: <?php echo "Доброе утро!"; // Вывод первого сообщения echo "Добрый день!"; # Вывод второго сообщения ?> Однострочные комментарии более просты в использовании, так как нет необходимости отслеживать конец строки. Многострочные комментарии могут оказаться полезными там, где надо вставить значительный объем текста. Кроме того, распространенным приемом при отладке является заключение части кода в комментарий, чтобы предотвратить его выполнение. Комментариев обычно не бывает слишком много. Их рекомендуется писать как минимум на каждую функцию и на каждый законченный фрагмент кода. Чрезмерное их количество может затруднить чтение исходного кода, но отсутствие комментариев всегда обходится гораздо дороже. Переменные Текст, отображаемый до сих пор, был неизменным, например: <?php echo "Привет от РНР"; ?> Но РНР предназначен далеко не только и не столько для формирования статичного текста. Для того, чтобы обрабатывать различные данные, в языке предусмотрены переменные. Переменные являются контейнерами для данных. Каждая переменная содержит определенное значение. Например, пусть требуется отобразить текущую температуру. В случае использования постоянных значений — констант — соответствующий код мог бы выглядеть следующим образом: <?php echo "Температура сегодня: ", 36; ?> При использовании переменной этот же код примет следующий зид: <?php echo "Температура сегодня: ", Stemperature; ?> Переменные предназначены для хранения данных под определенным идентификатором — именем переменной. В РНР имена переменных начинаются со знака доллара («$»), далее следует буква или знак подчеркивания, после которого может следовать произвольное количество букв, цифр или знаков подчеркивания. После ее создания доступ к переменной возможен в произвольном месте скрипта. Самое время перейти к созданию переменных.
30 Глава 1. Введение в РНР Создание переменных Переменная создается тогда, когда ей присваивается какое-либо значение. Для присвоения значения переменной в РНР используется оператор присваивания., виды которого подробно описаны в гл. 2. Наиболее часто употребительная форма оператора присваивания состоит из знака равенства (« = »). Ниже приведены примеры операторов присваивания, которые создают соответствующие переменные: Sternperature = 24; $number_of_earths = 1; $pi = 3.1415926535; Sreassurance = "Без паники!"; Smessage = "Доброе утро!"; Обратите внимание, что одним переменным присвоены числа, а другим — строки. В других языках программирования переменные требуют явного описания с указанием их типа, но РНР — язык с нестрогой типизацией переменных, что упрощает программирование на нем. Замечание % f При сохранении значений различных типов компьютер использует различное внут- / реннеепредставлениеданных,поэтомувнекоторыхслучаяхследуетобращатьвни- маниенатиппеременныхивыражений.См.такжераздел«Типыданных»нижевэтой главе. Рассмотрим пример 1.4. В нем переменной $ apples сперва присваивается значение 1, которое потом отображается: $ apples = 1; echo "Число яблок: ", $apples, "<BR>"; После этого значение переменной увеличивается на три, и результат снова отображается на экране $apples = Sapples + 3 ; echo "Теперь число яблок: ", $apples, "<BR>"; Пример 1.4. Присваиваниезначенийпеременным, phpvariables.php. <HTML> <HEAD> <TITLE> Присваивание значений переменным </TITLE> </HEAD> <B0DY> <H1> Присваивание значений переменным <,'Н1>
Интерполяция переменных в строках 31 <?php echo "Количество яблок устанавливается в 1.<BR>"; $apples = 1; echo "Число яблок: ", $apples, "<BR>"; echo "Добавляется 3 яблока.<BR>"; $apples = $apples + 3; echo "Теперь число яблок: ", $apples, "<BR>"; ?> </BODY> </HTML> •-ч.'-^i 'rt ■№•■*'»«««««•«•».? Результат выполнения этого примера приведен на рис. 1 8. Как видно, присваивать значение переменным и изменять эти значения достаточно просто. файл Правка Вод Иэбражое Сервис Справка A.'crii;, ;.|з http://locaJhost/php/01/phpvarables.php v.; Q Переход Присваивание значений переменным Количество яблокустшав.тагеается в 1. Число яблок: 1 Добавляется 3 яблока. Теперь число яблок: 4 Рис. 1.8. Присваивание значений переменным Интерполяция переменныхвстроках Значение переменной может быть отображено, например, следующим способом: $apples = 1; echo "Число яблок: ", $apples, "<BR>";
32__. ^ ^ _.,.-_. _. «. Oiaeajj ^Вве^ениев^РНР^ Но существует способ сделать это проще. Если имя переменной заключено в двойные (не одинарные) кавычки, то переменная интерполируется. Это означает, что имя переменной заменяется ее значением, которое помещается на то же место в строке, где стояло имя переменной. Этот способ проиллюстрирован ниже: Sapples = 1; echo "Число яблок: $apples <BR>"; Пример 1.5 повторяет пример 1.4, но с использованием интерполяции переменных. Пример 1.5. Интерполяция переменных, phpinterpolation.php. <HTML> <HEAD> <TITLE> Интерполяция переменных </ТТТЬЕ> </HEAD> <BODY> <Н1> Интерполяция переменных </Н1> <?php echo "Количество яблок устанавливается в 1.<BR>"; $apples = 1; echo "Число яблок: Sapples <BR>"; echo "Добавляется 3 яблока.<BR>"; Sapples = $apples + 3; echo "Теперь число яблок: $apples <BR>"; ?> </BODY> </HTML> Рис. 1.9 содержит результат выполнения этого примера. Существует одна тонкость при использовании интерполяции переменных. Рассмотрим следующий пример: <?php $text = "news"; echo "Where's the Stextpaper <BR>"; ?> Ожидается, что имя переменной $text будет заменено на ее значение. Но этого не происходит, вместо этого выдается сообщение об ошибке: PHP Notice: Undefined variable: textpaper in C:\php\t.php on line 4
Интерполяция переменных в строках ^^ 33 3 Интерполяция переменных - Microsoft Internet Explorer файл Правка Вид Избранное Сервис Справка ф Адрес:.! «jfjhttp://locaJhc3st/phpfln/phpmterpolaoonphp "* Я Переход Ссылки Интерполяция переменных Количество яблок устанавливается в 1. Число яблок: 1 Добавляется 3 яблока. Теперь число яблок: 4 Рис. 1.9. Интерполяция переменных в строках Это происходит потому, что РНР анализирует наличие имени переменной согласно синтаксическим правилам и всегда выделяет максимально возможное по длине имя. Для того, чтобы указать, какую именно переменную следует интерполировать в этом случае, следует использовать фигурные скобки, как показано в примере 1.6. Пример 1.6. Интерполяцияпеременныхв сплошном тексте, phpinterpolation2.php. »ШМКЖЦ**1Х^Шг**&'9&!фЪХМУг*Л<ЛМ*****<*+>: ш\¥Т&ЖЛ\*-*>ЪП'*'--.**А:*1*тГЛ~**Хт <HTML> <HEAD> <TITLE> Интерполяцияпеременных </ТТТЬЕ> </HEAD> <BODY> <Н1> Интерполяцияпеременных </Н1> <?php $text = "news" ; echo "Where's the { $text}paper"; ?> </BODY> </HTML> ■«■puiM'ja^mt^ №«р*аИ*щ>гЯщт»;щцдаатдст1УГ*г«*: .*ft?«**H4»i»rt<льат-^м ЪУ*Щ*П Ъ Л rwim ^ыМ-ЬР-.-ЬМкЛг**; ;»j*Hift> 2 РНР в примерах
34 -..,-,.„,-., " "-„„„->> ^,,.,„ Глава 1, Введение в РНР Переменные, содержащие имена переменных РНР позволяет размещать в переменных не только простые значения, но и имена других переменных. Пусть, например, создана переменная $ apples: <?php Sapples = 4; ?> Далее создается переменная $ fruit name, которая содержит имя переменной Sapples: <?php $apples = 4 ; $fruitname = "apples"; ?> После этого к переменной Sapples можно обратиться как $$fruitname: <?php Sapples = 4; Sfruitname = "apples"; echo "Число яблок: ", $$fruitname; ?> Для корректной интерполяции подобных переменных в строковых константах, заключенных в двойные кавычки, следует также использовать фигурные скобки, например: " $ {Sfruitname}" . Пример 1.7 показывает использование этих приемов. Пример 1.7. Переменные, содержащие имена переменных, phpvariablevariables.php <HTML> <HEAD> <TITLE> Переменные, содержащие имена переменных </TITLE> </HEAD> <BODY> <Н1> Переменные, содержащие имена переменных </Н1> <?php Sapples = 4; Soranges = 3; Sfruitname = "oranges"; echo "Число апельсинов: ${$fruitname} <BR>" ; Sfruitname = "apples"; echo "Число яблок: ${Sfruitname} <BR>"; ?> </BODY> </HIMD
Константы 35 Результат выполнения примера отображен на рис. 1.10. файл Правка №д Избранное С§раис О ранка ОЧ1;-" V* ■ i I Sji^L'ft™ -Цу№ркв ф %Ь Щ -Uf ■?>:# 1 http//locaJhost/php/OI/phpvanablevanables-php :. «i Ej Пароход Ссыпки Переменные, содержащие имена переменных Число апельсинов: 3 Число яблок: 4 Рис. 1.10. Переменные, содержащие имена переменных Если бы фигурные скобки отсутствовали, результат выполнения примера 1.7 был бы следующим: Число апельсинов: $oranges Число яблок: $apples Переменные, содержащие имена переменных, могут выглядеть курьезом, но на самом деле они могут быть очень полезны, что показано далее в гл. 3. Константы Иногда не требуется менять один раз заданное значение переменной. Например, после присваивания переменной $pi значения числа п, имеет смысл предотвратить его случайное изменение в другом фрагменте скрипта. Для этого используются константы — их значения не могут быть изменены в процессе выполнения скрипта. Для описания константы используется функция define, которой передается имя константы и ее значение, например: define ("pi", 3.1415926535);
36 Глава 1. Введение в РНР Следует обратить внимание, что имя константы всегда заключается в кавычки, а значение только тогда, когда оно является строкой. Кроме того, при использовании константы перед ней не ставится знак доллара. Пример 1.8 показывает использование констант, а на рис. 1.11 отображен результат выполнения этого примера. Пример 1.8. Использование констант, phpconstants.php. <HTML> <HEAD> <TITLE> Использование констант </ТТТЬЕ> </HEAD> <BODY> <Н1> Использование констант </Н1> <?php define ("pi", 3.1415926535); echo "Константа pi содержит значение ?> </BODY> </HTML> Pi. "<BR>"; i' ->miiiy<- 4^yTM»uiMPWI i Использование констант Microsoft Internet Explorer файл Дранка Вид избранное Сервис Справка Адр'-:..; | |) http://localho3t/php/01/phpccxi3tant3.php uf !( Q Перехол Ссыпки Использование констант Константа pi содержит значение 3 1415926535 Рис. 1.11. Использование констант
Константы 37 Попытка изменения значения константы приведет к ошибке перед началом выполнения скрипта — он даже не будет запущен. Так как перед именем константы не ставится знак доллара, в качестве имени константы не следует использовать зарезервированные слова языка РНР. Список зарезервированных слов приведен в табл. 1.1. Таблица 1.1. Зарезервированные ключевые слова РНР CLASS_ FILE FUNCTION. ,INE break echo and array as default die do endif endswitch endwhile global if include . METHOD . print require eval lnclude_onc e require_once return case сfunction class const continue declare else elseif empty enddeclare endfor endforeach exception exit extends for foreach function isset list new old_function or php_user_filter static switch unset use while xor Существует несколько предопределенных констант, которые можно использовать при разработке скриптов. Ниже приведен их краткий перечень. LINE FILE FUNCTION CLASS METHOD PHP_VERSION PHP_OS DEFAULT INCLUDE PATH Номер текущей строки скрипта. Полное имя файла текущего скрипта. Имя текущей исполняемой функции (добавлено начиная с РНР 4.3.0). Имя текущего класса (добавлено начиная СРНР4.3.0). Имя текущего метода класса (добавлено начиная СРНР5.0.0). Версия РНР. Операционная система, под управлением которой работает РНР. Список путей, в которых РНР ищет подключаемые файлы.
38 Глава 1. Введение в РНР Типы данных РНР является языком с нестрогой типизацией — тип переменной определяется на основе ее значения. Тем не менее, следует иметь представление об типах данных, которые присутствуют в РНР. Всего их восемь, и все они перечислены ниже: • boolean. Логический тип, содержит значения TRUE или FALSE. • integer. Целое число. • float. Вещественное число. • string. Текст произвольной длины. • array. Массив. • object. Объект. • resource. Ресурс (например, файл). • NULL Значение NULL. Обычно заботиться о типах данных не следует — тип определятся автоматически при создании переменной. Например, создание переменной строкового типа выглядит следующим образом: Svariable = "Доброе утро!"; Создание переменной вещественного типа: Svariable = 1.2345; Создание переменной логического типа: Svariable = TRUE; В данном случае тип переменной определяется однозначно. Трудности начинаются при смешивании различных типов данных в одном выражении, например, при сложении целого числа и строки и т.п. Ниже приведено несколько примеров подобных выражений: <?php //Тип и значение переменной: Svariable = "О"; // строка "О" Svariable = Svariable + 2; // целое число 2 Svariable = Svariable +1.1; // $вещественное число 3.1 Svariable =2 + "8 apples"; // целое число 10 ?> Для предотвращения потенциальных проблем не следует смешивать различные типы данных. Но даже и в таком случае РНР выполняет автоматическое неявное преобразование типов. Если же требуется выполнить явное преобразование типа, то требуемый тип должен быть указан слева от имени переменной в круглых скобках. Ниже приведено несколько примеров явного преобразования типов: $int_variable = (integer) $variable; $float_variable = (float) $variable; $string_jyariable = (string) $variable; При преобразовании в логический тип boolean, следующие значения преобразуются в значение FALSE (все остальные значения, включая все ресурсы, преобразуются в TRUE):
Итоги __./__ ,. _ \ . « „ Ж • Логическое FALSE. • Целое число 0. • Вещественное число 0.0. • Пустая строка и строка ". • Массив с нулевым количеством элементов. • Объект, не имеющий свойств. • Специальный тип NULL. При преобразовании в целое число значения других типов преобразуются следующим образом: • Логическое FALSE преобразуется в целое число 0, логическое TRUE преобразуется в целое число 1. • Вещественные числа округляются в меньшую сторону. При преобразовании в вещественное число сперва осуществляется преобразование в целочисленное значение. Возможно также преобразование строковых значений в численные типы данных, но при этом имеется ряд особенностей (см. гл.З) В следующей главе содержится описание основных операторов и управляющих структур языка РНР, при помощи которых можно создавать полноценные программы. Итоги РНР предназначен для создания динамических, интерактивных web-страниц. Ниже перечислены краткие итоги главы: • Порядок установки РНР сильно зависит от его версии и операционной системы. Он подробно изложен в документации, которая сопровождает установочный пакет или архив РНР. • Для проверки функционирования РНР используется команда php -v, которая отображает версию РНР. Для разработки PHP-скриптов следует выбрать среду разработки. Можно использовать простой текстовый редактор или интегрированную среду разработки (IDE). Кроме того, следует выбрать способ, при помощи которого скрипты будут загружаться на web-сервер. • Код РНР заключается между тегами <?php ... ?>. За пределами этих тегов можно использовать произвольные возможности HTML. • Оператор echo предназначен для отображения текста. Синтаксис heredoc позволяет включать в код большие блоки текста в естественном виде. • В РНР существуют три вида комментариев: /*...*/, // и #. • Имя переменной предваряется знаком доллара («$»), начинается с буквы или знака подчеркивания, после которого может следовать произвольное количество букв, цифр или знаков подчеркивания.
Глава 2 Операторы Предыдущая глава посвящена введению в язык РНР, а в данной главе описываются основные операторы языка. Во-первых, к ним относятся операторы обработки данных—арифметические, строковые и битовые. Например, при работе с численными данными широко используются операторы сложения («+»), вычитания («-»), умножения («*»)ит.д. Все операторы перечислены в табл. 2.1. Во-вторых, ниже описываются также основные управляющие конструкции языка — условные операторы и операторы циклов. При помощи условного оператора можно выполнять те или иные фрагменты кода в зависимости от значения некоторого условия. Наличие подобных средств в языке позволяют формировать динамические HTML-страницы, для чего прежде всего и предназначен язык РНР. При помощи циклов становится возможным эффективно обрабатывать большие объемы данных. Эта тема раскрывается далее в гл. 3, где описывается работа со строками и массивами. Математические операторы Численные данные обрабатываются при помощи следующих фундаментальных операторов языка РНР: Сумма двух чисел. Разность двух чисел. * Произведение двух чисел. / Частное от деления двух чисел. % Остаток отделения одного числа на другое (частное по модулю). Пример 2.1 демонстрирует использование математических операторов языка.
42 Глава 2. Операторы Пример 2.1. Использование математических операторов, phpmath.php ш лап • aii амгщ; г if ш <HTML> <HEAD> <TITLE> Математические операторы </TITLE> </HEAD> <BODY> <H1> Математические операторы </Н1> <?php echo «5 + 2 = », echo « 5 - 2 = » , echo «5*2=», echo «5 / 2 = », echo «5 % 2 = », 5+2/ 5 - 2 , 5*2, 5 / 2 , D  A i '<BR>4 <BR>" <BR>" <BR>" <BR>" ?> </B0DY> </HTMI> Результат выполнения данного примера представлен на рис. 2.1. файл Правка £ид Избранное Сервис Справка @ ни.™ - @- | Q"lp по«к ff Щаю 0 \ ^ £g§ Адрес; |Щ http://tocaJhost/php/02;phpmatti.php JLS2 Ладаод : Ссы/жи. Математические операторы 5 + 2 = 7 5-2 = 3 5 * 2= 10 5/2 = 2.5 5 % 2= 1 Рис. 2.1. Результат выполнения математических операторов
Математические функции 43 Математические функции Наряду с математическими операторами, в РНР предусмотрено большое количество математических функций. Ниже приведен перечень наиболее часто употребительных функций. • abs. Абсолютное значение (модуль) числа. • acos. Арккосинус. • acosh. Гиперболический арккосинус. • as in. Арксинус. • asinh. Гиперболический арксинус. • atan2. Арктангенс частного двух переменных. • atan. Арктангенс. • atanh. Гиперболический арктангенс. • baseconvert. Преобразование чисел в строковом представлении из одной системы счисления в другую. • bindec. Преобразование строки, представляющей двоичное число, в целочисленное значение. • ceil. Округление числа в большую сторону. • cos. Косинус. • cosh. Гиперболический косинус. • decbin. Преобразование числа в двоичное представление в виде строки. • dechex. Преобразование числа в шестнадцатеричное представление в виде строки. • decoct. Преобразование числа в восмеричное представление в виде строки. • deg2 rad. Преобразование градусов в радианы. • ехр. Вычисление экспоненты заданного числа. • floor. Округление числа в меньшую сторону. • fmod. Вещественный остаток от деления двух чисел. • getrandmax. Максимальное значение, которое можно получить функцией rand(). • hexdec. Преобразование строки, представляющей шестнадцатеричное число, в целочисленное значение. • hypot. Вычисление гипотенузы по двум катетам. • is_finite. Проверка, является ли значение конечным вещественным числом. • is in finite. Проверка, является ли значение бесконечностью (может возникнуть, например, в результате вычисления значения логарифма нуля). • is nan. Проверка, является ли значение специальным значением NAN (not-a-number, результат выполнения некорректной математической операции). • lcgvalue. Генератор псевдослучайных чисел. • loglO. Десятичный логарифм.
44 Глава 3:,,Операторы • log. Натуральный логарифм. • max. Максимум заданных чисел. • min. Минимум заданных чисел. • mtgetrandmax. Максимальное значение, которое можно получить функцией mtr and (). • mtrand. Генератор псевдослучайных чисел по алгоритму витка Мерсен- на1. • mtsrand. Инициализация генератора псевдослучайных чисел по алгоритму витка Мерсенна. • octdec. Преобразование строки, представляющей восьмеричное число, в целочисленное значение. • pi. Значение числа и. • pow. Возведение в степень. • rad2deg. Преобразования радианов в градусы. • rand. Генератор псевдослучайных чисел. • round. Округление числа. • sin. Синус. • sinh. Гиперболический синус. • sqrt. Квадратный корень. • srand. Инициализация генератора псевдослучайных чисел. • tan. Тангенс. • tanh. Гиперболический тангенс. Ниже приведен пример извлечения квадратного корня: <?рпр echo "sqrt D9) = ", sqrt D9); ?> В результате выполнения данного фрагмента кода будет выведена следующая строка: sqrt D9) = 7 Операторы присваивания Основным оператором присваивания является знак равенства («=»), который служит для присвоения значения выражения определенной переменной: $oranges = 12; В одной строке можно присвоить одно и то же значение сразу нескольким переменным. Например, данный пример демонстрирует присвоение значения 1 сразу трем переменным: Виток Мерсенна (Mersenne twister) — генератор псевдослучайных чисел, с периодом 21И"-1, разработанный в 1997 японскими учеными Макото Мацумото и Такуджи Нишимура. — Прим.ред.
<?php $a = $b = $c = 1; echo $a, ", ", $b, ", ", $c; ?> Результатом выполнения данного скрипта будет строка: 1,1,1 Наряду с основным оператором присваивания существуют комбинированные операторы для всех бинарных арифметических и строковых операторов. Они позволяют использовать значение переменной в выражении и сохранить результат в этой же самой переменной. Ниже приведен перечень этих операторов: + =_= *=/= ■= %=.= 1= -= <= > = Использование этих операторов делает код более компактным. Например, требуется прибавить 10 к значению переменной Svalue. Это можно сделать следующим образом: $value = $value + 10,- С использованием комбинированного оператора присваивания «+=» этот же код можно записать короче: $ value += 10; Ниже приведен пример использования комбинированных операторов присваивания для конкатенации и деления: <?php Stext = 'Жизнь "; Stotal = 150; echo Stext .= "прекрасна. "; echo "Результат = ", Stotal /= 3; ?> Результатом выполнения этого фрагмента кода будет строка: Жизнь прекрасна. Результат = 50. Увеличение и уменьшение Достаточно часто требуется увеличить или уменьшить значение некоторой переменной на единицу. Особенно часто это используется в циклах, что будет показано ниже в этой главе. В РНР для этого предусмотрены специальные операторы. Для увеличения значения на единицу (инкремент) предназначен оператор «++», а для уменьшения (декремент) — оператор «—». Например, если переменная Sbananas содержит значение 0, то после инкремента ее при помощи конструкции вида Sbanana s++ ее значение станет равным 1. Если переменная $ apples содержит значение 11, то после выполнения кода Sapples — ее значение станет равным 10. Операторы инкремента и декремента могут быть использованы как до (префиксная запись), так и после (постфиксная запись) имени переменной. Если используется префиксная запись, например, ++$bananas, то значение перемен-
46. Гпава2.^ Операторы ной увеличивается, и это же значение используется как результат вычисления данного выражения. При использовании постфиксной записи, например $bananas+ + , результатом вычисления выражения становится значение переменной до ее увеличения. Разница между этими двумя вариантами представлена ниже: ++$value Пре-инкремент $value++ Пост-инкремент — $value Пре-декремент $value - - Пост-декремент Все эти четыре способа показаны в примере 2.2. Увеличивает значение $value на единицу. Возвращает текущее значение $value, по- еле чего увеличивает значение $value на единицу. Уменьшает значение $value на единицу. Возвращает текущее значение $value, по- еле чего уменьшает значение $value на единицу. Пример 2.2. Инкремент и декремент, phpincrementing.php <HTML> <HEAD> <Т1ТЬЕ>Инкремент и декремент</Т1ТЬЕ> </HEAD> <BODY> <Н1>Инкремент и декремент</Н1> <?php $d = 1; $а++, "<BR>" ++$b, "<BR>" $c—, "<BR>" $a = $b = $c = echo "\$a++ = " echo "++\$b =" echo "\$c-- = " echo "--\$d =" ?> </BODY> </HTML> -$d, "<BR>" Результат выполнения данного примера показан на рис. 2.2. Как видно, имеются различия между префиксным и постфиксным применением операторов инкремента и декремента. Если значение, возвращаемое операторами, не используется (например, при увеличении значения счетчика цикла, как это показано ниже), то не имеет значения, какую форму операторов использовать — префиксную или постфиксную.
Приоритет операторов 47 файл Правка Эйд Избранное Сервис Справка ОНяд ' © ■ Й Э €\U iP 5 /ТЬбрэ+ноэ Ч2> ; ^> Щ Адрес;) $ ) http://tocalhcsVphp/0^phpincrementng.php Инкремент и декремент $а++ = 1 ++$Ь = 2 $с-=1 -Scl = 0 :* ^ИЛ1|р*,,?*'Со,,*и * http ://all -ebooks. com Рис .2.2. Различные способы инкремента и декремента Приоритет операторов При использовании нескольких операторов совместно в одном выражении возникает вопрос — в каком порядке они будут выполнены? Например, пусть имеется следующий фрагмент кода: <?php echo 4+2 Его результат будет зависеть от того, какой из двух операторов выполнится первым — сложение или умножение. В данном случае результат будет равен 22, так как первым выполнится оператор умножения, потому что умножение имеет более высокий приоритет по сравнению со сложением. В табл. 2.1 приведены операторы по убыванию приоритета. Операторы с одним приоритетом выполняются по порядку слева направо.
48 Глава 2. Операторы Таблица 2.1. Операторы в порядке убывания приоритета Операторы new J ! ~ ++ - (int) (float) (string) (array) (object) @ * / % + - . < > & _L 8& 11 ? . = +="=*=/=.- 9fr- &- Г- л = <= >= print and xor or Для изменения порядка выполнения операторов используются скобки. Пример 2.3 демонстрирует использование скобок для получения различного порядка выполнения арифметических операторов, и как следствие, для получения различного результата. Пример2.3. Управлениепорядкомвыполненияоператоров, phpprecedence.php <HTML> <HEAD> <TITLE> Управление порядком выполнения операторов </ТТТЬЕ> </HEAD> <BODY>
Оператор исполнения 49 <Н1> Управление порядком выполнения операторе! </Н1> <?php echo +2*9= ",4+2*9, "<BR>"; echo "D + 2) * 9 = " , D + 2) * 9, "<BR>" ; echo + B*9) =",4+ B*9), "<BR>"; ?> </BODY> </HTML> На рис. 2.3 приведен результат вычислений выражения с различным порядком выполнения арифметических операторов. файл [Правка Цид Избранное Сервис Справка ©> Ш Ш&Р**™ фи*™» &i§ ч* Адрес; '/^jttp://loc3lbcsl:/php/02/phpprei:edence.php :i&\ gj Первод . Сыпей Управление порядком выполнения операторов 4 + 2 * 9 = 22 D + 2)* 9 = 54 4 + B * 9) = 22 Рис. 2.3. Различный порядок выполнения операторов Оператор исполнения В РНР предусмотрен интересный оператор, позволяющий выполнить в рамках скрипта любую команду операционной системы и использовать результат ее выполнения. Любая строка, заключенная в обратные апострофы («'*»), рассматривается как команда операционной системы. Ниже приведен пример скрипта,
50 Глава 2, Операторы который использует системную команду date для получения текущей даты и отображает ее. <?php Soutput = vdate\- echo Soutput; ?> Результат выполнения этого кода будет различным в зависимости от операционной системы. Например, под Unix результат может быть таким: Thu Aug 12 10:53:28 PDT 2006 В командной строке Windows результат будет выглядеть несколько по-другому: Текущая дата: Вс 01.10.2006 Введите новую дату (дд-мм-гг) : Если команде операционной системы требуется передать параметр, то его также следует заключить в обратные апострофы вместе с именем команды, например: <?php Soutput = Ndir c:\\winnt\* echo Soutput; ?> Результат выполнения данного кода представлен на рис. 2.4. файл Дравка Вид Избрание С§реис Справка 0< ' - © " S Ш !&.!/1-""' "Избранное ф\Ш : Щ" " :\""'[- ■'-..'■/" <." ■'.::■:-'■ P-afle'..'.!lUhtJp://localhost/php/02/phpexecution,php j SE J "WO* Оператор исполнения v.-:.! ■I*.. ! Оэд^;*: Том в устройстве С не имеет метки. Серийный номер тома: 3766-18F3 Содержимое папки c:\wirait 21.07.2005 22:18 .21.07.2005 22:18 ..21.07.2005 22:18 system32 21.07.2005 22:18 system 21.07.2005 22:18 repair21.07.2005 22:18 Help 21.07.2005 22:18 Config 21.07.2005 22:18 msagent 21.07.2005 22:18 'Cursors 21.07.2005 22:18 Media21.07.2005 22:18 Java 21.07.2005 22:18 1 %■'■ Рис. 2.4. Выполнение команды операционной системы
Строковые операторы ____ ______ 51 Строковые операторы В РНР существуют два строковых оператора. Первый — это оператор конкатенации («.»), который объединяет две строки в одну. Второй — это конкатенирующий оператор присваивания, который добавляет строковый результат вычисления выражения справа к заданной переменной. В пример включены оба этих оператора. Пример2.4. Строковые операторы, phpstringop.php <HTML> <HEAD> <TITLE> Строковые операторы </TITLE> </HEAD> <BODY> <Hl> Строковые операторы </Н1> <?php $a = "Жизнь "; echo "\$a = ", $a, "<BR>"; echo "\$b = \$a . \"прекрасна \"<BR>"; $b = $a . "прекрасна "; echo "Теперь \$b = ", $b, "<BR>"; echo "\$b .= \ "и удивительна.\""<BR>"; $b .= "и удивительна."; echo "Теперь \$b = ", $b, "<BR>"; ?> </BODY> </HTMI> Результат выполнения данного примера приведен на рис. 2.5. Но этими двумя операторами возможности РНР по обработке строк не ограничиваются. В гл. 3 приведено большое количество функций, предназначенных для самых разнообразных манипуляций со строками. Битовые операторы Наконец, в РНР имеется несколько операторов, предназначенных для работы с отдельными битами в целых числах. Битовые операции используются обычно в достаточно сложных программах, например, когда требуется хранить в одном целом числе большое количество разнообразных двоичных признаков. При первом чтении данный раздел главы можно пропустить.
Глава 2. Операторы файл [Травка Вид Избранное Сервис Отрэвка &й) """'"";' :>' "^ ' ^ ij9SJ S*" ©Поиск <\Л/Избранное ^Э i k^gi Адр?с: ) ' http://localhost/php/02/phpstrjngop.php -Si ■; Япюсац :У5н>и*в<-.;?$ Строковые операторы Sa = Жгвнь Sb = Sa . "щзекрасна " Теперь Sb = Жизнь прекрасна $Ъ .= "и удивительна." Теперь Sb = Жизнь прекрасна и удивительна. Рис. 2.5. Выполнение строковых операторов Замечание »:^С»У*ЧИЕ.№»<*УТ.Ч*>в«п| CI»H|4J щ щ Наряду с целыми числами, при помощи битовых операторов могут обрабатываться / и строки. В этом случае преобразование осуществляется над ASCII-кодами симво- Перечень битовых операторов приведен в табл.2.2. Таблица2.2. Битовые операторы Оператор Обозначение Описание Логическое «И» $а & $Ь Результатомявляю7-сябитъ/,ко7-орь/е установлены и в $а, и в $Ь. Логическое «ИЛИ» Исключающее «ИЛИ» Логическое"/-^» Сдвигвлево $а 1 $а - ~$а $а < $Ь $Ь $ь Результатомявляютсябиты,которыеустано лены в $а или в $Ь. Результатомявляютсябиты, которыеустанов лены только в $а, или только в $Ь. Результатом являются биты, которые не установлены в $а. Сдвиг битов $а на $Ь битов влево. Каждый сдвиг эквивалентен умножению на 2. Сдвиг вправо $а > $Ь Сдвиг битов $а на$Ь битов вправо. Каждый сдвиг эквивалентен делению на 2.
Условный оператор IF 53 Например, рассмотрим оператор логического «ИЛИ», «]». Результатом его применения к двум целым числам является также целое число. Оно состоит из бит, которые установлены хотя бы у одного из операндов оператора. Если $а = 1 (установлен 0-й бит числа), а $Ь = 2 (установлен 1-й бит числа), то $а [ %Ь = 3 (установлен и 0-й, и 1-й бит). Операторы двоичного сдвига эквивалентны умножению и делению на степени числа 2. Например, в результате сдвига 4 < 2 получится число 16 = 4*22, а в результате сдвига 8 > 2 получится число 2 = 8 / 22. Следует обратить внимание, что данные операторы манипулируют именно целыми числами, а не логическими значениями TRUE и FALSE. Условный оператор IF Как и во всех высокоуровневых языках программирования, в РНР имеется условный оператор if, синтаксис которого представлен ниже: if (expression) statement Здесь expression — логическое выражение, которое может быть истинным или ложным. Например, выражение 5 > 2 истинно, так как число 5 больше, чем число 2. Оператор statement выполняется, когда выражение expression истинно и не выполняется когда оно ложно. Оператор i f хорош тем, что решение может приниматься непосредственно во время выполнения скриптов на основе произвольных данных. Такими данными, например, могут быть текст, введенный пользователем на web-странице, значения, полученные из базы данных или от другого web-сайта. Ниже приведен пример, в котором значение переменной Stemperature сравнивается с числом 30: Stemperature = 25; if (Stemperature < 30) echo "Отличный денек"; В данном случае переменная Stemperature содержит значение 25, так что оператор echo будет выполнен, и на экране мы увидим строку: Отличный денек Иногда возникает необходимость, чтобы при выполнении определенного условия выполнялось бы сразу несколько операторов. Для этой цели в РНР предусмотрен составной оператор, который содержит произвольное количество простых операторов, заключенных в фигурные скобки. В примере, приведенном ниже, из трех отдельных простых операторов при помощи фигурных скобок образован один составной оператор: { echo "Ваше время истекло!<BR>"; echo "Пожалуйста, положите трубку."; Shangupnow = TRUE; } В примере 2.5 этот составной оператор используется внутри оператора if:
54 Глава 2. Операторы Пример2.5. Использование оператора if, phpif.php <HTML> <HEAD> <TITLE> Использование оператора if </TITLE> </HEAD> <BODY> <H1> Использование оператора if </Hl> <?php $minutes = 4; if ($minutes > 3) { echo "Ваше время истекло!<BR>"; echo "Пожалуйста, положите трубку."; $hang_up_now = TRUE; } ?> </BODY> </HTML> На рис. 2.6 представлен результат выполнения этого примера. файл Правка Вед убранное Сервис Справка Аяв«1 !й-Ы :ф:№са1 Ьо5фЬр]02" 11 р"_р]р Д ® Перетру-::.6^|Д»--; Использование оператора if Ваше время истекло! Пожалуйста, положите трубку. Рис. 2.6. Использование оператора if
Операторы сравнения 55 В условии оператора i f могут быть использованы также логические функции. Например, функции isint, isfloat, isarray и т.д., которые предназначены для определения типа переменной. При помощи этих функций и оператора if можно проверить тип переменной, прежде чем использовать ее, например: if (is int ($var"iable) ) $variable = $variable + 10; Оператор i f является одним из фундаментальных операторов и используется практически в любых скриптах. Другие примеры использования оператора if будут рассмотрены в следующем разделе. Операторы сравнения Операторы сравнения — множество логических операторов, предназначенных для совместного использования с оператором if. В предыдущем разделе использовался оператор «больше» (>) для проверки значения переменной $ minutes: $minutes = 4; If ($minutes > 3) { echo "Ваше время истекло!<BR>"; echo "Пожалуйста, положите трубку."; $hang up now = TRUE; } Все имеющиеся в РНР операторы сравнения приведены в табл.2.3. Таблица2.3. Операторысравнения Оператор == === ! = о 1== < > <= Операция Равенство Идентичность Неравенство Неравенство Неидентичность Меньше Больше Меньше или равно Пример $а $а $а $а $а $а $а $а == $Ь ===$Ь != $Ь о $Ь !== $Ь < $Ь > $Ь <=$Ь Результат TRUE, если $а равно $Ь. TRUE, если $а равно $Ь, и они одного и того же типа. TRUE, если$а неравно $Ь. TRUE, если $а неравно $Ь. TRUE, если $а неравно $Ь, или они не одного и того же типа. TRUE, если$а меньше $Ь. TRUE, если $а больше $Ь. TRUE, если$а меньше или равно $Ь. >= Больше или равно $а >= $Ь TRUE, если $а больше или равно $Ь.
56____^ Глава 2. Операторы Например, если требуется проверить, что значение переменной точно равно 25 градусов, следует использовать оператор равенства (==): Stemperature = 25; if (Stemperature == 25) echo "Неплохой день"; Замечание 7 Следует обратить внимание, что оператор сравнения записывается какдвазн ака равенства [==) в отличие отоператора присваивания [=].Еслиоператор if всочетании с оператором сравнения не дает ожидаемых результатов, следует удостовериться втом, что используется именно оператор сравнения, а неоператор присваивания. Ниже приведен пример использования оператора неравенства (! =), который возвращает TRUE, если два значения не равны. Stemperature = 2 5; if (Stemperature != 25) echo "Температура не равна 2 5 градусов"; Особое внимание следует уделить сравнению вещественных чисел. Вещественные числа хранятся в двоичном, а не десятичном представлении. Это означает, что число, которое выглядит как 8, может в действительности храниться как 7,99999999, и в результате проверка на точное равенство даст неверный результат. Поэтому не имеет смысла выполнять проверку вещественных чисел на равенство или неравенство. Для сравнения вещественных чисел рекомендуется ограничиться определенной точностью. Например, если требуется проверить равенство определенной переменной числу п (в РНР предусмотрена отдельная функция pi, возвращающая значение числа и с высокой точностью, см. выше разд. «Математические функции»), для этой цели можно применить следующий оператор: $value = 3.1415926535; if (abs ($value - pi ()) < 0.0000001) { echo ("Это число 'пи'"); } В примере использована математическая функция abs, возвращающая модуль своего аргумента (также см. выше разд. «Математические функции»). Логические операторы Предположим, требуется проверить, что значение температуры лежит в пределах от 25 до 30 градусов. Этого можно достичь, например, при помощи вложенных операторов i f:
JQnepqTppJ£L£E ,»»«.>.«.««-_J5Z $temperature = 27; if ($temperature >= 25) { if ($temperature <= 30) { echo ("Комфортная температура" ) ; } } Но существует и более простой способ. Для этого можно использовать логический оператор «И» (&&), который объединит два отдельных условия в одно, как это приведено в примере ниже: $temperature = 27; if (($temperature >= 25) && ($temperature <= 30)) { echo ("Комфортная температура"); } Это составное условие выполняется тогда и только тогда, когда одновременно истинны оба входящих в него выражения. Полный список логических операторов РНР приведен в табл. 2.4 . Таблица 2.4. Логические операторы Оператор and && or 11 xor _1 Операция Логическое «И» Логическое «И» Логическое «ИЛИ» Логическое «ИЛИ» Логическое «Исключающее ИЛИ» Логическое«/-/Е» Пример $а and $b $а && $Ь $а or $b $а 11 $b $а xor $b ! $а Результат TRUE, если истинно $а и $Ь. TRUE, если истинно $а и $Ь. TRUE, еслиистинно$аили $Ь. TRUE, если истинно $ а и л и $ Ь . TRUE, если истинно $а или $Ь, но не оба одновременно. TRUE, если $а ложно. Замечание р Зачем нужны два оператора логического «И» и два оператора логического «ИЛИ»? / Дело в том, что операторы && и 11 имеютболее высокий приоритет, нежели операторы and и or, см. табл. 2.1. Оператор ELSE Зачастую возникает необходимость в случае истинности определенного условия выполнить какое-либо одно действие, а в случае ложности — другое. Для этого используется оператор (или точнее сказать, конструкция) else. Синтаксис оператора if с ключевым словом else приведен ниже: гп
58 if (ехргеззЗол) statementl else statement2 Оператор st ate me. n/2, следующий после ключевого слова е 1 s e, выполняется в том случае, если условие expression не выполняется. Пример использования ключевого слова else приведен ниже: $temperature = 3 5; if (($temperature >= 25) && ($temperature <= 30)) { echo ("Температура комфортна"); } else { echo ("Температура некомфортна"); } В данном примере условие оператора if не выполнено, и в результате выполнения скрипта на экран будет выведена строка: Температура некомфортна В следующем примере проверяется оценка ученика: $score = 4; if ($score >= 3) { echo "Экзамен сдан"; } else { echo "Экзамен не сдан"; } Условие оператора i f выполнено, и в результате будет выведена строка: Экзамен сдан OnepaTopELSBF Оператор i f имеет еще одно расширение, которое используется для последовательной проверки нескольких условий — ключевое слово else if. Синтаксис оператора if с ключевым словом е 1 s e i f приведен ниже: if (expressionl) statemen tl elseif (expression 2) statement2 Если условие expressionl истинно, то выполняется оператор statementl. В противном случае проверяется условие expression!, и если оно истинно, выполняется оператор statement2. Глава 2. Операторы
Тернарный оператор л„л To"""_m mm».mm-m V"_"§ Например, требуется вывести на экран определенную строку в зависимости от экзаменационной оценки. Этого можно достичь, например, при помощи следующего кода: $score = 4; if ($score == 5) echo "Отлично"; else { if ($score == 4) echo "Хорошо"; else { if ($score == 3) echo "Удовлетворительно"; else echo "Неудовлетворительно"; } } С использованием ключевого слова else if этот же пример можно записать в более компактной форме: $score = 4; if ($score == 5) echo "Отлично"; elseif ($score == 4) echo "Хорошо"; elseif ($score == 3) echo "Удовлетворительно"; else echo "Неудовлетворительно"; В результате выполнения этого примера на экран будет выведена строка: Хорошо Тернарный оператор В языке РНР предусмотрена конструкция, которая работает почти так же, как и оператор if — тернарный оператор. В его синтаксисе, приведенном ниже, не используются ключевые слова, только символы «?» и «:»: Svariable = condition ? expressionl -. expression2 ; Если условие condition выполняется, то переменной Svariable присваивается результат вычисления выражения expressionl, иначе — выражения expression2. В результате можно писать очень компактный, и тем не менее вполне прозрачный код. Возьмем пример из предыдущего раздела:
60 Глава 2, Операторы $temperature = 3 5; if (($temperature >= 25) && ($temperature <= 30)) { echo ("Температура комфортна"); } else { echo ("Температура некомфортна"); } Все восемь строк оператора i f могут быть заменены одной строкой с использованием тернарного оператора (правда, строка получается достаточно длинная, и в книге она разбита на две): Stemperature = 35; echo (Stemperature >= 25) && (Stemperature <= 30) ? "Температура комфортна" : "Температура некомфортна"; В следующем примере вычисляется абсолютное значение (модуль) числа. Обратите внимание на использование знака «—» для изменение знака числа. Svalue = -25; $abs_value = $value < 0 ? -$value : $value; echo $abs_value; Наконец, в последнем примере раздела производится преобразование числа в диапазоне от 0 до 15 в шестнадцатеричную форму. Для получения символов от «А» до «F» используется функция chr, которая возвращает символ по его коду ASCII (см. гл. 3). Svalue = 14; $output = $ value < 10 ? "Ox".$value : "Ox ".chr ($value - 10 + 65) ; echo "$value = $output"; Результатом выполнения скрипта является строка «14 = ОхЕ». Оператор SWITCH При проверке большого количества условий даже использование оператора if... elseif может стать несколько утомительным. В таких случаях на помощь приходит оператор switch, предназначенный для сравнения заданного выражения с различными вариантами значений. Оператор начинается с ключевого слова switch, за которым в скобках записывается некоторое выражение. Далее после ключевого слова case перечисляются возможные варианты значений. В случае совпадения результата вычисления выражения с каким-либо значением, выполняются операторы, записанные ниже, вплоть до оператора break. Если результат вычисления выражение не совпал ни с одним из значений, заданных после case, выполняются операторы, расположенные после ключевого слово default. Впрочем, секция default может и отсутствовать, тогда в таком случае никаких действий не выполняется. Ниже приведен пример использования оператора switch для анализа температуры.
Оператор SWITCH 61 $temperature = 2 5; switch ($temperature) { case 25 : echo "Приятная погода"; break; case 26 : echo "Все еще приятная погода"; break; case 27 : echo "Становится теплее"; break; default : echo "Температура за заданными пределами"; break; } В результате выполнения этого примера на экран будет выведена строка Приятная погода Следует иметь в виду, что после case могут располагаться только значения целого, вещественного или строкового типов. Но что если требуется выполнить одно и то же действие при нескольких значениях выражения? В этом случае можно использовать несколько подряд идущих конструкций case. Это иллюстрирует пример 2.6, в котором температура анализируется на принадлежности диапазонам 24-26, 27-29 и т. д. Пример2.6. Использованиеоператора switch, phpswitch.php циждитД1^1-Ц4^41»-ИЦШ-11Д11ии1' nm.irauiii. и iummnmHmnH.iLWUw— mpii—wihiцимимшгчпмг-тг 1Ч1Т ri-nrrпмцгч n— ^ '- " <HTML> <HEAD> <TTTLE> Использование оператора switch </TTTLE> </HEAD> <BODY> <H1> Использование оператора switch </Hl> <?php $temperature = 27; switch ($temperature) { case 2 4: case 2 5: case 2 6: echo "Приятная погода"; break; case 2 7: case 2 8: case 2 9:
62 Глава 2. Операторы . echo "Все еще приятная погода"; break; case 3 0 : case 31: case 32: echo "Становится жарковато" ; break; default: echo "Температура вне заданных пределов" ; } ?> </BODY> </HTML> На рис. 2.7 представлен результат выполнения этого примера. файл Правка Вид Избранное Сервис £ правка ©н:мл 'У й ш Ф : ;рп°»» ц/уф*+<е ' 0 \ % Адрес;.|| |3 http://localhost/php/02/phpswitch.php ш Переход ■■; Ссылки,- Использование оператора switch Все еще приятная погода Рис. 2.7. Использование оператора switch Циклы FOR Одним из основных назначений компьютеров является обработка больших объемов информации. Например, требуется подсчитать среднюю оценку на выборке из 10000 студентов. Выполнение этой задачи вручную займет уйму времени и не гарантировано от отсутствия ошибок. Но для компьютера это является тривиальным действием. Компьютеры обрабатывают повторяющиеся действия при помощи циклов, и первым типов циклов, которые рассматриваются ниже,
Циклы FOR 63 будут циклы for, предназначенные для повторения выполнения определенного оператора (который может быть и составным). Синтаксис цикла for приведен ниже: for {expressionl; expression2; expression3) statement В выражении expressionl производится инициализации цикла, чаще всего в нем выполняется присваивание начального значения определенной переменной (счетчику цикла). Обычно счетчик цикла используется для подсчета количества раз исполнения оператора statement (тела цикла). Выражение expressionl выполняется однократно перед выполнением собственно цикла. Следующие выражение, expression2, задает условие повторения цикла. Цикл продолжает выполняться до тех пор, пока это выражение остается истинным. Первый раз условие проверяется до выполнения оператора statement, так что если условие цикла будет ложным с самого начала, тело цикла не будет исполнено не разу. Обычно условие используется для проверки текущего значения счетчика цикла. Наконец, третье выражение, expression3, выполняется каждый раз после тела цикла. Обычно оно используется для изменения (например, увеличения) счетчика цикла. Ниже приведен простой пример использования цикла for. В примере 2.7 цикл используется для того, чтобы вывести заданную строку пять раз. Цикл начинается с присваивания счетчику цикла — переменной $counter — значения 0. Счетчик увеличивается каждый раз, когда выполняется тело цикла, при этом проверяется условие повторения цикла с тем, чтобы цикл исполнился ровно 5 раз. Пример 2.7. Использование цикла for, phpfor.php <HTML> <HEAD> <TITLE> Использование цикла for </TITLE> </HEAD> <BODY> <H1> Использование цикла for </Hl> <?php for ($counter = 0; $counter < 5; $counter++) { echo "Эта строка будет выведена пять pa3<BR>"; ?> </BODY> </HTML> Результат выполнения примера приведен на рис. 2.8.
64 Глава 2. Операторы файл Дранка Вод Избранное Сервис С/травка ф"л< ■ ф Ш Ш &>:«РПоИ1Ж "• «ранное ф\ШШ Aflpecy\UJhttp:i/localhpst/php/02/phpfor.php_ _Ц| "Переход.,..,Ownw. Использование цикла for Эта строка будет выведена пять раз Эта строка будет выведена пять раз Эта строка будет выведена пять раз Эта строка будет выведена пять раз Эта строка будет выведена пять раз Рис. 2.8. Использование оператора for Выражения в цикле for при необходимости могут обрабатывать несколько счетчиков цикла, при этом для разделения отдельных подвыражений используется оператор запятая «,». Ниже приведен пример цикла с двумя счетчиками: for ($varl = 1, $var2 = 2; $varl < 5 && $var2 < 5; $varl+ + , $var2++) } echo "$varl x $var2 = ", $varl*$var2, "<BR>"; Результатом выполнения этого примера будут следующие строки: 1x2=2 2x3 = 6 3 х 4 = 12 Впрочем, в цикле for использовать счетчики необязательно. Ниже приведен пример цикла с использованием гипотетических функций доступа к данным. Функция ini tialize_c о nn ее t ion устанавливает соединение, функция check_f or_data возвращает TRUE при наличии данных и FALSE при их отсутствии, и, наконец, функция move to next item предназначена для получения следующей порции данных. Как видно, явного изменения каких-то переменных в теле цикла не производится. for (initialize connection { ; checkfordata echo "Обработка данных<ВК>"; movetonextitem ())
ЦиклыУУН11-Е 65 Циклы\Л/Н11_Е Другим типом циклов являются циклы while. Вместо использования счетчика цикла, цикл проверяется некоторое условие и выполняется до тех пор, пока оно остается истинным. Ниже приведен синтаксис цикла while. while (expression) statement Оператор statement, образующий тело цикла, может быть как простым, так и составным. Условие проверяется перед вьшолнением тела цикла, так что если оно будет ложным с самого начала, цикл не выполнится ни разу. Как легко догадаться, тело цикла должно оказывать какое-то влияние на условие, чтобы предотвратить образование бесконечного цикла (зацикливание). Пример 2.8 иллюстрирует использование цикла while. В данном примере на экран выводится значение переменной $value до тех пор, пока оно не превысит 10, при этом значение удваивается при каждом выполнении тела цикла. Перед вьшолнением цикла переменная инициализируется (в противном случае ей бьшо бы по умолчанию присвоено значение 0, что автоматически привело бы к бесконечному циклу). Пример 2.8. Использование цикла while, phpwhile.php <HTML> <HEAD> <TITLE> Использование цикла while </TITLE> </HEAD> <BODY> <Hl> Использование цикла while </Hl> < ?php $value = 1 ; while ($value < 10) { echo "Значение $value = ", $value, "<BR>"; $value * = 2 ; } ?> </BODY> </HTML> Результат выполнения примера приведен на рис. 2.9. 3 РНР в щшмеоах
66 Глава 2. Операторы Н Использование цикла while - Microsoft Internet Explorer |„ ||П||Х| |айп Правка В« Избранное Сервис Справка Ф^-„л - ^- g2 Ш $&\р*»* ^"*»«" 4&\ШШ Адрес; Ц http://localhosyphp/0^/phpwhile.php giiii ЦЗПериод ^Ссылки. ■*■ ■ I Ш !■-■ — ■!« — «■ w^—ШШ ,M.H.W — ,4 |«| || | ЯИ^—..,^|.|,., Ч,..—Itll И ,W1P4. ■ Диг>.<1 I i ■<! t.' t< litH^rt^ Использование цикла while Значение 1 = 1 Значение 2 = 2 Значение 4 = 4 Значение 8 = 8 Рис. 2.9. Использование оператора while Данный тип цикла часто используется в том случае, если в цикле отсутствует явно заданный счетчик. Например, при чтении данных из файла обычно используется функция для проверки достижения конца файла. Ниже приведен пример подобного использования цикла while при помощи гипотетических функций. Обратите внимание, что в теле цикла происходит считывание данных (и тем самым продвигается указатель файла). Если этого не сделать, цикл станет бесконечным. openflle (); while (! end_of_file ()) { $data = read_data ( ) ; echo Sdata; } ЦиклыОО...WHILE Наряду с циклами while в PHP присутствуют и циклы do ... while. Основное их отличие состоит в том, что условие цикла проверяется не до, а после того как тело цикла будет выполнено, что отражается и в синтаксисе оператора: do statement while {condition) Ниже приведен пример из предыдущего раздела, только с использованием оператора цикла do... while:
Циклы FOREACH „_„_ 67 $value = 1; do { echo $value, "<BR>"; $value *= 2; } while ($value < 10); Отличие между циклами while и do. . . while на самом деле весьма существенно. Если условие цикла изначально ложно, то цикл while не выполнится ни один раз, а тело цикла do ... while будет выполнено однократно. Например, следующий цикл не выводит на экран ничего: $value = 20; while ($value < 10) { echo $value, "<BR>"; $value * = 2; } В тоже время после выполнения следующего примера на экран будет выведено число «20»: $ value- = 20; do { echo $value, "<BR>"; $value * = 2; } while ($value < 10); Циклы FOREACH Для упрощения обработки массивов предусмотрен специальный тип цикла — оператор foreach. Массивы будут рассматриваться более подробно в следующей главе, а здесь они будут лишь бегло упомянуты. Массивы состоят из отдельных элементов, и цикл fore ас h предназначен для перебора всех элементов массива без использования счетчика цикла. Ниже приведен синтаксис этого оператора: foreach (array as $value) statement foreach (array as $key => $value) statement Пример 2.9 демонстрирует применение данного типа циклов для последовательного вывода на экран всех элементов массива $агг. Пример 2.9. Использование цикла foreach, phpforeach.php <HTML> <HEAD> <TITLE> Использование цикла foreach </TITLE>
68 Глава 2. Операторы </HEAD> <B0DY> <Н1> Использование цикла foreach </Н1> <?php $arr = array ("яблоки", "апельсины" foreach ($arr as $value) { echo "Текущий фрукт: $value<BR>' } ?> </B0DY> </HTML> 'бананы") Результат выполнения примера представлен на рис. 2.10. Особенности данного типа циклов будут более подробно освещены в гл. 3. файл Правка Вил избранное Сервис Справка ^jr uj lsu ч,*» ; Адресу \Щ http://locaJhosVphp/<Wphpforeach.php Использование цикла foreach Текущий фрукт: яблоки Текущий фрукт: апельсины Текущий фрукт: бананы ...JP Рис. 2.10. Использование оператора foreach Оператор BREAK Иногда требуется прервать выполнение тела оператора for, foreach, whi le, do. . .while или switch. Этого можно достичь при помощи оператора break. Он уже встречался ранее при рассмотрении оператора switch — там он использовался для завершения обработки определенного значения температуры:
Оператор CONTINUE 69 $temperature = 2 6; switch ($temperature) { case 25 : echo "Приятная погода"; break; При помощи оператора break можно также досрочно прервать выполнение любого цикла. Например, выполнение следующего цикла for будет досрочно прервано, как только значение счетчика цикла достигнет 2 (на третьей итерации): for ($counter = 0; $_counter < 5; $counter++) { echo "Эта строка будет выведена пять pa3<BR>"; if ($counter == 2) { echo "Достаточно, конец цикла<ВЯ>"; } В результате выполнения данного примера на экран будут выведены следующие строки: Эта строка будет выведена пять раз Эта строка будет выведена пять раз Эта строка будет выведена пять раз Достаточно, конец цикла Оператор CONTINUE Наконец, предусмотрена возможность досрочного перехода к началу цикла, не выполняя все тело цикла целиком. Для этого используется оператор continue. Его применение продемонстрировано в примере 2.10, который выводится на экран числа, обратные к счетчику цикла. Оператор continue используется для предотвращения деления на ноль, что неминуемо вызвало бы сообщение о математической ошибке. Пример2.10. Использование оператора continue, phpcontinue.php <HTML> <HEAD> <TITLE> Использование оператора continue </TITLE> </HEAD> <BODY> <H1> Использование оператора continue
70 Глава 2. Операторы </Н1> <?php $value = 1 ; for ($value = -2; $value < 3; $value++) { if($value == 0) { continue; } } echo  / Svalue = ", 1 / Svalue, "<BR>"; </BODY> </HTML> m i wjhhhmitwgJHUPW^mieMH Результат выполнения примера представлен на рис. 2.11. Обратите внимание, что деление на ноль не произошло Файл Правка 2ид избранное Сервис Справка (У'-О -id &®\p4«it"*~™ 0\Ш Адрес*, iSgjhttp/yiocalhosyphp/02/phpcontinuelphp j j j 3 г | epe«Mf/ Sajmtti-' Использование оператора continue 1 / -2 = -0.5 1/-1=-1 1/1 = 1 1/2 = 0.5 Рис. 2.11. Использование оператора continue Альтернативный синтаксис В PHP также предусмотрен альтернативный синтаксис для операторов if, while, for, foreacb. и switch. В альтернативном варианте открывающая фигурная скобка составного оператора заменяется на двоеточие (:), а закрывающая скобка — на оператор endif, endwhile, endfor, endforeach или endswitch соответственно, после которого следует точка с запятой. Ниже приведен пример использования альтернативного синтаксиса для оператора if:
$value =10; if ($value == 1) : echo '$value = 1' ; elseif ($value == 10) : echo '$value = 10' ; else: echo '$value не равно ни 1, ни 10"? endi f; Итоги Для построения программ в РНР предусмотрен широкий спектр операторов и управляющих структур. При помощи операторов осуществляется обработка данных, например сложение чисел или проверка равенства. Управляющие структуры предназначены для организации требуемого порядка выполнения программы. Ниже перечислены краткие итоги главы: • Арифметические действия представлены пятью операторами: + ,-,*,/ и%. Кроме того, предусмотрены различные математические функции от abs до tan. • Операторы присваивания =,+ = ,- = ,* = ,/=, .=,%=,&=, [ = ,л=,<= и>= предназначены для присваивания значений переменным, с возможностью совмещения собственно присваивания с выполнением арифметического или логического действия. • Операторы++ и-- предназначены для увеличения и уменьшения значения переменной. • Оператор N" предназначен для выполнения команд операционной системы. • Операторы . и . = позволяют склеивать строки. • Битовые операторы &, |,л, ~, < и> позволяют управлять отдельными битами в переменных. • Операторы ==,===, ! = ,<>, ! = = ,<,>,<= и>= предназначены для сравнения значений переменных и выражений. • Логические операторы and, or, xor, !, && и И предназначены для построения сложных условий. • Оператор if проверяет выполнение определенного условия и выполняет различные операторы в зависимости от результата. • Оператор switch позволяет проверять сразу несколько вариантов условия, действуя как расширенный оператор i f. • Оператор цикла for позволяет выполнить последовательность операторов до тех пор пока условие цикла остается истинным. Он состоит из инициализации, условия цикла, тела цикла и оператора, который выполняется после тела цикла. • Цикл while выполняется, пока его условие остается истинным. • Цикл do. . . while отличается от цикла while тем, что проверка выполнения условия производится после тела цикла, а не до него. • Цикл foreach предназначен для работы с массивами.
Глава 3 Строки и массивы Два типа данных заслуживают особого внимания — строки и массивы. Строки уже использовались ранее, включая строковые константы как в одинарных, так и в двойных кавычках (в последнем случае выполняется также замена переменных на их значения). В РНР включено множество функций для обработки строк, которые позволяют решать самые различные задачи — определение длины строки, сортировка, поиск подстроки, удаление начальных и конечных пробелов и многие, многие другие. В этой главе приведен обзор основных функций по обработке строк. Кроме строк, в этой главе описывается работа с массивами. Ранее было показано, как хранить данные в простых переменных, но на этом возможности языка далеко не исчерпываются. Массивы содержат в себе множество элементов данных, с каждым из которых связан числовой или строковый индекс или ключ. Например, для хранения экзаменационных оценок можно использовать массив целых чисел, в качестве индекса которого выступает порядковый номер или даже фамилия студента. Идеальным средством для обработки массивов являются циклы, а цикл foreach специально для этого и предназначен. Функции обработки строк В РНР имеется множество функций для обработки строк. В табл. 3.1 приведены наиболее часто используемые из них. Таблица 3.1. Функции обработки строк Функция Назначение chr Возвращает символ по его коду ASCII. chunkspl it Разбивает строку на подстроки заданной длины. Зашифровываетстрокус использованием одного из ал го- ритмов (например, DES). echo Выводит одну или несколько строк.
74 Глава 3. Строки и массивы Функция Назначение explode Разбивает строку на подстроки, ограниченные заданным разделителем, и формирует из них массив. html_ent i ty_de с ode Декодирует все HIM {.-представления в соответствующие символы. Функция обратно по отношению Khtmlentites. htmlentites Кодирует все специальные символы в их НГМ {.-представление (например, символ < кодируется как &gt;). htmlspecialchars Кодирует все символы в их HIM {.-представление, если оно у них есть. implode Формирует строку из элементов массива. Itrim Удаляет начальные пробелы из строки. number format Представляет число в виде строки в различных форматах. ord Возвращает ASC//-irqq символа. parse_str print Разбираетстрокуив1иприсваиваетзначенияпеременным. Выводитстроку. printf rtrim Выводит строку с форматированием. Удаляетконечныепробелыизстроки. setlocale Устанавливает информацию о кодовой странице. similar text Вычисляет степень похожести двух строк. s printf Возвращает строку с форматированием. sscanf Разбирает строку по шаблону и присваивает полученные значения переменным. str_ireplace Гоже самое, 4Tonst rre place, но без учета различий врегисгресимволов. str_pad Дополняет строку до заданной длины другой строкой. str_repeat Г/овгоряегсгрокузаданноеколичествораз. str_replace И щет в строке все вхождения подстроки и меняет на задан- нуюстроку. str shuffle Случайным образом перемешиваетвсе символы вст роке. strsplit Формирует массив из символов строки. str word count Подсчитывает количество слов в строке. strcasecmp Выполняетпобайтовое сравнениестрокбез учетарегистра символов strchr Гоже самое что strstr.
Функции обработки строк Функция strcmp strip_tags stripos strlstr strlen strnatcasecmp strnatcmp stmcasecmp strncmp strpos strrchr strrev strripos strrpos strspn strstr strtolower strtoupper strtr substr compare sub str —count Назначение Выполняет побайтовое сравнение строк с учетом регистра символов. Удаляетиз строки eceHTML-иРНР-теги. Ищетпервоевхождениеподстрокивстрокебезучетареги- сграсимволов. Тоже самое что s t r s t r, но 5езучета.регистпрасимволов. Возвращает длину строки. Тоже самое что strnatcmp, ш>Ъезучета.регистпра символов. Сравн\лваетстрок\лсучетоместественногопорядка'. Выполняет побайтовое сравнение первыхп символов строк безучетарегистра символов. Выполняет побайтовое сравнение первых п символов строк. Ищетпервоевхождениеподстрокивстроке. Ищет последнее вхождение символа в строке. Инвертирует строку—прочитываетего справа налево. Ищет последнее вхождение подстроки в строке без учета регистра символов. Ищет последнее вхождение подстроки в строке. Возвращает длину участка строки, состоящего из заданных символов. Возвращает часть строки от первого вхождения подстроки до конца. Преобраэуетпрописныебуквывстрочные. Преобразует строчные буквы в прописные. Преобразует заданные символы в строке. Сравнивает две строки, начиная с заданного смещения (сучетомилибезучетарегистрас\лмволов]. Подсчитывает, сколько раз заданная подстрока встречается встроке. Естественным здесь и далее называется такой порядок сортировки, при котором цифровые последовательности, входящие в состав сравниваемьи строк, рассматриваются как числа. Например, при естественном сравнении строк они будут упорядочены следующим образом: «А» < «АО < «А1» < «А1А» < «А1Б» < «А2» < «А10» < «А20». — Прим.ред.
76 Глава 3. Строки и массивы Функция stubstr_ substr trim uc fi rst replace Назначение Ищет в заданном участке строки все вхождения подстроки и меняет на другую строку. Возвращает заданную часть исходной строки. Удаляет начальные и конечные пробелы из строки. Преобразует первую букву строки в прописную. Использование строковых функций Ниже приведен пример использования некоторых строковых функций. <?php echo trim (" Жизнь прекрасна ! " ) , " \п" ; echo substr ("Жизнь прекрасна!" , 6, 9) , "\п"; echo "\"прекрасна\" начинается с символа ", strpos ("Жизнь прекрасна!", "прекрасна"), "\п"; echo ucfirst ("жизнь прекрасна!"), "\п"; echo "Длина строки \"Жизнь прекрасна!\" ", strlen ("No worries."), " символов.\n"; echo substr_replace ("Жизнь прекрасна!", "ужасна", 6, 9), "\n"; echo chr F5), chr F6), chr F7), "\n"; echo strtoupper ("Жизнь прекрасна!"), "\п"; ?> В данном примере используются функции, описанные в табл. 3.1. В результате выполнения примера на экран будут выведены строки: Жизнь прекрасна! прекрасна "прекрасна" начинается с символа б Жизнь прекрасна! Длина строки "Жизнь прекрасна!" 11 символов. Жизнь ужасна! ABC ЖИЗНЬ ПРЕКРАСНА! Пример показывает использование наиболее употребительных функций. Их список намного больше, но для решения большинства задач функций, приведенных в в табл. 3.1, обычно оказывается более чем достаточно. Кроме того, различные функции можно комбинировать между собой. Еще один прием — в РНР можно обратиться к произвольному символу строки по его номеру при помощи фигурных скобок, как показано ниже: $string = 'Жизн прекрасна! ' ; $first_character= $string{0};
Форматирование строк 77 Форматирование строк Часто встречается задача представления различных данных в строковом виде, например, для вывода на экран. Для этого идеально подходят две функции — printf и sprintf. printf сразу выводит результат на экран, a sprintf возвращает его в виде строки. Ниже приведен синтаксис этих функций (здесь и далее аргументы в квадратных скобках являются необязательными): printf (формат [, аргументы]) sprintf (формат [, аргументы]) Строка формата состоит из нескольких директив (в предельном случае она может быть и пуста, но тогда и результат будет пустой строкой). Каждая директива представляет собой символы, которые копируются без изменений, или спецификацию фотмата. Спецификация формата начинается со знака процента (%), после которого следуют по порядку один или несколько элементов: • Необязательный описатель заполнения, определяющий, какой символ будет использоваться для дополнения результата до требуемой длины. Это может быть пробел (по умолчанию) или 0. • Необязательный символ «-» (минус), который задает выравнивание результата влево. По умолчанию результат выравнивается вправо. • Необязательное число, задающее минимальное число символов в результате форматирования. • Необязательный описатель точности, определяющий, сколько десятичных разрядов отображать для чисел с плавающей точкой. Записывается как точка с числом после нее. Имеет смысл только для числовых данных типа float. • Описатель типа данных аргумента — символ. Ниже перечислены допустимые описатели типов данных: % Применяется для вывода символа процента. Аргумент не используется. b Аргумент считается целым числом и выводится в виде двоичного числа. с Аргумент считается целым числом и выводится в виде символа с соответствующим кодом ASCII. d Аргумент считается целым числом и выводится в виде десятичного числа со знаком. е Аргумент считается вещественным числом (float) и выводится в экспоненциальном виде, например 1.2е+2. f Аргумент считается вещественным числом (float) и выводится в виде десятичного числа. о Аргумент считается целым числом и выводится в виде восьмеричного числа. s Аргумент считается строкой и выводится как строка. и Аргумент считается целым числом и выводится в виде целого числа без знака. х Аргумент считается целым числом и выводится в виде шестнадцате- ричного числа, используются прописные буквы. X Аргумент считается целым числом и выводится в виде шестнадцате- ричного числа, используются строчные буквы.
78 Глава 3. Строки и массивы Эти функции особенно удобны для работы с вещественными числами. Например, спецификация формата % f6.2 описывает вещественное число, которое займет 6 знаков, из них два знака будет отведено на дробную часть числа. Ниже приведен пример использования рассматриваемых функций. <?php Print f ("У меня %s яблок и %s апельсинов. \п" , 6, 56) ; $уеаг = 2005; $month = 4; $day = 28; printf ("%04d-%02d-%02d\n", $year, $month, $day); $price = 5999.99; printf("\$%01.2f\n", $price); printf("%6.2f\n", 1.2); printf("%6.2f\n", 10.2) ; printf("%6.2f\n", 100.2) ; $string = sprintf ("Сейчас у меня %s яблок и %s апельсинов. \n" , 5,45); echo $string; ?> В этом примере представлен широкий спектр типов данных. Вот что будет выведено на экран в результате: У меня б яблок и 56 апельсинов. 2005-04-28 $5999.99 1.20 10.20 100.20 Сейчас у меня 5 яблок и 45 апельсинов. Замечание ф . Для форматирования чисел также можно применять функцию number_format. Преобразование в строки и из строк Преобразование данных между строковым форматом и другими форматами является достаточно распространенной задачей при программировании в Интернет, так как данные между браузером и web-сервером передаются в текстовом виде. Для преобразования в строку используется функция strval или преобразование типов (string), как это показано ниже. <?php $float = 1.2345; echo (string) $ float, "\n"; echostrval($float), "\n"; ?>
лоздание массивов 79 Логическая истина TRUE преобразуется в строку «1», а логическая ложь FALSE — в пустую строку. Целое или вещественное число преобразуется в строку очевидным образом, при необходимости используется экспоненциальная форма представления. Значение NULL всегда преобразуется в пустую строку. Строка, в свою очередь, может быть преобразовано в число. Если в ней содержатся символы «.», «е» или «Е», то число считается вещественным. В противном случае число считается целым. РНР анализирует начало строки и преобразует его в число. Если в начале строки не содержится корректной записи числа, результатом будет 0. Корректная запись числа начинается с необязательного знака («+» или «-»), за которым следуют цифры. Для вещественного числа далее допустима десятичная точка, снова цифры и необязательная показательная часть после буквы «е» или «Е». При использовании строковых констант в арифметических операциях РНР выполняет преобразование типов автоматически, что продемонстрировано в примере ниже: <?php $number = 1 + 4.5"; echo " $number\n" ; $number = 1 + "-1.5e2"; echo "$number\n"; $text = .0"; $number = (float) $text; echo $number / 2 . 0 , " \n" ; ?> В результат на экран будут выданы строки: 15.5 -149 2.5 Создание массивов Время перейти к изучению следующей структуры данных в РНР — к массивам. Массивы представляют собой набор данных, объединенных под одним именем, и они занимают значительное место в программировании. Каждый массив состоит из отдельных элементов, и каждый элемент массива ассоциирован с определенным индексом. Массивы могут быть созданы при помощи оператора присваивания точно так же, как и обычные переменные. Имена массивов подчиняются тем же правилам, что и имена переменных, в частности, они начинаются со знака $. Отличительным признаком массива являются квадратные скобки после его имени, например: $fruits [1] = "яблоко"; Данный оператор создает массив Sfruits и присваивает его элементу с индексом 1 значение "яблоко". С этого момента к элементу можно обращаться точно также, как и к обычной переменной, не забывая указывать значение индекса в квадратных скобках, например: echo $ fruits [l] ;
§£ »^.. ^.»^. _^.лл Глава 3. Строки и массивы Этот оператор просто выведет строку "яблоко". К массиву легко добавить и другие элементы, например: $fruits [2] = "груша"; $fruits [3] = "абрикос"; Наряду с числами, в качестве индексов массивов могут быть использованы и строки, например: $apple_count ["Москва"] = 10000; $apple_count ["Рязань"] = 500 0; $apple_count [ "Казань" ] =3000; Следует обратить внимание на то, что в одном и том же массиве могут использоваться и числовые, и строковые индекс одновременно. Существует сокращенная форма создания массива — после имени массива ставится пара квадратных скобок [], например: Sfruits [] = "яблоко"; $ fruits [] = "груша"; $ fruits [] = "абрикос"; РНР по умолчанию нумерует элементы массива, начиная с 0, так что в этом случае Sfruits [ 1 ] будет содержать строку " груша", ане "яблоко", каквпер- вом примере. Для обработки всех элементов массива удобно использовать циклы, например, цикл for. Нумерация элементов массива начинается с 0, а функция count возвращает количество элементов массива. Ниже приведен пример, который последовательно выводит все элементы массива, каждый в своей строке. for ($index = 0; $index < count ($fruits) ; $index+ + ) { echo $fruits [$index], "\n"; } Существует еще более краткая форма для создания массива при помощи функции array: $fruits = array ("яблоко", "груша", "абрикос"); Этот оператор создает массив, индекс которого начинается с 0. Если же требуется начать нумерацию элементов массива с другого числа, можно воспользоваться конструкцией =>: $fruits = array (I => "яблоко", "груша", "абрикос"); Этот массив, в отличие от предыдущего, в элементе $ fruits [ 1 ] содержит строку "яблоко", ане "груша". Точно так же может быть создан массив со строковыми индексами: $apple_count = array ("Москва" => 10000, "Рязань" => 5000, "Казань" => 3 0 0 0); Оператор => связывает индекс и соответствующее ему значение элемента массива.
Модификация элементов массива 81 Замечание Щ « Для массивов, содержащих последовательные данные, существует еще один эффек- [ тивный способ создания при помощи функции range. Например, для создания массива, содержащего буквы латинского алфавита, можно использовать оператор $letters = range ("a", " z " ) ; Модификация элементов массива После создания массивов нередко требуется изменение значений его элементов. Это выполняется так же просто, как и изменение значения переменной. Для этого требуется обратиться к элементу массива по его индексу. Например, имеется следующий массив: $fruits [О] = "яблоко"; $fruits [1] = "груша"; $fruits [2] = "абрикос"; Для присваивания нового значения второму элементу массива используется оператор: $fruits [2] = "персик"; Для добавления нового элемента в конец массива используются уже знакомая конструкция: $fruits [] = "манго"; Наконец, выведем на экран содержимое массива при помощи цикла. Все эти операторы объединены в примере 3.1. Пример 3.1. Модификация элементов массива, phparray.php <HTML> <HEAD> <TITLE> Модификация элементов массива </ТТТЬЕ> </HEAD> <BODY> <Н1> Модификация элементов массива </Н1> <?рпр $fruits [0] = "яблоко"; $ fruits [1] = "груша"; $fruits [2] = "абрикос"; $fruits [2] = "персик"; $fruits [] = "манго"; for ($index = 0; $index < count ($fruits); $index++)
ы 1 лава S . строки и массивы echo $fruits t$index], "<BR>"; } ?> </B0DY> </HTML> На рис. 3.1 представлен результат выполнения этого примера. <£айл Правка Вид убранное Сервис Справка Qh*™ v 0 - gj (J) ^|рп«« 'ft»*-*-* ф'.£^'89 мдрес! ;, " h 11 p: //localhost/php/03/phparray.php Модификация элементов массива яблоко груша персик манго Рис. 3.1. Модификация элементов массива Предусмотрена также возможность скопировать массив целиком как одну переменную: <?php $ fruits [О] = "яблоко"; $ fruits [1] = "груша"; $ fruits [2] = "абрикос"; $new fruits = $ fruits; echo $new fruits [2] ; Пример кода, приведенный выше, выведет строку " абрикос".
Удаление элементов массива 83 Удаление элементов массива Помимо модификации, существует и возможность удаления элемента из массива. Для удаления элемента, казалось бы, можно просто присвоить элементу массива пустую строку, например: <?php $ fruits [О] = "яблоко"; $ fruits [1] = "груша"; $ fruits [2] = "абрикос"; Sn-uits [1] = " " ; for ($index = О; $index < count ($fruits); $index++) { echo $fruits [$index], "\n"; } ?> Но таким образом удалить элемент массива не удастся, и в результате на месте второго элемента будет выведена пустая строка: яблоко абрикос Для удаления элемента из массива следует использовать функцию uns et, которая действительно освобождает занятую им память. Пример использования этой функции приведен ниже: <?php Sfruits [О] = "яблоко"; $ fruits [1] = "груша"; $ fruits [2] = "абрикос"; unset (Sfruits [l]); for ($index = 0; $index < count ($fruits); $index++) { echo $fruits [$index], "\n"; } ?> При выполнении этого кода на экран будет выведено сообщение о том, что элемент массива не определен: яблоко PHP Notice: Undefined offset: 1 in 76-02.php on line 8 Замечание eemeaj^MMmimem00Mea**m4m<*ttm*mmm*^ammmu*0*iMmaam***Eitmma»*Mmmmmim*rmmmiimi и*» мц hi i иуы Miyaiii hi wh« i истиц»—^щч* Щ ^ Следует обратить внимание, что строка «абрикос» не была выведена на экран, так / как количество элементов массива после удаление стало равно двум. Для обработки массивовсостроковым\лилинепоследовательнымичисловымииндексамииспользу- ютсяспециальныеприемы, описанныениже. Крометого, сообщениебудетвыведено только в том случае, если в настройках РНРразрешена выдача сообщений класса Notice. Обычно по умолчанию выдача подобных сообщений отключена.
84 , , Глава 3. Строки и массивы Перебор элементов массива В предыдущем разделе был приведен пример вывода всех элементов массива при помощи цикла for. Для более простого вывода всех элементов массива (в том числе со строковыми или непоследовательными числовыми индексами) предусмотрена функция printr, пример использования которой приведен ниже: <?php $fruits [О] = "яблоко"; $fruits [1] = "груша"; $fruits [2] = "абрикос"; print_r (SFruits); ?> При выполнении этого кода будет выведено следующее Array ( [0] => яблоко [1] => груша [2] => абрикос ) Замечание щ Функция р г i n t _ г предназначена для вывода переменной произвольного типа, / включая обычные переменные, массивы и объекты. Для обработки массивов предусмотрен также специальный вид цикла — цикл foreach. Синтаксис этого оператора имеет два варианта: foreach (array as $value) statement foreach (array as $key => $value) statement Первый вариант оператора присваивает в цикле переменной Svalue очередной элемент массива. Второй вариант кроме этого присваивает переменной $кеу значение индекса, соответствующего текущему элементу массива. Пример использования цикла foreach приведен ниже: <?php $fruits = array ("яблоко", "груша", "абрикос"); foreach ($fruits as $value) { echo "Значение: $value\n"; } ?> В результате выполнения этого примера будут выведены строки: Значение: яблоко Значение: груша Значение: абрикос
Функции для работы с массивами Л5 Для вывода индекса элемента массива вместе с его значением используется второй вариант синтаксиса оператора foreach: <?php $fruits = array ("яблоко", "груша", "абрикос"); foreach ($fruits as $key => $value) { echo "Индекс: $key; Значение: $value\n"; } ?> В результате выполнения этого примера будут выведены строки: Индекс: 0; Значение: яблоко Индекс : 1; Значение: груша Индекс: 2; Значение: абрикос Для перебора элементов массива может быть также использован цикл whi le в сочетании с функцией each. Эта функция специально предназначена для перебора элементов массива. Каждый раз, когда она вызывается, она возвращает текущий элемент массива и передвигает внутренний указатель на следующий элемент. Функция возвращает пару индекс—значение в виде массива. Для присваивания индекса и значения элемента массива отдельным переменным используется функция list. Пример использования этих двух функций приведен ниже. <?php $fru,its = array ("яблоко", "груша", "абрикос"); while ($list ($key, $value) = each ($fruits)) { echo "Индекс: $key; Значение: $value\n"; } ?> Результат выполнения этого кода точно такой же, как и у предыдущего примера. Функции для работы с массивами Как и для обработки строк, для работы с массивами в РНР предусмотрено достаточно много функций. Наиболее важные из них приведены в табл. 3.2. Таблица 3.2. Функцииобработкимассивов Функция Назначение array _chunk arraycom'bine Разбивает массив на несколько меньшихмассивовзаданно- го размера. Создает массив из двух заданных массивов — массива индексов элементов и массива значений. Формируетмассив, индексами которогоявляются значения arraycountvalues заданного массива, а значениями — число повторений соот- ветствующегозначенмявзаданноммассиве.
86 Глава 3. Строки и массивы Функция Назначение Формирует массив из тех элементов первого заданного массива, которые отсутствуют в остальных заданных в качестве аргументов функциимассивов. array_diff array_fill Заполняет массив заданным значением. Формируетмассивизэлементов.которыеприсутствуютво всех заданных массивах. array_intersect array_key_exists Проверяет наличие заданного индекса в массиве. array_keys Возвращает массив из индексов заданного массива. array_merge Объединяет несколько массивов в один. array_multisort Выполняетсортировкумногомерногомассиваилинесколь- ких одномерных массивов. array _p ad Дополняет массив до заданного количества элементов за - даннымзначением. аггаурор Возвращает последний элемент массива, одновременно удаляяэлементиз массива. array_push Добавляет заданныеэлеменгывконецл#ассива.у4иал0гич- ноконструкции$array [] = $value;. array_rand array_reduce Выбираетодинилинесколъкослучайновзятыхэлементов из массива. Осуществляетпоследовательное применение заданной функции кэлементаммассива, формируя итоговоезначение. Например, еслифункциявыполняетсложениесвоихаргументов, врезультатеформируетсясуммавсехэлементовмассива. array_reverse Производит обращение массива — первый элемент становится последним, второй — предпоследним и тд. array_search Ищет заданный элемент в массиве и возвращает соответствующим ему индекс array_shift Возвращает первый элемент массива, одновременно удаляя его из массива с перенумерацией числовых индексов. array_slice Вырезает из массива подмассив заданной длины, начиная с указанного элемента. arraysum Вычисляет сумму всех элементов массива. array umque ay_umqt 'Удаляет дублирующиеся значения из массива. array_unshi ft array_walk Добавляет один или несколько элементов в начало массива с перенумерацией числовых индексов. Вызывает заданную функцию последовательно для каждого элементадеассива.
Сортировка массивов 87 Функция array arsort assort count current each inarray key krsort ksort list natcasesort natsort pos reset rsort shuffle sizeof sort usort Назначение Создает массив из заданных значений или пар индекс—значение. Сортирует массив по убыванию его значений, сохраняя индексы неизменными. Сортирует массив по возрастанию его значений, сохраняя индексы неизменными. Возвращаетколичествоэлементоввмассиве. Возвращает значение текущего элемента массива. Возвращает текущие индекс и значение элемента массива и продвигаетуказатель на следующий элемент. Проверяет, присутствует ли заданное значение в массиве. Возвращает индекс текущего элемента массива. Сортирует массив по убыванию его индексов. Сортирует массив по возрастанию его индексов. Присваивает значения из массива списку переменных. Сортируетмассивестественнымобразом'безучета регистра символов. Сортируетмасолв естественным образом с учетом регистра символов. Синоним функции current. Устанавливает внутренний указатель на первый элемент массива. Сортируетмассивпоубыванию значений егозпементов с перенумерацией его индексов. Переставляет элементы массива случайным образом. Синоним функции count. Сортирует массив по возрастанию значений его элементов с перенумерацией его индексов. Сортируетмассивсиспользованиемзаданной функции сравнения элементов массива. Примеры использования этих функций приведены далее в этой главе, и первыми будут рассмотрены функции сортировки массивов. См. замечание нас. 75. — Прим.ред.
88 Глава 3. Строки и массивы Сортировка массивов В РНР предусмотрены все возможные способы сортировки данных в массивах. Простейшим способом является функция sort, которая сортирует заданный массив по возрастанию значений его элементов. Ниже приведен пример использования этой функции. <?php Sfruits [0] = "яблоко"; Sfruits [1J = "груша"; Sfruits [2] = "абрикос"; printr (Sfruits); sort ($fruits); printr ( $ fruits); 7> Ниже приведен результат выполнения этого примера. Массив Sfruits отсортирован, а его элементы перенумерованы. Array ( [0] => яблоко [1] => груша [2] => абрикос ) Array ( [0] => абрикос [1] => груша [2] => яблоко ) При помощи функции rsort массив можно отсортировать по убыванию значений его элементов: <?php Sfruits [0] = "яблоко"; Sfruits [l] = "груша"; Sfruits [2] = "абрикос"; printr (Sfruits); rsort ($ fruits); printr ( $ fruit s); 7> В результате будет выведено следующее: Array ( [0] => яблоко [1] => груша [2] => абрикос ) Array ( [0] => яблоко [1] => груша [2] => абрикос
Навигация по ассивам 89 Но что если в массиве используются строковые индексы? При использовании функций sort и г sort происходит перенумерация элементов массива, и информация о строковых индексах будет потеряна. В этом случае на помощь приходит функция assort, пример использования которой приведен ниже. <?php $fruits ['красный'] = "яблоко"; $fruits ['зеленый'] = "груша"; $fruits ['оранжевый'] = "абрикос"; print г ($fruits); asort ($ fruits); print г ($ fruits); 7> Результат выполнения примера выглядит так: Array ( [красный] => яблоко [зеленый] => груша [оранжевый] => абрикос ) Array ( [оранжевый] => абрикос [зеленый] => груша [красный] => яблоко ) Функция arsort также сохраняет строковые индексы, но сортирует массив по убыванию. Функции ksort и krsort сортируют массив не по значениям элементов, а по их индексам (в возрастающем и убывающем порядке соответственно). Наконец, если определить собственную функцию сравнения элементов массива, то при помощи функции u s о г t можно отсортировать массив по произвольному критерию. Навигация по массивам В РНР имеется ряд функций для навигации по массивам. Навигация осуществляется при помощи указателя текущего элемента массива. Например, имеется следующий массив: $vegetables [0] = "картошка"; $vegetables [1] = "морковка"; $vegetables [2] = "свекла"; Текущий элемент массива определяется при помощи функции current. После создания массива его первый элемент становится текущим: echo "Текущий: ", current ($vegetables), "<BR>"; Для перемещения указателя к следующему элементу используется функция next: echo "Следующий: ", next ($vegetables) , "<BR>";
90 Глава 3, Строки и массивы Для перемещения указателя к предьвдущему элементу используется функция next: echo "Предыдущий: ", prev ($vegetables) , "<BR>"; Функция end перемещает указатель к последнему элементу массива и возвращает его: echo "Последний: ", end ($vegetables) , "<BR>"; Для возврата указателя к началу массива используется функция reset: reset ($vegetables); Использование всех этих функций показано в примере 3.2. ПримерЗ.2. Навигация по массиву, phpnavigate.php <HTML> <HEAD> <TITLE> Навигация по массиву </TITLE> </HEAD> <BODY> <Hl> Навигация по массиву </Н1> <?php $vegetables [0] = "картошка"; $vegetables [l] = "морковка"; $vegetables [2] = "свекла"; print_r ($vegetables); echo "<BR>"; echo "Текущий: ", current ($vegetables), "<BR>"; echo "Следующий: ", next ($vegetables),■"<BR>"; echo "Предыдущий: ", prev ($vegetables), "<BR>"; echo "Последний: ", end ($vegetables), "<BR>"; echo "Сброс указателя.<BR>"; reset ($vegetables); echo "Текущий: ", current ($vegetables) , "<BR>"; ?> </BODY> </HTML> На рис. 3.2 представлен результат выполнения этого примера.
Преобразование строк в массивы и наоборот 91 Файл Правка Btv; избранное Сервис Справка АдрРС ///yfchttp://locajhost/php/03/phpnavigate.php r^[ ES Переход , Навигация по массиву Array ([0] => картошка [1] => морковка [2] => свекла) Текущий: картошка Следующий: морковка Предыдущий: картошка Последний: свекла Сброс указателя. Текущий: картошка Рис. 3.2. Навигация по массиву Преобразование строк в массивы и наоборот В РНР предусмотрена возможность преобразования данных из строки в массив и обратно. Функция implode формирует строку из массива, а функция explode формирует массив из указанной строки. Например, требуется получить все содержимое массива в виде одной строки. Для этого используется функция implode, которой передаются два аргумента — сам массив и строка, которая используется как разделитель элементов массива. Пример использования implode приведен ниже, в качестве разделителя использована запятая. <?php $vegetables [0] $vegetables [1] $vegetables [2] $text = implode echo $text; "картошка"; "морковка"; "свекла"; ,", $vegetables)?
92 „ "»««". Глава 3. Стр^окии массивы В результате выполнения этого примера будет выведена строка: картошка,морковка,свекла Для того чтобы добавить дополнительные пробелы после запятой, надо просто изменить строку-разделитель: Stext = implode (", ", Svegetables); Результат будет следующим: картошка, морковка, свекла Обратная операция производится при помощи функции explode. В строке ищется заданный разделитель, и части строки, ограниченные разделителями, становятся элементами нового массива. Пример использования функции приведен ниже. <?php $text = "картошка, морковка, свекла"; Svegetables = explode (", ", $text); print г (Svegetables); 7> Результат выполнение приведен ниже. Как видно, строка корректно преобразована в массив. Array ( [0] => картошка [1] => морковка [2] => свекла ) Извлечение переменных из массивов Если требуется для массива, проиндексированного строками, присвоить значения элементам переменным, одноименным с соответствующими индексами, то на помощь приходит функция extract. Например, имеется следующий массив: $ fruits ["good"] = "яблоко"; $fruits ["better"] = "груша"; $fruits ["best"] = "персик"; После вызова функции extract будут созданы переменные Sgood, Sbetter и т.д., и им будут присвоены соответствующие значения из массива. extract (Sfruits); Это легко наблюдать в примере 3.3.
Извлечениепеременныхизмассивов „« »,«-,_,", «§?. Пример 3.3. Извлечение переменных из массива, phpextract.php <HTML> <HEAD> <TITLE> Извлечение переменных из массива </TITLE> </HEAD> <BODY> <Hl> Извлечение переменных из массива </Н1> <?php $fruits ["good"] = "яблоко"; $fruits ["better"] = "груша"; $fruits ["best"] = "персик"; extract ($fruits); echo "\$good = $good<BR>"; echo "\$better = $better<BR>"; echo "\$best = $best<BR>"; ?> </BODY> </HTML> После выполнения этого примера переменной Sgood будет присовоено значение "яблоко", переменной Sbetter — значение "груша" ит.д., что показано на рис. 3.3. Замечание щт_ В РНР индексом массива можетбыть произвольная строка. Нодляуспешной работы f функции extract требуется, чтобы индексами массива были строки, которые являются корректными названиями переменных в языке. Например, использовать русские буквы в индексах массива в данном случае не удастся. л гичтимачч Для аналогичной цели может также использоваться функция list, которая последовательно присваивает значения элементов массива указанным переменным. Ниже приведен пример использования этой функции: <?php $vegetables [0] = "картошка"; $vegetables [l] = "морковка"; $vegetables [2] = "свекла"; list ($first, $second) = $vegetables; echo $first, "\n"; echo $second; ?>
Глава 3. Строки и массивы файл Правка £ид избранное Сервис С/травка *.l*'Wj Ш) http I t/lzatx>sKli*pl03lfh!LcttKt ftp 1'.В'5УУ!*.;' Извлечение переменных из массива $good = яблоко Sbetter = груша $best = персик Рис. 3.3. Извлечение переменных из массива В результате выполнения этого примера будут выведены строки картошка морковка А что делать, если требуется выполнить обратную операцию и сформировать массив на основе списка переменных? Для этого предназначена функция compact. В качестве аргументов она принимает имена переменных или массивы имен переменных. Значения переменных с указанными именами становятся очередными элементами массива. <?php Sfirstname = "Сергей"; Slastname = "Банников"; Srole = "Редактор"; Ssubarray = array ("flrstname", "lastname"); Sresultarray = compact (Ssubarray, "role"); printr (Sresultarray); ?> В результате выполнения этого примера будет сформирован следующий массив: Array [flrstname] => Сергей [lastname] => Банников [role] => Редактор
деление массивов 95 Слияние и разделение массивов Над массивами возможны операции слияния и разделения. Например, требуется сформировать массив, который состоит из последних двух элементов заданного трехэлементного массива. Для этого используется функция arrayslice, которая имеет три аргумента: исходный массив, смещение —номер первого элемента массива (начиная с 0) и длина создаваемого массива: <?pbp $ fruits ["good"] = "яблоко"; Sfruits ["better"] = "груша"; Sfruits [^est"] = "персик"; $subarray = array slice ($fruits, 1, 2) ; foreach ($subarray as $value) { echo "Фрукт: $value\n"; } ?> В результате будут выведены строки: Фрукт: груша Фрукт: персик Если задано отрицательное смещение, то начальный элемент будет отсчиты- ваться с конца, а не с начала массива. Если длина задана отрицательным числом, то выборка остановится за это число элементов до конца исходного массива. Если длина не задана вообще, то будет вырезан массив, начиная с заданного элемента и до конца массива (или до его начала в случае отрицательного смеще - ния). Слияние массивов выполняется при помощи функции arraymerge: <?php $fruits = array ("яблоко", "груша", "абрикос"); $vegetables = array ("картошка", "морковка", "свекла"); $produce = array_merge ($fruits, $vegetables); foreach ($produce as $value) { echo "Элемент массива : $value\n"; } ?> В результате будут выведены строки (см. также разд. «Операторы над массивами» ниже): Элемент массива '• яблоко Элемент массива: груша Элемент массива: абрикос Элемент массива: картошка Элемент массива: морковка Элемент массива: свекла
96 \ Глава 3. Строки.и массивы Сравнение массивов В РНР имеются средства для сравнения массивов и нахождения различий в их элементах. Допустим, имеются два массива, в которых совпадает только второй элемент. Для построения массива, в который будут входить только те элементы первого массива, которые отсутствуют во втором, используется функция arraydif f. <?php $local_fruits = array ("яблоко", "гранат", "абрикос"); $tropical_fruits = array ("ананас", "гранат", "папайя"); $difference = array_diff ($local_fruits, $tropical_fruits); foreach ($difference as $key => $value) { echo "Индекс: $key; Значение: $value\n"; } ?> В результате выполнения этого примера будут выведены строки: Индекс: 0; Значение: яблоко Индекс: 2; Значение: абрикос В данном случае сравнивались только значения элементов массива. Если же нужно анализировать еще и индексы, на помощь приходит функция arraydif fassoc (ее название объясняется тем, что массивы со строковыми индексами называются также ассоциативными массивами): <?php $local_fruits = array ("фрукт1" => "яблоко", "фрукт2" => "гранат", "фруктЗ" => "абрикос")г $tropical_fruits = array ("фрукт_1" => "ананас", "фрукт_2" => "гранат", "фрукт_3" => "папайя"); $difference = array_diff_assoc ($local_fruits, $tropical_fruits); foreach ($difference as $key => $value) { echo "Индекс: $key; Значение: $value\n"; } ?> В результате будут выведены строки (следует обратить внимание на то, что полностью совпадающих как по значению, так и по индексу элементов в двух массивах не найдено): Индекс: фрукт1; Значение: яблоко Индекс: фрукт2; Значение: гранат Индекс:' фруктЗ; Значение: абрикос Встречается и обратная задача — найти элементы, которые являются общими для двух массивов. В этом случае используется функция arrayintersect:
Обработка данных в массивах 97 <?php $local_fruits = array ("яблоко", "гранат", "абрикос"); $tropical_fruits = array ("ананас", "гранат", "папайя"); $difference = array_intersect ($local_fruits, $tropical_fruits); 'foreach ($difference as $key => $value) { echo "Индекс: $key; Значение: $value\n"; } ?> В результате будет выведена единственная строчка: Индекс-. 1; Значение: гранат Если же требуется учесть и индексы при определении общих элементов, используется функция arrayintersectassoc: <?php $local_fruits = array ("фрукт1" => "яблоко", "фрукт2" => "гранат", "фруктЗ" => "абрикос"); $tropical_f ruits = array ("фрукт" => "яблоко", "фрукт2" => "гранат", "фруктЗ" => "папайя"); $difference = array_intersect_assoc ($local_fruits, $tropical_fruits); foreach ($difference as $key => $value) { echo "Индекс: $key; Значение: $value\n"; } ?> Результатом выполнения этого примера будет также одна строка (следует обратить внимание, что первые элементы массивов равны по значениям, но не по индексам): Индекс:,фрукт2; Значение: гранат Обработкаданныхвмассивах Данные в массивах могут бьпъ обработаны самыми различными способами, Например, если требуется удалить в массиве элементы с повторяющимися значениями, на помощь приходит функция arrayunique: <?php $scores = array F5, 60, 70, 65, 65) ; printer ($scores); $scores = array_unique ($scores); printr (Sscores); ?> Ниже приведен результат выполнения этого примера — следует обратить внимание на то, что дублирующиеся элементы удалены: 4 РНР в примерах
9j3 Глава 3. Строки и массивы Array ( [0] => 65 [1] => 60 [2] => 70 [3] => 65 [4] => 65 ) Array ( [0] => 65 [1] => 60 [2] => 70 ) Вот еще одна полезная функция для обработки данных — arraysum, которая возвращает сумму всех элементов массива: <?php $scores = array F5, 60, 70, 64, 66) ; echo "Средний балл = ", array sum ($scores) / count ($scores) ; ?> В этом примере вычисляется средний балл экзаменационных оценок студентов: Средний балл = 65 И последний пример обработки данных — функция arrayf I ip меняет местами индексы и значения элементов массива, как показано в примере 3.4. Пример 3.4. Перестановка местами индексов и значений элементов массива, phpflip.php <HTML> <HEAD> <TITLE> Переворот массива </TITLE> </HEAD> <BODY> <H1> Переворот массива </Н1> <?php $local_fruits = array ( "фрукт1" => "яблоко", "фрукт2" = > "груша", "фруктЗ" => "апельсин"); foreach ($local_fruits as $key => $value) { echo "Индекс: $key; Значение: $value<BR>"; }
М(ногомерные массивы 99 echo "<BR>"; $local_fruits = array_flip ($local_fruits); foreach ($local_fruits as $key => $value) { echo "Индекс: $key; Значение: $value<BR>' } ?> </B0DY> </HTML> Результат выполнения примера представлен на рис. 3.4. файл Правка Вид Избранное Сервис Справка АД**^|Щ ^tp://Vxrf<>gJpW03fofpffrD,php *) Переход : Ссьтки Переворот массива Индекс: фрукт 1; Значение: яблоко Индекс: фрукт2; Значение: груша Индекс: фруктЗ; Значение: апельсин Индекс:яблоко; Значение: фрукт1 Индекс: груша; Значение: фрукт2 Ицджс: апельсин; Значение: фруктЗ Рис. 3.4. Перестановка местами индексов и значений элементов массива Многомерные массивы До сих пор рассматривались только одномерные массивы. Но в РНР имеется возможность работы и с многомерными массивами. Пусть для хранения экзаменационных оценок используется одномерный массив Stestscores:
100 Глава 3, Строки и массивы $ test scores ["Иванов"] = 95; $test scores ["Петров"] = 87; Но что если надо хранить оценки по нескольким предметам? Для этого удобно использовать двухмерный массив, например: <?php $test_scores ["Иванов"] [1] = 95 $test_scores ["Иванов"] [2] = 85 $test_scores ["Петров"] [1] = 87 $test_scores ["Петров"] [2] = 93 print_r ( $test_scores ) ; ?> Элемент массива Stestscores ["Иванов"] [1] содержит оценку Иванова по первому предмету, Stestscores ["Иванов"] [2] — по второму предмету и т.д. В результате выполнения предыдущего примера будет выведен созданный многомерный массив: Array ( [Иванов] =>Array ( [1] => 95 [2] => 85 ) [Петров] =>Array ( ) [1] => 87 [2] => 93 ) Доступ к элементу многомерного массива осуществляется путем указания всех его индексов, например: echo "Оценка Иванова по первому предмету : ", $test_scores [ "Иванов"] [1], "\п"; Если требуется заменить элемент массива его значением в строковой константе, ограниченной двойными кавычками, подобно тому, как это делается с обычной переменной, следует заключить элемент массива в фигурные скобки и использовать для строковых индексов одиночные кавычки: echo "Оценка Иванова по первому предмету : ($test_scores['Иванов' ] [1]}\п"; Для создания многомерных массивов можно использовать и сокращенную форму, но следует иметь в виду, что в данном случае нумерация второго индекса начинается с 0: <?php $test_scores ["Иванов"] [] =95 $test_scores ["Иванов"] [] =85 $test_scores ["Петров"] [] =87 $test_scores ["Петров"] [] =93 print_r ( $test_scores ) ; ?>
Многомерные массивы »л_л_л_«л,» л_л»_»._.лл 1Я1 В РНР многомерные массивы можно рассматривать как массивы массивов. Например, двухмерный массив можно рассматривать как одномерный массив, элементами которого в свою очередь также являются одномерные массивы. Пример такого описания приведен ниже: <?php $test_scores = array("Иванов" => array(95, 85), "Петров" => array(87, 93) ) ; print_r($test_scores); ?> В результате будет создан следующий массив: Array ( [Иванов] => Array ( [0] =>95 - [1] =>85 ) [Петров] => Array ( [0] =>87 [1] =>93 ) ) Если требуется начать нумерацию второго индекса с 1, используется уже известный синтаксис: <?php $test_scores = array ("Иванов" => array A => 95, 85) , "Петров" => array A => 87, 93) ) ; print_r($test_scores) ; ?> В результате будет создан массив следующего вида: Array ( [Иванов] => Array ( [1]=>95 [2]=>85 ) [Петров] => Array ( [1]=>87 [2]=>93 ) )
102 _____ Глава". Строки и массивы Многомерныемассивыициклы Часто возникает необходимость перебрать все элементы многомерного массива в цикле. Для этого используются вложенные циклы. Например, для случая двухмерного массива внешний цикл перебирает первый индекс массива, а внутренний цикл перебирает второй индекс. Пример вложенных циклов приведен ниже. <?php $test_scores $test_scores $test_scores $test_scores for ($outer_ [0] [] [0] [] [1] [] [1] [] index = = 95 = 85 = 87 = 93 0; $outer_index < count ($test_scores); $outer_index++) { for ($inner_index = 0; $inner_index < count ($test_scores [$outer_index]); $inner_index++) { echo "\$test_scores [$outer_index] [$inner_index] = ", $test_scores[$outer_index] [$inner_index] , "\n"; } } ?> В результате выполнения этого кода будет выведен весь исходный двухмерный массив: $test scores [О] [О] = 95 $test scores [О] [1] = 85 $test scores [1] [О] = 87 $test scores [1] [1] = 93 Для этой же цели могут использоваться циклы foreach, а для случая строковых индексов это наилучший способ, так как строковые индексы нельзя увеличивать оператором + + . В примере 3.5 при каждом выполнении тела внешнего цикла из исходного массива извлекается одномерный массив, соответствующий значению счетчика цикла. Пример 3.5. Цикл по всем элементам двухмерного массива, phpmultidimensional.php <HTML> <HEAD> <TITLE> Цикл по всем элементам двухмерного массива </TITLE> </HEAD> <BODY> <Н1> Цикл по всем элементам двухмерного массива </Н1>
Многомерные массивы и циклы 103 <?php $test_scores ["Иванов"]["первый"] = 95, $test_scores ["Иванов"]["второй"] = 85, $test_scores [ "Петров"] ["первый"] = 87, $test_scores ["Петров"]["второй"] = 93, foreach ($test_scores as $outer_key => $single_array) { $value<BR>" ; } } ?> </B0DY> </HTML> foreach ($single_array as $inner_key => $value) { echo "\$test_scores [$outer_key][$inner_key] Результат выполнения примера представлен на рис . 3.5. ю. всем элементам двухмерного массива ■ soft Internet Explorer файл Правка Вид избранное Сервис ^правка фнадд -. €> . Ш Ш |й уШ-нс. #Ч£ршЕ4&1& Ш ' Адреса N5ehttp://localhoEt/php/03/phpmultJdJmensJonal.php '^Ш В ПвРвх°Л : сСы.п Цикл по всем элементам двухмерного массива Stestscores [Иванов] [первый] = 95 Stestscores [Иванов] [второй] = 85 Stestscores [Петров] [щзвый] = 87 Stestscores [Петров] [второй] = 93 Рис. 3.5. Цикл по всем элементам двухмерного массива
104 Глава 3. Строки и массивы Операторы над массивами Кроме разнообразных функций, над массивами можно производить действия при помощи следующих операторов: $а + $Ь Объединение Объединение массивов $ а и $Ь. са gb p TRUE, если $а и $Ь содержат одни ите же — а в н о элементы. Sa = Sb ТоЖдественно равно TRUE, если $а и $Ь содержат одни и те же элементы в том же самом порядке. $а != $Ь Неравно TRUE, если массив $а не равен массиву $Ь. $а О $Ь Неравно TRUE, если массив $а не равен массиву $Ь. 4, , ,к m TRUE, если массив $а не равен тождества !— go Тождественно не равно *, венно массиву $Ь. Большинство операторов занимаются сравнением массивов, но оператор + предназначен для их конкатенации. В примере показано использование операторов + и==. ПримерЗ. 6. Примериспользованияоператоров смассивами, phparrayops.php <HTML> <HEAD> <TITLE> Операторы над массивами </ТТТЬЕ> </HEAD> <BODY> <Н1> Операторы над массивами </Н1> <?php $fruits ["яблоки"] = 3839; $ fruits ["апельсины"] = 22 89; $vegetables ["картошка"] = 1991; $vegetables ["морковка"] = 9195; echo "\$fruits: "; print_r ($fruits); echo "<BR>"; echo " \$vegetables: "; print_r ($vegetables); echo "<BR>"; $produce = $£ruits + $vegetables; echo "\$produce: "; print_r ($produce); echo "<BR>";
Операторы над массивами 105 if ($£ruits ==' $vegetables) { echo "Массив \$fruits равен массиву \$vegetables<BR>" } else { echo "Массив \$fruits не равен массиву \$vegetables<BR>"; } ?> </B0DY> </HTMI> Результат выполнения примера представлен на рис. 3.6. файл Правка Вод Избранное Сервис Справка Qntsu * йдвос-jjfil hBr>:ffloc«hofl/pftrt03fpftparriYOp».ptv €>Ш s ш Ссыют Операторы над массивами Sfruits: Array ([яблоки] => 3839 [апельсины] => 2289) Svegetables: Array ([картошка] => 1991 [морковка] => 9195) Sproduce: Array ([яблоки] => 3839 [апельсины] => 2289 [картошка] => 1991 [морковка] => 9195 ) Массив Sfruits не равен массиву Svegetables Рис .3.6. Пример использования операторов с массивами
Итоги В РНР предусмотрены богатые возможности по работе со строками и массивами. Для обоих типов данных предусмотрено большое количество функций. Ниже перечислены краткие итоги главы: • В РНР имеется достаточное количество функций для обработки строк, наиболее важные из которых сведены в табл. 3.1. • Функции print f и sprintf предназначены для форматированного вывода переменных и выражений различных типов. • Функция s t r s t r предназначена для поиска заданной подстроки в строке. • Функция substrcompare предназначена для сравнения строк. • Массивы — регулярные структуры данных, в которых каждый элемент соответствует определенному значению числового или строкового индекса. • Синтаксически элемент массива задается при помощи квадратных скобок после его идентификатора. • Функция unset предназначена для удаления переменных и элементов массива. • Цикл foreach предназначен для перебора всех элементов заданного массива. • Разнообразные функции по обработке массивов приведены в табл. 3.2. • Сортировка массивов выполняется при помощи семейства функций sort. • Преобразование между строками и массивами и обратно осуществляется при помощи функций implode и explode соответственно. • Функция arraydiff формирует массив, содержащий различия между заданными массивами. • Кроме одномерных, имеется возможность работы с многомерными массивами.
Глава 4 Функции В предыдущих главах рассматривались базовые кирпичики программирования — простые переменные, константы, массивы, в том числе и многомерные. Настало время перейти к структурному построению приложений. Как уже неоднократно упоминалось, в РНР имеется большое количество встроенных функций, решающих самые разнообразные задачи. В данной главе речь пойдет о создании собственных функций. Как и в других языках программирования, функция представляет собой набор операторов, который идентифицируется определенным именем. По мере роста размера приложения возможность создания функций становится все более и более востребованной, так как разбиение кода на отдельные фрагменты повышает его прозрачность и структурность. Если скрипт содержит более двух десятков строк кода, имеет смысл подумать о разбиении его на отдельные функции. Использование функций также значительно облегчает процесс отладки. Если ошибка возникла в скрипте из двух тысяч строк, процесс ее нахождения может стать весьма затруднительным. Но если код разбит на отдельные функции, они могут быть отлажены в индивидуальном порядке, что радикально сокращает трудоемкость тестирования. Функции также ограничивают область действия переменных. Если в скрипте из двух тысяч строк в начале используется переменная с распространенным именем Scounter, может получиться так, что в конце она уже будет использована совершенно для других целей, что неминуемо приведет к возникновению ошибки на стадии выполнения. При использовании функций все переменные, создаваемые в ее теле, являются по умолчанию локальными и не доступны извне функции. Таким образом одни и те же имена переменных могут быть использованы внутри различных функций, и это не приведет к возникновению ошибок. Итак, перейдем к созданию собственных функций. Создание функции Как же создавать свои собственные функции? Ниже приведен формальный синтаксис описания функции:
108 Глава 4, Функции function function name {[argument list... ]) { [statements;] [return return value;] } Рассмотрим создание функции на примере. Пусть требуется для нескольких web-страниц создать панель навигации, содержащую набор гиперссылок. Вместо того чтобы включать необходимый код в каждый скрипт, генерирующий страницу, можно один описать соответствующую функцию, которая может быть вызвана из любого необходимого места. Путь такая функция называться navbar: function nav_bar () { } Чтобы создать панель навигации, используется стандартная функция echo, которая формирует необходимые теги HTML и соответствующий текст (обозначение &nbsp; в HTML формирует так называемый неразрывный пробел, который не разрывается при выравнивании строк): function nav_bar ($text, $copyright) { echo "<hr>"; echo "<center>"; echo "<a href='home.htmr>floMofi</a>&nbsp;&nbsp;&nbsp;"; echo "<a href='map.html'>Карта can,Ta</a>&nbsp;&nbsp;&nbsp;"; echo "<a href='help.html'>Помощь</а>"; echo "<hr>"; echo "</center>"; } Теперь каждый раз при вызове данной функции будет формироваться панель навигации. Использование функции имеет еще одно преимущество — теперь для внесения изменений в внешний вид панели требуется изменить код только в одном месте, а не редактировать множество файлов. Пример 4.1 Демонстрирует вызов функции navbar. Пример4.1. Вызовфункции, phpnavbar.php <HTML> <HEAD> <TITLE> Вызов функции </TITLE> </HEAD> <B0DY> <Hl> Вызов функции </Н1> <?php echo "<НЗ>Добро пожаловать!</H3>"; echo "<br>";
1£аадаиие.;.,&.улл1ши.., ,09 echo "Для навигации используйте ссылки"; echo "<br>"; echo "<br>"; nav_bar (); function nav_bar () { echo "<hr>"; echo "<center>"; echo "<a href='home.html'>flOMOft</a>&nbsp;&r±>sp;&nbsp;" ; echo "<a href='map.htmr>KapTa cairra</a>&nbsp;&nbsp;&nbsp;"; echo "<a href='help.htmr>IIoMoiiib</a>"; echo "</center>"; } ?> </BODY> </HTML> На рис. 4.1 показана панель навигации, расположенная в нижней части web-страницы. Теперь для ее создания достаточно просто вызвать функцию nav_bar. ШИН Дайя Вивка В«и Иэбрмюе Соршс Оправка Адрусг] jjfa http://1ocalhosyphp/04/phpnavbar.php Г | £ J Пареадд ; Ш яки '■■ Вызов функции Добро пожаловать! Дпя навигации используйте ссылки Домой Карта сайта Помощь Рис. 4.1. Панель навигации, созданная функцией
110 Глава 4. Функции Следует обратить внимание на главную особенность функций — их код выполняется не в момент описания функции, а в момент ее вызова из другого участка скрипта. Передача данных в функцию Функция может использовать данные, переданные ей при вызове. Для этого используется список аргументов функции, который представляет собой их перечисление через запятую: function function name {largumentliet...]) { [statements;] [return return value;] } Это механизм работает следующим образом. Предположим, требуется дополнить панель навигации из предыдущего раздела некоторым текстом и сведениями об авторских правах (копирайтом). Этого можно достичь путем передачи в функцию двух аргументов. Пусть они называются $name и Scopyright, тогда строка описания функции будет выглядеть следующим образом: function nav_bar ($text, $copyright) { } После такого описания эти аргументы можно использовать в теле функции как простые переменные: function nav_bar ($text, $copyright) echo "<hr>"; echo "<БОУГ SIZE=1l1>$text</Ix/FONT>"; echo "<BRxF0NT SIZE= ' 1' >$copyright</Ix/FONT>" ; echo "</center>"; } В примере 4.2 использован вызов модифицированной функции, которой в качестве аргументов передаются две строковых константы. Пример 4.2. Вызов функции с аргументами, phpcustomnavbar.php <HTML> <HEAD> <Т1ТЬЕ>Функция с аргументами</Т1ТЬЕ> </HEAD> <B0DY> <Н1>Функция с аргументами/Rl> <?php echo "<НЗ>Добро пожаловать !</НЗ>"; echo "<br>";
Передача данных в функцию 111 echo "Для навигации используйте ссылки"; echo "<br>"; echo "<br>"; nav_bar(00 'СуперПуперСайты'", "(С) 2 006"); function nav_bar ($text, $copyright) { echo "<hr>"; echo "<center>"; echo "<ahref ='home.html'>floMoft</a>&nbsp;&nbsp;&nbsp,-"; echo "<ahref='map. html'Жарта caOT?a</a>&nbsp;&nbsp;&nbsp;"; echo "<a href='help.html'>Помощь</а>"; echo "<hr>"; echo "<F0NT SIZE= ' 3 ' >$text</Ix/FONT> echo "<BRxF0NT SIZE= ' 3 ' >$copyright</Ix/FONT> "; echo "</center>"; } ?> </BODY> </HTML> На рис. 4.2 представлена улучшенная панель навигации. файл Правка Вид Избранное Сервис ".правка АДР*С1]<Щ http://localhost/php/04/phpcustomnavbar.php | Д-П^ремаД ■ ■ £а Функция с аргументами Добро пожаловать ! Для навигации используйте ссылки ДОМОН Карта сайта Помощь ООО 'СуперПуперСайты' " (С) 2006 Рис. 4.2. Улучшенная панель навигации
112 Глава 4. Функции Передача массивов в функцию Наряду с обыкновенными переменными, в качестве аргументов функции можно использовать и массивы. При этом никаких специальных описаний использовать не требуется. Ниже приведен пример функции arrayechoer, которая просто отображает содержимое массива, переданного ей в качестве единственного аргумента: <?php function array_echoer ($array) { for ($index = 0; $index < count ($array) ; $index++) { echo "Элемент $index: ", $array [$ index] , "\n"; } } $fruits [0] = "яблоко"; $fruits [1] = "груша"; $ fruits [2] = "апельсин"; $fruits [3] = "мандарин"; array_echoer (Sfruits); ?> Результат исполнения этого фрагмента кода приведен ниже: Элемент 0: яблоко Элемент 1: груша Элемент 2: апельсин Элемент 3 : мандарин Другой пример демонстрирует вычисление среднего балла по группе студентов: <?php function array_averager($scores) { $total = 0; for ($index = 0; $index < count ($scores) ; $index++) { $total += $scores [$index]; } echo "Средний балл = ", $total / count($scores); } $test scores [0] = 4; $test scores [1] = 5; $test scores [2] = 3; $test scores [3] = 4; array averager ($test scores); ?> После использования данного фрагмента будет отображена следующая строка: Средний балл = 4
Значения аргументов по умолчанию 1_1_3 Значения аргументов по умолчанию В предыдущем разделе было показано, как передавать данные в функцию через ее аргументы. Например, следующая функция просто отображает переданную ей строку: function greeting($text) { echo Stext, "\n"; } greeting ("С добрым утром!"); Такую функцию можно по ошибке вызвать без указания аргумента: greeting (); В этом случае будет выведено сообщение об ошибке: PHP Warning: Missing argument 1 for greeting() in C:\php\test.php on line 5 Для того, чтобы избежать подобной ситуации, аргументу функции можно присвоить значение по умолчанию, которое будет использоваться, если при вызове аргумент не задан. Это достигается при помощи знака = и указания соответствующего значения: <? function greeting ($text = "Хорошая погода") { echo $text, "\n"; } greeting () ; ? > . Данный фрагмент кода отобразит следующий текст: Хорошая погода Если аргумент функции задан в явной форме, значение по умолчанию не используется. Значение по умолчанию может бьпъ задано больше чем для одного аргумента, но после того, как оно будет задано для одного из них, оно должно быть задано и для всех последующих аргументов до конца списка, чтобы исключить неоднозначность, если какой-либо из аргументов будет опущен. Ниже приведен пример подобной функции: function greeting ($textl, $text2 = "Без ", $text = "паники.") { echo Stextl, $text2, $text3, "\n"; } Пример 4.3 демонстрирует использование значений аргументов функции по умолчанию. Пример предназначен для бронирования кают на круизном лайнере, по умолчанию бронируется двухместная каюта класса люкс.
114 Глава 4, Функции Пример4.3. Вызов функции созначениямипоумолчанию, phpdefault.php <HTML> <HEAD> <TITLE> Значения по умолчанию </TITLE> </HEAD> <BODY> <Н1>Значения по умолчанию</Н1> <Н2>Добро пожаловать в круиз!</Н2> <?php function book ($name, $number = 2, $deluxe = TRUE) { echo "Добро пожаловать, $name, вам зарезервировано $number». " мест"; if ($deluxe) echo " в каюте класса люкс.<ВК>"; else echo " в стандартной каюте.<BR>"; } book ("Иван"); book ("Петр", 1 ) ; book ("Мария", 4, FALSE); ?> </B0DY> </HTML> файл Правка &нд избранное Сервис Справка П о и (х л </-■-" ■ 0 ■ й И *й>1ЯПои,х л '**"«* «М ЛЩ f 7 Щ EJ Переход -V Севши Значенияпоумолчанию Добро пожаловать в круп^! Добро пожаловать, Иван, вамзарезервировано2мествкаютеклассалюкс. Добро пожаловать, Петр, вамзарелвировано1меств каюте классалюкс. Добро пожаловать, Мария, вамзарезервировано4мествстандартнойкаюте. Рис. 4.3. Использование значений поумолчанию
Передача аргумента по ссылке 115 На рис. 4.3 видно, что явное задание аргумента функции перекрывает значение по умолчанию. Передача аргумента по ссылке Обычно передача аргумента функции осуществляется по значению. Это означает, что в функцию передается копия данных, а не сами данные. Если аргумент функции изменяется внутри тела функции, это не оказывает никакого влияния на значения переменных за ее пределами. Зачастую возникает необходимость в том, чтобы функция могла возвращать измененное значение переменной, переданной ей в качестве аргумента. К примеру, требуется разработать функцию, которая добавляет к переданной ей переменной строку и возвращает результат через ту же переменную. Соответствующий код должен был бы выглядеть следующим образом: <?php function add_text( Stext) { Stext .= "прекрасна"; } Sstring = "Жизнь "; addtext (Sstring); echo Sstring; ?> Но при запуске этого примера будет выведена только строка «Жизнь», так как по умолчанию аргументы передаются по значению. Исправить эту ошибку можно при помощи единственного символа, который определяет передачу аргумента функции по ссылке. Таким символом является амперсанд (&): <?php function add_text (& $ text) { Stext .= "прекрасна"; } Sstring = "Жизнь "; addtext (Sstring); echo Sstring; ?> В данном примере в функцию передается ссылка на аргумент — переменную Sstring. Это означает, что при обращении внутри функции к переменной Stext на самом деле происходит обращение к переменной S string. Таким образом, изменения, сделанные в теле функции, распространяются на данные основного скрипта. Это демонстрирует пример 4.4.
116 Глава4. Функции Пример4.4.Передачааргументовпоссылке,рЬрЬуге^рЬр ДЯДИН» Q4'JLHUPPl1VH <HTML> <HEAD> <TITLE> Передача данных по ссылке </TITLE> </HEAD> <BODY> <Н1> Передача данных по ссылке </Н1> <?php function add_text (&$text) { $text .= "паники!"; } $string = "Без "; add_text ($string); echo $string; ?> </BODY> </HTML> 1ередача данных по ссылке файл Правка Вид Избранное Сервис "правка О1-"-*-- о Ш Ш S|J>:,PnoMCK -"Избранное 4&) \ %t 1Э Дцрес_ Щ http://localhosl/php/04/pripbyreF.prip Г0?*^°ЭД::^^ Передача данных по ссылке Без паники! Рис. 4.4. Передача аргументов по ссылке
Функции с переменным количеством аргументов 117 Как видно из рис. 4.4, значение переменной, переданной по ссылке, изменено внутри функции. При передаче данных по ссылке следует соблюдать осторожность, так как при неаккуратном использовании этой возможности можно внести в код программы трудно обнаружимую ошибку. Именно поэтому по умолчанию принята передача данных по значению. Функции с переменным количеством аргументов Все функции, которые были разработаны ранее, имели фиксированное количество аргументов. Но в РНР предусмотрена возможность работы с функциями, которые имеют переменное количество аргументов. Это не то же самое, что использование значений аргументов по умолчанию, речь идет о том, что функция может быть вызвана с разным количеством аргументов, каждый из которых может быть проанализирован при помощи специализированных функций. При этом функция может быть вызвана с таким количеством аргументов, с каким потребуется. Например, требуется разработать функцию, которая отображает конкатенацию всех переданных ей строк. Вызываться эта функция под названием joiner будет, например, следующим образом: joiner ("Без", "паники") ; joiner ("Сегодня", "хорошая", "погода."); joiner ("Просто", "очень", "длинная", "строка."); Для обработки переменного списка аргументов в РНР предусмотрены следующие три функции: • funcnumargs. Возвращает количество аргументов функции. • funcgetarg. Возвращает заданный аргумент функции. • funcgetargs. Возвращает все аргументы функции в виде массива. В примере 4.5 для реализации функции joiner используются две из этих функций. При помощи функции funcnumargs определяется количество аргументов, переданных при данном вызове функции, а при помощи функции funcgetargs из аргументов формируется массив, элементы которого последовательно обрабатываются в цикле. Пример4.5. Переменное числоаргументовфункции, phpvariableargs.php <HTML> <HEAD> <ТТТЬЕ> Функции с переменным числом аргументов </ТТТЬВ> </HEAD> <BODY> <Hl> Функции с переменным числом аргументов </Н1>
118 ___ _ Г-л^ 4 . Функции^ <?php function joiner () { $text = " "; $arg list = func get args (); for ($loop index = 0; $ loop index < func num args (); $loop index++) { $text .= $arg list Г$1оор indexl . " "; } return $text; } echo "joiner (\»Без\", \"паники.\") = ", joiner ("Без", "паники. " ) , "<BR>" ; echo "joiner (\"He\", \"стоит\", \"волноваться.\") = ", joiner ("He", "стоит", "волноваться."), "<BR>"; echo "joiner (\"Это\", \"совсем\", \"длинная\", \"строка. \") = ", joiner ("Это", "совсем", "длинная", "строка."), ,,<BR>"; ?> </BODY> </HTML> На рис. 4.5 представлен результат выполнения этого примера. Видно, что все переданные функции j oiner аргументы корректно обработаны. £айп Правка Ыд Избранное Сервис Справка есарес", |" http://localhost/php/04/phpvarjableargs.php щщ^т: Функцииспеременнымчислом аргументов joiner ("Без", "паники.") = Без паники. joiner ("He", "стоит", "волноваться.") = Не стоит волноваться. joiner ("Это", "совсем", "длинная", "строка.") = Это совсем длинная строка. http ://all -ebooks. com Рис. 4.5. Обработка переменного числа аргументов
Функции",возвращающие значение лл л_^^_л ^л 119 Для получения конкретного аргумента функции может быть также использована функция funcgetarg. Ей надо передать номер аргумента (нумерация начинается с 0), и она вернет его значения в качестве результата. Функции, возвращающие значение Большинство встроенных функций в РНР возвращают какое-либо значение в качестве результата. Несмотря на то, что это свойство широко использовалось в предыдущих главах, до сих пор все разработанные функции не возвращали никаких значений. Пришло время исправить этот недостаток. Для возврата значения из функции используется оператор return, синтаксис которого представлен ниже: return {value) ; Скобки, которые делают оператор return похожим на функцию, являются необязательными. Ниже приведен пример функции square для вычисления квадрата заданного числа: <?рпр function square ($value) { return $value * $value; } ?> После того, как данная функция описана1, ее можно использовать так же, как и любую другую встроенную функцию РНР: <?рпр function square ($value) { return $value * $value; } echo 6 x 16 = ", square A6), "."; ?> В результате выполнения данного кода будет отображена следующая строка: 16 х 16 = 256. Функция может возвращать значения любого типа, например, логического. Ниже приведен пример функции, предназначенной для проверки комфортности температуры воздуха2. Функция возвращает значение TRUE в случае хорошей погоды и FALSE в противоположном случае. Соответствующий фрагмент кода выглядит следующим образом: Р HP допускает вызов функции до ее описания при условии, что она описана в теле скрипта ниже. Но использование этой возможности затрудняет анализ исходного текста и не рекомендуется. — Прим. ред. Не стоит воспринимать приведенные значения температур буквально, это всего лишь личная точка зрения автора. — Прим. ред.
120 Глава 4. Функции <?php function check_temperature ($temperature) { $return_value = FALSE; if ($temperature > 24 && $temperature < 26) { Sreturnvalue = TRUE; } return $ return value; } $degrees = 2 5; if (check_temperature ($degrees)) { echo "Хорошая погода."; } else { echo "Плохая погода."; ?> Результатом запуска этого скрипта является отображение следующей строки: Хорошая погода. Функция может содержать более одного оператора return. При этом выполнение оператора приводит к немедленному завершению обработки функции и возврату соответствующего результата в ту точку, где она была вызвана. Пре- дьщущий пример может быть переписан с использованием двух операторов return: <?php function check temperature ($temperature) { if ({temperature > 24 && {temperature < 26) { return TRUE; } return FALSE; } {degrees = 25; if (check temperature ($degrees)) { echo "Хорошая погода. " ; } else { echo "Плохая погода."; } ?> При выполнении этого примера результат будет точно такой же, как и в предыдущем случае.
звращающая массив 121 Функция, возвращающая массив Функция может вернуть в качестве своего результата не только скалярное значение, но и целый массив. Для этого используется тот же самый оператор return, описанный в предыдущем разделе. Например, требуется разработать функцию, которая удваивает элементы массива, переданного ей в качестве единственного аргумента: function array_doubler ($arr) { } В теле функции осуществляется циклическая обработка элементов массива, которая состоит в том, что их значения удваиваются и помещаются на прежнее место: function array_doubler ($arr) { for ($loop_index =0; $loop_index < count ($arr); $loop_index++) { $arr t$loop_index] *= 2; } Наконец, преобразованный массив возвращается как результат выполнения функции: function array_doubler ($arr) { for ($loop_index = 0; $loop_index < count ($arr); $loop_index+ +) { $arr [$loop_index] *= 2; } return $arr; Пример 4.6 демонстрирует использование функции arraydoubler. Пример4.6. Функция, возвращающая массив, phpdoubler.php <HTML> <HEAD> <TITLE> Функция, возвращающая массив </TITLE> </HEAD> <BODY> <Hl> Функция, возвращающая массив
122 Глава 4. Функции </Н1> < ?php function array_doubler ($arr) { for ($loop_index = 0; $loop_index < count ($arr) ; $loop_index++) { } $arr [$loop_index] *= 2; return $arr; } $array = array A, 2, 3, 4, 5, 6); $array = array_doubler ($array); } ?> </BODY> </HTML> echo "Удвоение значений элементов массива<ВИ>"; foreach ($array as $value) { echo "Значение: $value<BR>"; файл [Травка Вид избранное # г к 3 А 0 ' Й Ш Сервис Справка Л ; ХЭ ГЬос "Избранное Afipec:j"http;//localhosyphp/04;phpdoubler.php Функция, <э %ш возвращающая Удвоение значений элементов массива Значение: 2 Значение: 4 Значение: б Значение: 8 Значение: 10 Значение: 12 ™Й''Влч1»»ьА-. массив . .*■ ■ Сшмм _.* ■V: Рис. 4.6. Удвоение элементов массива На рис. 4.6 представлен результат выполнения примера. В качестве исходного массива были взяты первые шесть натуральных чисел.
Использование списков 123 Использование списков Использование функции, которая возвращает массив данных, является одним из способов передачи нескольких значений из функции. Существует модификация этого способа, при котором используется списки переменных. Для описания списка переменных применяется системная функция list, осуществляющая присвоение перечисленным при ее вызове переменным значений элементов массива. Для демонстрации использования этой функции взята функция arraydoubler из предыдущего раздела, которая удваивает значения элементов массива. Пусть требуется присвоить первые шесть элементов удвоенного массива переменным $ first, Ssecond, SthirdHT. д. Этого можно достичь при помощи конструкции следующего вида: list ($first, $second, $third, $fourth, $fifth, $sixth) = array_doubler ($array); Пример 4.7 демонстрирует использование данного способа. Таким образом можно осуществить передачу из функции нескольких значений. Альтернативой служит передача аргумента по ссылке (см. соответствующий раздел выше). Пример4.7. Hcnonb3OBaHne0yHKi4nnlist,phplist.php <HTML> <HEAD> <TITLE> Использование функции list </TITLE> </HEAD> <BODY> <H1> Использование функции list </Hl> <?php function array_doubler ($arr) { for ($loop_index = 0; $loop_index < count ($arr); $loop_index+ +) { $arr [$loop_index] *= 2; } return $arr; } $array = array A, 2, 3, 4, 5, 6); list ($first, $second, $third, $fourth, $fifth, $sixth) = array_doubler ($array); echo "\$£irst: $first<BR>"; echo "\$second: $second<BR>"; echo "\$third: $third<BR>"; echo "\$fourth: $£ourth<BR>"; echo "\$fifth: $fifth<BR>"; echo "\$sixth: $sixth<BR>";
124 Глава 4. Функции </BODY> </HTML> Рис. 4.7 показывает, что значения переменным присвоены корректно. 5 Использование функции list - Microsoft Internet Explorer Файл Правка бил избранное Сервис Справка фнзЛд - © ■" Э [Ц ^Н /5"-Л "Избраг+ное 0| ^ @ <Ц http^localhcdfahpflH/phtifet.php ЩЙ!1'**''0* '.'!'b«W*': Использование функции list Sfust: 2 Ssecond: 4 Sthird; 6 Sfourth: 8 Sfiftli: 10 Ssixth: 12 Рис. 4.7. Использование списков В том случае, если требуется использовать только первые три элемента массива для присвоения их значений переменным, соответствующий оператор выглядит следующим образом (лишние элементы массива, который возвращает функция, просто игнорируются): list ($first, $second, $third) = array_doubler ($array); echo "\$first: $first\n"; echo "\$second: $second\n"; echo "\$third: $third\n"; Следует обратить внимание на то, что использование функции list для формирования массива некорректно. Следующий фрагмент кода является ошибочным: return list ($arr[0J, $агг[1], $arr[2], $arr[3], $arr[4], $arr[5]);
Функция, возвращающая ссылки 125 Функция, возвращающая ссылки Помимо передачи аргументов функции по ссылке имеется возможность вернуть ссылку как результат вызова функции. Это может быть необходимо при дальнейшем использовании ссылок в коде программы. Данная технология применяется достаточно редко и требует особой аккуратности. Ссылка указывает на то же место в памяти, которое занимает исходная переменная. Для создания ссылки используется оператор &: $value = 5 ; $ref = &$value; Теперь $ref является ссылкой на переменную Svalue. Изменение значения ссылки немедленно отражается на значении исходной переменной. Для описания функции, которая возвращает ссылку как результат своего вызова, также используется символ &. Пусть требуется разработать простейшую функцию, которая просто возвращает ссылку на переданную ей в качестве аргумента переменную. Для этого аргумент тоже следует передавать по ссылке: function &return_a_reference (&$reference) { return $ reference; } Следует обратить внимание на то, что символ & в описании функции использован дважды. При вызове функции, возвращающей ссылку, следует также использовать оператор &. Ниже приведен пример, который присваивает переменной $ref ссылку на переменную Svalue и увеличивает значение ссылки, изменяя этим также и значение исходной переменной: $value = 5; echo "Старое значение: ", $value, "\n"; $ref = & return_a_reference ($value); $ref++; echo "Новое значение: ", $value, "\n"; В результате выполнения этого фрагмента будут отображены следующие строки: Старое значение: 5 Новое значение: б Локальные переменные Как рассказывалось выше, областью действия переменной называется та часть кода, в которой сохраняется ее значение. Область действия приобретает важное значение при использовании функций. В скриптах, не содержащих функций, областью действия является весь скрипт целиком. Например, если переменная была один раз использована в начале скрипта, то ее значение будет сохраняться до конца скрипта или до тех пор, пока оно не будет изменено в результате другого оператора присваивания. В нижеследующем фрагменте кода оба раза речь идет об одной и той же переменной $ count:
126 Глава 4. Функции <?php SCOUnt = 1; $count = 55; ?> Если скрипт является достаточно длинным и разрабатывается продолжительное время, легко сделать ошибку и использовать одно и то же имя переменной для разных применений, что неминуемо приведет к конфликту при выполнении программы. Ошибки такого рода (особенно если совпадает тип использованных значений) обнаружить достаточно затруднительно. При использовании функций область действия всех переменных, описанных внутри функции, ограничена этой функцией. Это позволяет использовать одни и те же названия в разных функциях, не опасаясь того, что они начнут конфликтовать. Все локальные переменные уничтожаются при возврате управления из функции. Пример 4.8 демонстрирует использование локальных переменных. В основном скрипте осуществляется присвоение значения переменной $ value. Такое же присвоение осуществляется внутри функции locals соре, но на самом деле оно относится к другой, одноименной переменной. При выходе из функции ее локальная переменная исчезает, но переменная, описанная в основном скрипте, сохраняет свое первоначальное значение. Пример 4.8. Локальные переменные, phpscope.php <HTML> <HEAD> <TITLE> Локальные переменные </TITLE> </HEAD> <BODY> <H1> Локальные переменные </Н1> <?php function local_scope() { $value = 1000000; echo "Внутри функции \$value = ", $value,""<BR>"' } $value = 5 ; echo «В теле скрипта \$value = ", $value, "<BR>"; local_scope() ; echo Три этом в теле скрипта все еще \$value = " , $value, "<BR> ; ?> </BODY> </HTML>
Глобальные переменные 127 Рис. 4.8 демонстрирует использование локальной переменной и сохранение значения переменной $value в основном скрипте. Э Локальные! >айл Правка §ид Избранное Сервис Справка фк»« - О - jj| lU UJpnoHCK «Пяфное #} f ta ре cij "http://localhost/php/04/phpscope.php . JV* | "-Переход Ссылки Локальные переменные В тане скрипта Svalue = 5 Внутри функции Svalue = 1000000 При этом в теле скрипта все еще Svalue = 5 Рис. 4.8. Использование локальной переменной Глобальные переменные Локальные переменные ограничены той функцией, в рамках которой они используются. При этом переменные, описанные в основном скрипте (они называются глобальными), для функции являются недоступными. В отличие от некоторых других языков программирования, в РНР такой доступ по умолчанию запрещен, чтобы избежать конфликтов локальных и глобальных данных. Чтобы получить доступ к глобальным переменным, должно использоваться их явное описание при помощи оператора global. Пример 4.9 демонстрирует использование как локальных, так и глобальных переменных.
128 Глава 4. Функции Пример 4.9. Глобальные и локальные переменные, phpglobal.php <HTML> <HEAD> , <TITLE> Глобальные и локальные переменные </TITLE> </HEAD> <BODY> <Н1> Глобальные и локальные .переменные </Н1> < ?php function local_scope () { $value =1000000; echo "Внутри функции \$value = ", $value, "<BR>"; } function global_scope () { global $value; echo "Внутри функции глобальная переменная \$value = " , $value, "<BR>"; } $value = 5; echo "В теле.скрипта \$value = ", $value, "<BR>"; local_scope (); global_scope (); echo "В теле скрипта все еце \$value = ", $value, "<BR>"; ?> . </BODY> </HTTylL> ' Из примера 4.9 видно, что после использования оператора global значение переменной $value стало доступно внутри функции global_scope. Вместо использования оператора global доступ к глобальным переменным можно получить при помощи специального суперглобального массива SGLOBALS, как показано в следующем фрагменте кода: function global_scope () { echo "Внутри функции глобальная переменная \$value .= ", $GLOBALS ["value"], "<BR>"; }
Статические переменные 129 файл Правка Вед йэбражое Сервис Справка ^■%. . . . .-■'■ '-'Л ГА .,.■/, ■ .-■. *,■ ■■.■■■■-. -i J j f j j t '<.■' ' .'■-"■■" •■""■•;-'',4l/lK"ff(Acx;*ost(php@<t(phpg local php nternet Expteref ■0 ! Pfc'ifiki * V' i £sj Перевод Глобальные и локальные переменные В теле скрипта Svalue = 5 Внутри функции Svalue = 1000000 Внутри функции глобальная переменная Svahie = 5 В теле скрипта все еще Svalue = 5 Рис. 4.9. Использование глобальной переменной Статические переменные Следует иметь в виду, что локальные переменные в функциях инициализируются при каждом ее запуске. Между вызовами функции значения локальных переменных не сохраняются. Это демонстрирует пример 4.10, в котором делается попытка использовать функцию trackcount для увеличения значения внутреннего счетчика. Пример4.10. Попытка создания счетчика, phpstaticO.php <HTML> <HEAD> <TITLE> Статические переменные </TITLE> </HEAD> <BODY> <H1> Статические переменные </Н1> <?php 5 PHP в примерах
130 .НГлава. Функции function track_count (,) Scounter = 0 ,- $counter++; return Scounter; ?> </BODY> /HTML> echo echo echo echo echo "Значение "Значение "Значение "Значение "Значение счетчика счетчика счетчика счетчика счетчика " , track_ ", track_ ", track_ ", track_ ", track_ jcount ( _count ( _count ( _count ( _count ( , "<BR> , "<BR> , "<BR> , "<BR> , "<BR> VIVMKUIv^ Как видно из рис.4.10, попытка создания счетчика оказалась неудачной, так как значение переменной Scounter теряется после каждого возврата из функции. файл Правка | иа Избранное Сервис Справка 0Л «Ф • ШШ5и Р"»" ^?***- €>! & Алрес: )Щ http://locaJhc3sVphp/04/phpstatic0.php ..'*§ О Переход ; Ссыпки Статические переменные Значение счетчика: 1 Значениесчетчгжа: 1 Значение счетчика: 1 Значение счетчика: 1 Значение счетчика: 1 Рис. 4.10. Неработающий счетчиквызовов Для решения данной проблемы следует объявить переменную Scounter как статическую. Статические переменные сохраняют свое значение между вызовами функции. Как видно из примера 4.11, единственное ключевое слово static превращает неработоспособный код в работающее приложение.
Статические переменные 131 Пример4.11. Статическиепеременные,рЬрзЬаИс.рМр переменные переменные <HTML> <HEAD> <TITLE> Статические </TITLE> </HEAD> <BODY> <H1> Статические </Hl> <?php function track_count { static $counter = $counter++; return $counter; } echo "Значение echo "Значение echo "Значение echo "Значение echo "Значение 0 0; счетчика: счетчика: счетчика: счетчика: счетчика: ?> </BODY> </HTML> track_count track_count track_count track_count track_count 0, " 0, " 0, " 0, " o, h <br>"; <BR>"? <BR>"; <BR>"; <BR>"; Рис. 4.11 демонстрирует, что теперь значение переменной $ counter сохраняется между вызовами функции trackcount. файл Правка Вид Избранное Сервис 'правка Он««. о-а &&;р-*~ <&«**«. 0|^в"' Алрм l {4g htt>:/fecal»*/php/04/p}iptUtfc, php Статические переменные Значение счетчика: 1 Значение счетчика: 2 Значение счетчика: 3 Значение счетчика: 4 Значение счетчика: 5 - ! * J][ упадом <«мси * Рис.4.11 .Работоспособный счетчиквызовов
132 ™ х^. >-^ ™ „___ШМ1"" <4-'УнкЦии Переменные, ссылающиеся на функции В РНР предусмотрена возможность использования переменных, ссылаю- щихся на функции. Переменная может содержать имя функции, и функция, имя которой содержится в переменной, может быть вызвана путем использования соответствующего синтаксиса. Подобным способом во время выполнения скрипта можно определять, какая именно функция будет вызвана. Замечание '■> 0*^™**4V<V-*K><*AJ ■HE4}*>^v>HiCW1»i*W«4lP**« W • Wi ШШ£У 'fQ ИГ дО*г,<Шд» A» J^ ^^Х*» ШВЖ. Щ ,, В практике существует несколько причин, по которым требуется определять имя вы- л/ зываемой функции во время выполнения скрипта. Например, это требуется при использовании т. н. callback-функций, которые вызываются изнутри другой функции принаступленииопределенногособытия.Другимвариантомпвппетспсозр,ан\летаб- лицы-селектора, которая содержит имена функций, вызываемых в зависимости отпоступлениятехилииныхданных. ■Г-.-.'*. ■J4-.1 _»»■•* < /.' ■*-0»Л"'>;| >-.*. <-A►..V^«Л."Vk>^.-.,^ЛГ^^,.f*^»«C^ '111 111" I "'ill III If llll I !"■ I|"l"ll^ I I ■"'! Ill I 11 "ll II ЧМ1Г1Ц1.1 1.1 I l|l » I J» < I "Т'"~ FITff ГГИЩТ¥ЫГ)ТAГ1 Ц^ЛГ^Ч~|Г |)>Г|.М> 1.М.Ш I.IHI_II !■! Пусть описана следующая функция: function apples () { echo "Теперь внутри apples ().<BR>"; echo "В наличии много яблок. <BRxBR>" ; } Для вызова данной функции при помощи переменной следует присвоить ей в качестве значения имя функции и потом использовать имя этой переменной как будто бы производится вызов функции: $function_variable = "apples"; $function_variable () ; Функциям, вызываемым при помощи данного способа, можно передавать аргументы, при этом можно также использовать значения аргументов по умолчанию, что и показано на примере 4.12. Пример 4.12. Функция какзначение переменной, phpvaiiunctions,php <HTML> <HEAD> <Т1ТЬЕ>Функция как значение переменной</Т1ТЬЕ> </HEAD> <BODY> <Н1>Функция как значение переменной</Н1> <?php function apples () { echo "Теперь внутри apples ().<BR>"; echo "В наличии много яблок. <BRxBR>" ; } function oranges ($argument)
Переменные, ссылающиеся на функции 133 { echo «$argument <BR>"; echo "В наличии также много апельсинов. <BRxBR>"; } function bananas ($argument=" " ) { echo " $argument <BR>"; echo "В наличии большое количество бананов. <BRxBR>" ; } $function_variable = "apples"; $function_variable (); $function_variable = "oranges"; $function_variable ("Теперь внутри oranges ()."); $function_variable = "bananas"; $function_variable ("Теперь внутри bananas ()."); ?> </BODY> </HTML> Результат выполнения этого примера приведен на рис. 4.12, из которого видно, что передача аргументов внутрь функций, вызванных при помощи переменной, не составляет никакого труда. файл [Правка Еид избранное Сервис Справка А £> поиск ■£;- №бр<нмое -0 ^ Щ <У*гс;i<ЙЬ№р:Iftxdteitjpbpfoutpbpverfirelicns.nhp v4 {Qпсреян Функция как значение переменной ТепсцЬвн)Т|)И apples (). В наличии много яблок. Теперь внутри oranges O. В наличии также много апельсинов. Теперь BHyrpHbananas Q. В наличии большое количество бананов. Рис. 4.12. Функция какзначение переменной
Условное описание функций РНР является интерпретируемым языком, что, в частности, означает, что в том случае, если функция описывается в теле условного оператора if, она не будет доступна для вызова до тех пор, пока тело оператора не будет выполнено. Например, пусть функция описана следующим образом: if ($create_function) { function created_function() { echo "created_function () : доступна только после выполнения тела оператора if.<BR>"; } В этом случае функция createdfunct ion будет доступна для вызова только после выполнения тела оператора if. Поэтому при необходимости использовать эту функцию далее, следует убедиться в ее наличии. В данном случае необходимо проверить значение переменной Screate_function: if (Screatefunction) { created function (); } Пример 4.13 показывает использование условного описания функций. Пример4.13. Динамическое описание функций, phpconditionalfunction, php и,ч*« у «ч^.г-утлЕпдгудииоуушги* v>&/* «ОоПиж тмтшшу*9*ягя*90'*41Я>аа1ама'шзтмштв*тажятж)щивтюг- <HTML> <HEAD> <TITLE> Динамическое описание функций </TITLE> </HEAD> <BODY> <Hl> Динамическое описание функций </Н1> <?php function existing_function () { echo "existing_function () : доступна сразу после запуска скрипта.<BR>"; } existing_function ( ) ; $create_function = TRUE;
Условное описание функций 135 if ($create_function) { function created_function () { echo "created_function () : доступна только после выполнения тела оператора if.<BR>"; } } if ($create_function) { } ?> </BODY> </HTML> created_function ( ) Результат выполнения примера показан на рис. 4.13. £айл .Правка Вид Избранное Сервис 0*фЯВК1 о^ -ой a fbiP"-» &■**— ®\иш А* р« i M htlB://iotalho5t/php/04/phpcondftionaffunctioniphp jlL .Переход Ссылки- Динамическое описание функций existingfunction 0: доступна срачу после запуска скрипта, createdfunction 0 доступна только после выполнения тела оператора if Рис. 4.13. Вызов функции, описаннойусловно
136 Глава 4. Функции Вложенные функции РНР также допускает описание функции внутри функции — т.н. вложенные функции. Как и в случае функций, описанных условно, вложенная функция становится доступной только после вызова функции, внутри которой она описана, что и представлено в примере 4.14. Пример4.14. Вложенные функции, phpnestedfunction.php <HTML> <HEAD> <TITLE> Вложенные функции </TITLE> </HEAD> <BODY> <Hl> Вложенные функции </Н1> <?php function enclosing_function () { echo "Это объемлющая функция !<BR>"; function created_function () { echo "Это вложенная функция !<BR>"; } } enclosing_function (); created_function (); ?> </BODY> </HTML> Рис .4.14 показывает, что обе описанные в примере функции успешно выполнились. Вложенные файлы Как уже было сказано, функции позволяют разбивать кол на отдельные фрагменты, которые могут быть повторно использованы снова и снова. Но помимо функций, в РНР существует еще одно средство для повторного использования кода — вложенные файлы. Такой файл содержит код, который будет включен в тело основного скрипта в том месте, где использован соответствующий оператор include.
Вложенные файлы файл Правка Еод Иэбражое Сервис Справка Адрес! j"http://localhosyphp/04/phpnestedfunct ion. php Ь6р»«ов 4£ ' .'£, |"уЗ V.: 3 Переход Ог.'»-и Вложенные функции Это объемлюшдя функция ! Это вложенная функция ! Рис. 4.14. Вызов вложенной функции Например, требуется описать несколько числовых констант, которые будут использоваться в различных скриптах. Для этого создается файл constants . inc, содержащий необходимые описания. В РНР в качестве расширения для вложенных файлов обычно используется inc, но ничто не мешает использовать и традиционное расширение php (в частности для того, чтобы пользователи не могли загрузить вложенные файлы напрямую без исполнения). Пример 4.15 показывает содержимое вложенного файла. Следует обратить внимание, что и во вложенных файлах также требуется использования синтаксиса <?php.. . ?>. Пример4.15. Вложенный файл, constants, inc <?php define ("pi", define ("e", ?> 3.14159); 2.71828); n^OWMWWMiWjIlWarOrtiMaiA; iXTteh %>fj-1a ^^pCA" >t4vX* ■!> >*,-*? ■.. Для того, чтобы использовать данный файл в скрипте, применяется оператор include ("constants . inc"), как в примере 4.16. Файл должен находиться в том же каталоге, что и ссьшающийся на него скрипт. Константы, описанные во вложенном файле, становятся доступными и могут быть использованы в скрипте.
138 Глава 4. Функции Пример 4.16. Использование вложенныхфайлов, phpincludes.php <HTML> <HEAD> <TITLE> Использование вложенных файлов </TITLE> </HEAD> <BODY> <Hl> Использование вложенных файлов </Н1> <?php echo "Включение constants.inc...<BR>"; include("constants.inc"); echo "Определено значение pi: echo "Определено значение е: ?> </BODY> </HTML> pi, "<BR>"; e, "<BR>"; Рис. 4.15 демонстрирует успешное отображение значений констант, описанных во вложенном файле. Файл ордока Вид избранно* Cgpmc flpuen СлНг""> * TQ ' 12У Щ # \jPnw it 0\&т Адрес! Щ hHp://lpcalho5l/php/Q4/phplnclucl(g,php Использование вложенных файлов Включение constants.inc... Определенозначениер1:3.14159 Определено значение е: 2.71828 Рис.4.1 5. Использование вложенныхфайлов
Обработка ошибок 139 Во вложенных файлах может размещаться произвольный код, в частности функции или цель, 1е библиотеки функций. Пример 4.17 описывает функцию includedfunction во вложенном файле, которая используется в примере 4.18. Пример4.17. Вложенныйфайлсфункцией, function, inc <?php function included_function () { echo "Это функция included_function ()!<BR>"; } ?> l*W1S*C*o»«*SJOOvI*^ЦиМдамдуТУЬУДПСУХ»-'^» '.[»11|Р1ЧЧ).0_Г1 МИ.И i.ll Щщ .lil' UHMjLlMJIi'HUi 11'НИ. HI UHjTWnWTil I Т[>Л П«»Н|У11|~«ПЧП~Г|^1ИПППШИМ1ЧПИ1ШПаШ«»П»»11М1Ч111^МЦ1^ПГ Пример4.18. Использованиефункцийвовложенномфайле, phpincludefunction, php mil kimhiiumih питии 111циш—whmih—w»i <HTML> <HEAD> <TITLE> Использование вложенных файлов </TITLE> </HEAD> <BODY> <H1> Использование вложенных файлов </Hl> <?php echo "Включение function.inc....<BR>"; include ("function.inc") ; 7> included_function(); </BODY> </HTML> На рис . 4.16 приведен результат успешного вызова функции , описанной во вложенном файле. Обработка ошибок Во многих случаях, если в процессе выполнения функции возникла какая-либо ошибка, то функция возвращает значение FALSE в качестве своего результата. Так поступают многие встроенные функции в РНР, и этот же прием можно использовать и в своих собственных функциях. Например, требуется разработать функцию, возвращающую значение, обратное своему аргументу. Если же значение аргумента равно 0, то функция возвращает значение FALSE.
140 Глава 4. Функции 3 Использование функций во вложенном файле файл Правка Вид Избранное Сервис Справка >ft Internet Explorer ;х] J) '■ Поиск \у Избражое | g | ; " Щ 'д-чл;. :;'Jo http://lucdlhost/php/04]'phpincludefunJ-Ti'on.php 'jj; ЦЩ Переход <.й:^:и Использование функций во вложенном файле Включение function.inc... Это функция includedLfunction ()! Рис. 4.16. Функция, описанная во вложенном файле function reciprocal ($value) { if ($value != 0) { return 1 / $value; } else { return FALSE; } } Одним из способов обработки значения FALSE, возвращенного какой-нибудь функцией, является использование функции die (или exit). Эта функция отображает сообщение, переданное ей в качестве аргумента, и завершает выполнение скрипта. Например, требуется открыть файл при помощи функции fopen (см. гл. 7). В том случае, если функция не может открыть файл (например, если он не существует), она вернет значение FALSE. В таком случае для вывода сообщения об ошибке можно использовать функцию die в сочетании с логическим оператором or:
Итоги 141 <?php $filename = "nonexistent_data_file"; $file = fopen ($filename, "r") or die ("Файл '$filename' не найден") ; ?> При попытке выполнения данного фрагмента кода сперва будет выведено стандартное предупреждение РНР (его вывод можно отключить), а потом сообщение об ошибке, после чего выполнение скрипта завершится. Warning: fopen(nonexistent_data_file) : failed to open stream: No such file or directory in test.php on line 3 Файл 'nonexistent_data_file' не найден На этом рассмотрение работы с функциями завершается. В следующей главе описывается создание интерактивных форм и web-страниц. Для многих разработчиков это — самое сердце РНР. Итоги Функции позволяют разделить сплошной код на небольшие изолированные фрагменты, что, в частности, позволяет избежать конфликтов при использовании переменных. Данные передаются функциям при помощи аргументов и возвращаются как результат их вызова. Ниже перечислены краткие итоги главы: • Для описания функции используется оператор function. • Вызов функции происходит по ее имени. • Данные передаются в тело функции при помощи списка аргументов. Список располагается после имени функции, заключается в круглые скобки и представляет собой перечисление аргументов через запятую. В теле функции аргументы доступны по соответствующим именам как обычные переменные. • В качестве аргументов функций могут использоваться как простые переменные, так и массивы любой размерности. • Аргумент функции может иметь значение по умолчанию, которое используется, если при вызове функции аргумент был опущен. • По умолчанию аргументы передаются по значению. Для передачи по ссылке используется символ &. • Имеется возможность создавать функции с переменным числом аргументов и получать доступ к ним при помощи функции funcgetargs. • Описание static позволяет сохранять значение локальной переменной между вызовами функции.
Элементы управления HTML В этой главе описывается работа с различными элементами управления HTML — полями ввода, выключателями и переключателями, списками и т.п. Элементы управления превращают статическую страничку в интерактивное содержимое, которым можно управлять с их помощью. После того как пользователь ввел необходимые данные в соответствующие поля, они могут быть обработаны соответствующим скриптом, и сформирован ответ в виде HTML-страницы. Перечень элементов управления, которые рассматриваются в этой главе, приведен в табл. 5.1. Таблица 5.1. Элементыуправления Элемент управления Выключатель' (checkbox) Кнопка [button) Кнопка-изображение (image map) Многострочный текст Отправка Тег <INPUT TYPE=CHECKBOX> <BUTTON> < INPUT TYPE=IMAGE> <TEXTAREA> <INPUT TYPE=SUBMIT> Описание Выключатель, идеален для ввода логических переменных. Кнопка с произвольным внешним видом. Графическое изображение, на котором выделены области различной формы (прямоугольники, овалы, многоугольники] для гиперссылок на другие страницы. Поле, предназначенное для ввода нескольких строчектекста. Кнопка, предназначенная для завершения ввода данных и отправке их на web-сервер. В специальной литературечастоиспользуетсятранслитерация данного слова — чекбокс. В рамках данной книги выбран термин «выключатель». — Прим.ред.
144 Глава 5. Элементы управления HTML Элемент управления Пароль Переключатель (radiobutton) Сброс Скрытое поле Тег Описание <INPUT TYPE=PASSWORD> Текстовое поле для ввода пароля. При вводе символы пароля не отображаются на экране, заменяясь звездочками. < INPUT Переключатель, предназначенныйдпявыбо- TYPE=RADIO> pa одного из нескольких вариантов. < INPUT Кнопка, предназначенная для очистки всех TYPE=RESET> полей формы. Предназначен для хранения текста, который не виден на экране, но доступен при обработке формы <INPUT TYPE=HIDDEN> Список <SELECT>, <OPTION>, <OPTGROUP> Многострочный список, предназначенныйдля выбора одного или нескольких элементов. Текстовое поле < INPUT Поле, предназначенное для ввода одностроч- TYPE=TEXT> ного текста или других данных. Файл <INPUT TYPE=FILE> Файл для загрузки на сервер. Создание web-форм Прежде чем приступить к обработке данных в PHP-скрипте, необходимо создать web-форму, где их можно было бы ввести. Для этого используется HTML-тег <FORM>. Он имеет следующие атрибуты: • AC 1ION. Атрибут задает URL скрипта, который будет обрабатывать данные, введенные в форме. Если атрибут не задан, то по умолчанию обработчиком будет назначен текущий скрипт или документ. • METHOD. Определяет способ передачи данных скрипту-обработчику. Если используется метод GET (он же является умолчанием), то все поля, описанные в форме, передаются в строке URL в следующем виде: URL?name=value&name=value. При использовании метода POST поля формы кодируются таким же образом, но передаются через скрытые переменные, не используя строку URL. Метод POST обычно используется при передаче большого объема данных или если необходимо скрыть от пользователя передаваемый набор полей. • TARGET. Задает имя фрейма, в котором будут отображен результат выполнения обработчика формы. Например, требуется обработать данные, вводимые пользователем на странице phpreader.html, при помощи скрипта phpreader.php, расположенного в том же каталоге. В данном случае атрибуту ACTION присваивается значение "phpreader.php" (если бы скрипт-обработчик находится в другом каталоге или даже на другом сайте, то следовало бы указать относительный или абсолютный путь к нему, например, http://www.orioner.ru/php/phpreader.php). Пример такой формы приведен ниже.
Создание web-форм ^ ^ ^ ^ ^^ ^_ ^ ^ 145 <HTML> <HEAD> <TITLE> Пример HTML-формы </TITLE> </HEAD> <BODY> <Hli> Пример HTML-формы </Hl> <FORMMETHOD= "POST " ACTION= "phpreader.php " > </FORM> </BODY> </HTML> Теперь следует наполнить форму полями, например выключателями, переключателями или текстовыми полями. После того как пользователь внесет все необходимые данные и нажмет кнопку «Отправить», будет запущен скрипт phpreader. php, и все данные будут переданы ему. Для отправки предназначен специальный тип кнопки, как показано на примере ниже: <HTMLxHEADxTITLE> Пример HTML-<£opMH</TITLEx/HEAD> <В0БУхН1>Пример НТМЕ-формы</Н1> <КЖМ METHOD="POST" ACTION = "phpreader.php"> <INPUT TYPE ="SUBMIT" VALUE="OK'> </FORM> </BODY> </HTML> Выделенный жирным шрифтом тег отображает кнопку с надписью «ОК.», предназначенную для отправки данных. Надпись на кнопке может быть произвольной и задается атрибутом \MJJE, например: <INPUTTYPE ="SUBMIT" VALUE="Зарегистрироваться"> Обычно рядом с кнопкой «Отправить» располагается кнопка «Сброс» для удаления всех данных, введенных в форму (или для установки их в значения по умолчанию). Ниже приведен пример такой кнопки (как и в предыдущем случае, надпись на кнопке может быть произвольной): <FORMMETHOD= " POST" ACTION= "phpreader . php" > <INPUT TYPE ="SUBMIT" VALUE="OK"> <INPUT TYPE ="RESET" VALUE="Стереть"> </FORM> Каким же образом обратиться к данным, переданным из формы скрипту? Если используется метод POST, для этого используется массив $_POST, как показано в следующем разделе. Для метода GET используется массив $_GET. Оба этих массива являются суперглобальными, что означает, что они доступны в любой функции без необходимости применения оператора global. Еще один суперглобальный массив SREQUEST содержит объединение данных из $_GET и $_POST и может использоваться в тех случаях, когда скрипт может вызываться различными способами.
146 Глава 5. Элементы управления HTML Замечание чир ииищщрч ияыппиничимшичиишинил iij> || \ш1нтчтм*шш*ш1ттшшт^1~тм**—***ш^туящ**м1^1 и и»|»р|ц|иц I | 11 luij? Щ ш Суперглобальные массивы $_GET, $_P0ST, $_REQUEST появились, начиная f с PHP4.1.0. До этой версии вместо $_GET и $_P0ST использовались глобальные массивы $HTTP_GET_VARS и $HTTP_POST_VARS, которые внутри функций требуют обязательного объявления при помощи оператора g I о b a I . Начиная с РНР 6.0, эти массивы перестали поддерживаться. Текстовые поля Текстовые поля предназначены для ввода однострочных данных в web-формах и являются наиболее часто употребительными элементами управления. Для создания текстового поля используется тег < INPUT TYPE—' TEXT' > внутри Tera<F0RM>. Ниже в примере используются два файла — HTML-страница, на которой пользователь может ввести данные, и PHP-скрипт, которые их отображает. В HTML-странице содержится форма с текстовым полем, которая направляет данные скрипту phptext. php. В примере 5.1 пользователь вводит собственное имя, для чего используется текстовое поле с именем «Name». Имя поля задается при помощи атрибута NAME и присваивается для того, чтобы к данным, введенным в этом поле, можно было бы обратиться в РНР-скрипте. Пример 5.1. Описание текстового поля, phptext.html <HTML> <HEAD> <TITLE> Текстовое поле </ТТТЬЕ> </HEAD> <BODY> <CENTER> <Н1>Текстовое поле</Н1> <FORM METHOD="POST" ACTI0N="phptext.php"> Введите Ваше имя <INPUT NAME ="Name" TYPE="TEXT" > <BRxBR> <INPUT TYPE=SUBMIT VALUE="OK" > </F0RM> </CENTER> </BODY> </HTML> При загрузке данного файла на экране будет отображено текстовое поле для ввода имени пользователя и кнопка «ОК» для завершения ввода данных, как показано на рис. 5.1
Получение данных из текстовых полей 147 Эр»айл [Травка ^ид Избранное Сервис "правка ©н"^ : О - Э Й ©]/>»*"» Дранное 4&\ & S3 ' Адрес;. Щ http://localho3t/php/0S/phptext.html Jl^JlfT? :~ Текстовое поле Введите Ваше имя £*?Г®?.. ЩГотсар >?м естнан интрасеть Рис. 5.1. Пример использования текстового поля — запрос имени пользователя После того как пользователь ввел имя и нажал кнопку «ОК», производится загрузка РНР-скрипта, указанного в атрибуте ACTION, и данные передаются ему для обработки. В следующем разделе рассказывается, как получить доступ к этим данным. Получение данных из текстовых полей Для того чтобы получить доступ к данным, переданным скрипту из HTML-формы, используются суперглобальные массивы $_GET ИЛИ $ POST для способов передачи GET и POST соответственно. Для обеспечения независимости от способа передачи данных рекомендуется использовать массив $_REQUEST, который содержит данные из обоих этих массивов. В предыдущем разделе использовалось текстовое поле с именем «Name», заданным в атрибуте NAME Значение этого поля может быть получено как элемент массива $ REQUEST [ "Name" ], как показано в примере 5.2.
Пример 5.2. Чтение данных из текстового поля, phptext.php <."С Гч?"»'>Л>^ ;л- <HTML> <HEAD> <TITLE> Обработка текстового поля </TTTLE> </HEAD> <BODY> <CENTER> <Н1>Чтение данных из текстового полж/Н1> Ваше имя <?php echo $_REQUEST ["Name"]; ?> </CENTER> </BODY> </HTML> Результат выполнения данного примера показан на рис. 5.2. Файл Правка Вад Избранное Сервис Справка tj Нил. • ■ .- ,ч\ "j ■■("] ' у-.' Поиск ^~у Избранное ■";-r_i";|http//localhost/php/05/phptext.php Щ U)l Q Переход _ С&1ПКМ Чтение данных из текстового поля Вашеимя Сергей 4£j Готово ■ *§ Местная интрасеть Рис. 5.2. Отображение содержимого текстового поля
Многострочные поля 149 Как видно, доступ к данным HTML-формы осуществляется при помощи обращения к элементу массиву $ REQUEST [" ControlName" ], где ControlName — название элемента управления, например, текстового поля. Если способ передачи данных известен заранее и не меняется, можно также использовать массивы $_GET или $ POST, например, для обработки формы из примера 5.1 можно также использовать следующий код: <?php echo $_POST ["Name"]; ?> Многострочные поля Многострочные поля предназначены для ввода большого количества текста. Для их описания используется тег <TEXTAREA>, в атрибутах которого задается размер области для ввода текста по вертикали в строках (атрибут ROWS) и по горизонтали в символах (атрибут COLS). В остальном работа с ними практически аналогична использованию текстовых полей, что и продемонстрировано в примере 5.3. Пример 5.3. Описание многострочного поля, phptextarea. html <HTML> <HEAD> <Т1ТЪЕ>Многострочное поле</Т1ТЬЕ> </HEAD> <BODY> <CENTER> <Н1>Многострочное поле</Н1> <FORM METHOD=POST ACTION= "phptextarea . php" > Перечислите Ваших лучших друзей: <BR> <TEXTAREA NAME="Friends" COLS=0" R0WS="> 1. 2. 3. 4. </TEXTAREA> <BR> <BR> <INPUT TYPE=SUBMIT VALUE= " OK" > </FORM> </CENTER> </BODY> </HTML>
150 Глава 5. Элементы управления HTML Следует обратить внимание на то, что в отличие от простого текстового поля, начальное значение многострочного поля содержится внутри тега <TEXTAREA>, что видно на рис. 5.3. Файл Правка §ид Избранное Сервис Справка £i'-«:-M - iT'" ifj |Ш ift ; J~'- Гипс Луйршное #jl|i;."^g """ Ддрег^ " h ' ' К //locaIhost/php/05/phptextareaJitml -VIS Переезд :ш\ Ссылки Многострочное поле Перечислите^Ваших лучших друзей: il. Юрий \г ■ Андрей J 3. Александр ,14. Алексей tfiMiiMbiUiiiiUetti Местная ннтрасет*» . Рис. 5.3. Пример заполнения многострочного поля Для получения данных, введенных в многострочном поле, используется тот же массив $_REQUEST, что и в предьщущем разделе, как показано в примере 5.4. Пример 5.4. Обработка многострочного поля, phptextarea.php <HTML> <НЕАБхТ1ТЬЕ>0бработка многострочного полж/Т1ТЬЕх/НЕА0> <BODY> <CENTER> <Н1>Чтение данных из многострочного полж/Н1> Вашими лучшими друзьями являются: <?php echo $_REQUEST ["Friends"]; ?> </CENTER> </B0DY> </HTML>
Выключатели (checkboxes) 151 Результат выполнения этого примера представлен на рис. 5.4. Следует обратить внимание, что несмотря на то, что данные были введены в несколько строк, браузер при формировании страницы отформатировал их в одну строку. Для того чтобы расположить данные на экране также, как они были введены пользователем, следовало бы заменить при выводе символ " \п" (перевод строки) на тег <BR> (разрыв строки). файл Правка Вед Избранюе Сервис .Оравка ОНазад ' 0' [" § СЬ .;#лП°"" -г!?1****тм ф\ ^ д Ац\ЛО_ Ж, http://localho5"php/05/phptextarea.php а Переход '■ СО:'! Чтение многострочного поля Вашими лучшими друзьями являются: 1. Юрий 2. Андрей 3. Александр 4. Алексей • Готово : ^jj Местная и нтрзееть Рис. 5.4. Отображение содержимого многострочного поля Выключатели (checkboxes) Еще одним основным элементом управления в HTML-формах является выключатель (checkbox). Для его описания используется тег < E4PUT ТУРЕ=СНЕСКЮХ>. В примере 5.5 он используется для того, чтобы получить от пользователя ответ на заданный вопрос.
1 52 Глава 5. Элементы управления HTML Пример 5.5. Описание выключателей в форме, phpcheckboxes. html :*i^ijj^uriiMPtw<c*j*^Wiaotiv;«(H».*iaoeewiw«T»Hi»^ <HTML> <НЕА0хТ1ТЬЕ>Использование выключателей*; /TTTLEx/HEAD> <BODYxCENTER> <Н1>Использование выключателей</HI> <FORM METHOD=POST ACTION="phpcheckboxes.php"> Подписаться на новости? <INPUT NAME="Checkl" TYPE="CHECKBOX" VALUE="Yes"> Да <INPUT NAME="Check2" TYPE="CHECKBOX" VALUE="No"> Нет <BRxBR> <INPUT TYPE=SUBMIT VALUE="OK"> </FORM> </CENTERx/BODY> </HTML> ; '/ньчулюкнягск «'«чоияжм'декдоюмхлсмш льлд*г*пшт»>тгнпт&1штшш&гюл.жптаг*тп11маиск%м1ъшшмп^ На рис. 5.5 видно два выключателя с соответствующими подписями1. "И Использование выключателей - Miciosort Internet Explorer |_ ;;S 'X. файл Правка Вид Избранное Сервис Справка jp-" Ш< :"ад • © • ; Й il ф1~)},}пжк "'избраний • Ф\Ш 3 - Адрес fhttplfocalhost/php/05/phpcheckboxes.html -Ф^.'З Переход .' ;'Г""КН Использование выключателей Подписаться на новости? О Да ■ Нет дк] ИЗ Готово Рис. 5.5. Использование выключателей В данном примере пользователь может одновременно включить оба выключателя, дав оба ответа на вопрос. Для предотвращения возможности такого ввода можно использовать скрипт на стороне клиента, например JavaScript, что выходит за рамки данной книги. Альтернативой является использование переключателей, как показано в следующем разделе. Можно также производить проверку данных на корректность в PHP-скрипте на стороне сервера, о чем рассказывается в главе 6. — Прим. ред.
Переключатели (radio buttons) 153 Для определения состояния выключателей в скрипте используются выражения $_REQUEST ["Checkl"] и $_REQUEST ["Check2"] соответственно. Тонкость заключается в том, что если выключатель включен, то соответствующий ему элемент массива принимает значение, определенное в атрибуте \ALUE тега INPUT, в данном случае «Yes» и «No» соответственно. Если же он выключен, то значение соответствующего элемента массива не определено, и использование его вызовет предупреждение. Для проверки, существует ли заданный элемент массива, может использоваться функция is set. Функция возвращает TRUE, если переменная или элемент массива, заданный ей в качестве параметра, существует, и FALSE в противоположном случае. Использование этой функции продемонстрировано в примере 5.6. Пример 5.6. Отображение состояния выключателей, phpcheckboxes.php <HTMI> <НЕАБхТ1ТЬЕ>Использование выключателей</Т1лЕх/НЕАВ> _<BODYxCENTER> <Н1>0тображение состояния выключателей</Н1> Вы выбрали <?php if (isset ($_REQUEST ["Checkl"])) echo $_REQUEST ["Checkl"], "<BR>"; if (isset ($_REQUEST ["Check2"]) ) echo $_REQUEST ["Check2"], "<BR>"; ?> </CENTERx/BODY> </HTML> Как видно из рис. 5.6, состояние выключателей отображаются корректно. Переключатели (radio buttons) В предыдущем примере пользователь может одновременно отметить оба варианта ответа на вопрос, что в общем случае недопустимо. В таком случае можно использовать переключатели1, который позволяют выбрать только один вариант из некоторого фиксированного множества альтернатив. Переключатель описывается при помощи набора тегов <INPUT TYPE=RADIO>, а для группировки различных альтернатив все они связываются при помощи атрибута NAME, значение которого должно быть одинаково внутри группы. В примере 5.7 демонстрируется описание переключателя. Английское название «radio button» берет свое начало от кнопок переключения диапазонов на транзисторных приемниках, и форма этих элементов управления напоминает по внешнему виду эти кнопки. — Прим.ред.
154 Глава 5. Элементы управления HTML Э Использование выключателей - Microsoft Interne Explorer файл £1равка Вид Избранное Сервис Справка Л HteGaq - U >Stj jjgj | Jj I р Псих -"Избранное. Щ \ л |$ -■цц>^" \4U http://localhost/php/05/phpcheckboxes.php £$} л Переход ■',' Ссылки Отображение состояния выключателей Вы выбрали Yes ^Готово \ "8j Mjjrn>w штруять . Рис. 5.6. Отображение состояния выключателей Пример5.7. Описаниепереключателя, phpradio.html ЛГ.Т:Л*,УДГ**: <HTML> <НЕА0хТ1ТЬЕ>Пример переключателж/Т1ТЬЕх/НЕАБ> <BODYxCENTER> <Н1>Пример переключателж/Н1> <F0RM METHOD="POST" ACTI0N="phpradio.php"> Подписаться на новости? <INPUT NAME="Radiol" TYPE="RADIO" VALUE="Yes"> Да <INPUT NAME="Radiol" TYPE="RADIO" VALUE="No"> Нет <BR> <BR> <INPUT TYPE="SUBMIT" VALUE="OK"> </F0RM> </CENTERx/BODY> </HTML> .-O-.V *i :r:iJ<V4> V>t -!■<«».к»^ЦЯОчТЙКиИ««*КИа ■MHlTi«WtH»l ЧЫ ito*y*fMMf Г IT И На рис. 5.7 виден переключатель на две позиции.
Переключатели (radio buttons) ^^ 155 файл Правка §w Избранное Сервис "правка Адрей-\Ui^p:/flcx3lhosVphp/05/phpradio.html g€ Q Переход Cctinrn Пример переключателя Подписаться на новости? © Да О Нет £9пэГйоа ■' . " Местмая интрасетъ Рис. 5.7. Использование выключателей Для получения состояния переключателя используется одно обращение к соответствующему элементу массива SREQUEST, как показано в примере 5.8. Следует обратить внимание на то, что если пользователь не сделал никакого выбора, то соответствующий элемент массива SREQUEST будет не определен, поэтому и в этом случае рекомендуется использовать функцию is set. Пример 5.8. Отображение состояния переключателя, phpradio.php МяМкч^м»г <HTML> <НЕАВхТ1ТЬЕ>Отображение состоянияпереключателя </TITLEx/HEAD> <BODYxCENTER> <Н1>0тображение состояния переключателя </Н1> <?php if (isset ($_REQUEST ["Radiol"])) { echo "Ваш выбор ", $_REQUEST ["Radiol"]; } else { echo "Выбор не произведен"; } ?> </CENTERx/BODY> </HTML>
156 Глава 5. Элементы управления HTML Как видно из рис. 5.8, состояние переключателя отображается корректно. файл Правка Вид избранное Сервис Справка ^P-^'i \Ua http2//bcahosVphp/05/phpradio.php 'Л У0 .«J В Переход Ссыпки Отображение состояния переключателя Ваш выбор Yes ^l Готово "§ Местмая ннтрасетъ Рис. 5.8. Отображение состояния переключателя Если в одной форме требуется использовать несколько переключателей, то для их идентификации каждой из групп тегов <rNPUT TYPE=RADIO> необходимо присвоить при помощи атрибута №МЕ свое уникальное имя, которое и будет именем переключателя. Списки Списки в HTML-формах создаются при помощи тега <SELECT>. В отличие от рассмотренных ранее элементов управления, списки допускают выбор сразу нескольких значений. В примере 5.9 пользователю предлагается выбрать его любимые фрукты, отметив одну или несколько строчек в списке на экране. Возможность выбора не одного, а нескольких вариантов разрешается атрибутом MULTIPLE. Следует обратить внимание, что в атрибуте №МЕ задано имя массива с квадратными скобками, а не имя простой переменной.
списки 157 Пример 5.9. Выбор нескольких альтернатив в списке, phplistbox. html v*>*OAP»eMC*»a4*AwtwM m увялое* twawr.' уГ4»"К7ж&*'*л*) jhiMemai лттмллл *» ?^*уа<х»тсж<мй*а»*.>vowat>HW*v>»»g«A. *--«ak< </LV%bxx<^*> <HTML> <НЕАВхТ1ТЪЕ>Использование criMCKOB</TITLEx/HEAD> <BODYxCENTER> <H1использование списков</Н1> <F0RM METH0D="P0ST" ACTION="phplistbox.php"> Выберите любимые фрукты: <BR> <BR> <SELECT NAME="Food[] " MULTIPLE> Апельсинх /0 PTI0N> rpyma</0PTT0N> Персик</0РТ10Ы> Яблокск /0 PTI01\Г> </SELECT> <BR> <BR> <INPUT TYPE="SUBMIT" VALUE="OK"> </F0RM> </CENTERx/BODY> </HTML> Пользователь может выбрать несколько элементов списка, как показано нарис. 5.9. файл £1равка £ид Избранное Сервис Справка Адресу |"http://localhosi:/php/05/phplistbo>;.html \Щ Щ Пересход ■ ссылки Использование списков Выберите любимые фрукты: е Щ* Местная интрасеть Рис. 5.9. Использование списков
158 Глава 5. Элементы управления HTML Так как в списке разрешен выбор нескольких вариантов, нельзя просто обратиться к элементу массива $ REQUEST [ "Food" ] и считать оттуда результат выбора. Элемент $ REQUEST [ "Food" ] в данном случае сам является массивом, элементы которого следует обработать в цикле, например, с использованием оператора foreach, как показано в примере 5.10. Пример 5.10. Отображение выбранных элементов списка, phplistbox. php <ШМ1> <НЕАБхТ1ТЬЕ>Использование craiCKOB</TITLE></HEAD> <BODYxCENTER> <Н1>Отображение выбранных элементов списка</Н1> Ваш выбор: <BR> <?php foreach (S_REQUEST ["Food"] as Sfruit) { echo Sfruit, "<BR>"; } ?> </CENTERx/B0DY> </HTML> Y s^.1 Л1VV.-W.-/-*/**:■*>•-'s£Жчr.М»Л**i'AlytmwXZ■ ^7>ЪШГ&.Vrt»tVWfVGSAbWmKt«СКЛЧОМЛМЗДММвфг*W*b"И«яЛарпЩщ f*< Г*Ы*тШ&Х(* Результат выполнения данного примера представлен на рис. 5.10. *$ Использование списков - Microsoft Internet Explorer файл Правка £ид Избранное Сервис "правка ©Назад - ,у Jj] $ fj) ;|/)ГЫх ГдИфнсе 0i& В AtiPeti Щ rmp://tacalriosVpripAM/pripll51box.prip Э'В iiiiiiiii»!^ »>!>■■ 1 itt nr i ii» ■ iii i nil iihIiii^iiihhiii» mm ««nil ii mil umimn i imniiiiii iT! Выбранные элементы списка Ваш выбор: Груша Яблоко Ml Готово I *М Местная wrpaceTb ■ ■ ■■ ... ..■■■■,■■ ... 7*,. ...... ...:,Г~-■■■■. ....■■„ ........ Рис. 5.10. Отображение выбранных элементов списка
Скрытые поля 159 Скрытые поля Еще одним элементом управления являются скрытые поля, которые позволяют сохранять в формах служебные данные. Это может быть удобно, например, в тех случаях, когда не разрешено использование cookies, а требуется сохранить какие-либо сведения о текущем сеансе работы пользователя. Пример 5.11 демонстрирует использование скрытого поля. Пример 5.11. Использование скрытого поля, phphidden.html II IIIHIII Will I1IIIHHII МИМ !!■■ IIIIIHIH !■■■ Ml 1IMIIIWIHII1I4—IHI1I»IW—Hi—MII1HI Hill IIIM1IWI1—WMIMMllllHIl 11 ■ IIIW 11II Г1 |l Ц milHUHI ГЦ I |l||| <HTML> <HEAD> <TITLE> Использование скрытого поля </TTTLE> </HEAD> <BODY> <CENTER> <H1использование скрытого полж/Н1> <FORM METHOD="POST" ACTION="phphidden.php"> Нажмите на кнопку для отображения скрытых данных <INPUT NAME="Hidden" TYPE="HIDDEN" VALUE="Большой секрет!"> <BR> <BR> <INPUT TYPE="SUBMIT" VALUE="OK"> </FORM> </CENTER> </BODY> </HTML> файл Правка &1д Избранное Сервис ^лршкв ©"*" - © - 3 II &!/*"** l/tiapeuve,0, ^ Ш- Awec: [£| hnp:/»ocd*KHtftih(iAISft]hphldden.htjrif Q Переход . ая*:пг^ Использование скрытого поля Нажмите на кнопку для отображения скрытых данных Д Готово ц Местная интрасегь.. Рис. 5.11. Отображение выбранных элементов списка
160 __ .„„^г„.„^^....,„„Гу- ^,«^„-х~^, С£2Ла §^ ^ле^йТ'^!-ХПРавления нхгч/к_ Внешний вид этой страницы представлен на рис. 5.11. Данные, расположенные в скрытом поле, естественно, не отображаются на экране, но при нажатии на кнопку запускается скрипт, который способен отобразить их. Содержимое скрытого поля может быть получено уже описанным выше способом — как элемент одного из массивов $_GET, $_POST или $_REQUEST. Это продемонстрировано на примере 5.12. Пример 5.12. Отображение содержимого скрытого поля, phphidden.php <HTML> <HEAD> <Т1ТЬЕ>0тображение содержимого скрытого полж/Т1ТЬЕ> </HEAD> <B0DY> <CENTER> <Н1>0тображение содержимого скрытого полж/Н1> В скрытом поле содержится строка: <BR> <?php echo $_REQUEST ["Hidden"]; ?> </CENTER> </B0DY> </HTML> Результат выполнения данного примера представлен на рис. 5.12. файл Правка Вид Избранное Сервис С_правка фи**» - О ■ Й [^ ^|!рПшсК ^ИЛр^юе ^!| В Адрес:| j3 http:/ftacalhosVphp/DS/phphidden.php \..ty' Q Переход. Содержимое скрытого поля В скрытом поле содержится строка: Большой секрет! ж) Готово - Чд Местная интрасеть ■. # С<мя*I Рис. 5.12. Отображение содержимого скрытого поля
Поля для паролей 161 Полядляпаролей При вводе паролей и иных конфиденциальных данных нежелательно, чтобы вводимый текст отображался на экране. Для этого предназначены поля для ввода паролей. В HTML-форме они описываются при помощи тега <INPUT TYPE=PASSWORD>. С точки зрения РНР между ними и простыми текстовыми полями нет никакого различия, но при вводе данных в такие поля вместо вводимых символов отображаются звездочки. В примере 5.13 описывается поле для пароля с именем «Password». Пример 5.13. Запрос пароля у пользователя, phppassword. html <HTML> <HEAD> <TITLE> Ввод пароля </TITLE> </HEAD> <BODY> <CENTER> <Hl> Ввод пароля </Hl> <FORM METHOD="POST" ACTION="phppassword.php"> Введите пароль : <INPUT NAME= " Password" TYPE= " PASSWORD" > <BR> <BR> <INPUT TYPE= " SUBMIT" VALUE= " OK" > </FORM> </CENTER> </BODY> </HTML> ПЦИЁЩЩ^ПдТИП lWtftt» iil.H Tf nnWttn »В*&фЛ**я&ЛЫ ЧгЖ&ДСХХЛ&Ц'Ж'Ы \--W.'. X Пример формы с уже введенным паролем приведен на рис. 5.13. Для того чтобы прочитать введенный пароль в скрипте, используется все тот же массив $ REQUEST, что показано на примере 5.14. Пример 5.14. Чтение введенного пароля, phppassword.php <HTML> <HEAD> <Т1ТЬЕ>0тображение паролж/Т1ТЬЕ> </HEAD> <BODY> <CENTER> <Н1>Отображение паролж/Н1> Пароль: <BR> 6 РНР в примерах
162 Глава 5. Элементы управления HTML <?php echo $_REQUEST ["Password"]; ?> </CENTER> </BODY> </HTML> файл Правка §.ид избранное Сервис Справка * ||Н31ЭД "• © - jj jj§ ф J рПОИСК ^ изданное ф. Л Д Ajipeci Д_ htO://localhosVphp/OS/phppassword.html Q Переход Ссылки Ввод пароля Вт ""|1мЯ1<"мХмм ведите пароль:.J ы фгрщю :<j№ 'стная иктрзсетъ . Рис. 5.13. Ввод пароля Результат выполнения этого примера показан на рис. 5.14. Конечно, в реальном приложении вместо того, чтобы показывать введенный пароль на экране, его следует сравнить с значением, хранящимся в закрытом списке, например, для того, чтобы предотвратить несанкционированный доступ к данным. Кнопка-изображение РНР также поддерживает кнопки-изображения, который представляют собой графические файлы, щелчок по каждой точке которого можно обработать особым образом. Для создания подобных элементов управления используется тег < INPUT TYPE=IMAGE>, атрибут SRC которого указывает на графический файл, что продемонстрировано в примере 5.15.
Кнопка-изображение фйЙЛ Правка £ид Избранное Сервис Справка Q*w . £) . g) g) $ j рпоиск S^Mp»« 0 | jj^ Адрес;. f£) h^i://loc^(^/php/rfi/phppi№word.php j^.El Ibpsagn? iilamm Отображение пароля Пароль: password -■■ "■■■■-•'— ^- : < ^Местная иктрасетъ/ Рис. 5.14. Отображение введенного пароля Пример 5.15. Графическая кнопка-изображение, phpimap.html <HTML> <HEAD> <TITLE> Кнопка-изображение </TITLE> </HEAD> <B0DY> <CENTER> <H1> Кнопка-изображение </Hl> <F0RM METH0D="POST" ACTI0N="phpimap.php"> Щелкните по картинке: <BR> <INPUT NAME="imap" TYPE="IMAGE" SRC="imap.BMP"> </F0RM> </CENTER> </B0DY> </HTML>
164 Глава 5. Элементы управления HTML Когда пользователь щелкает мышкой по картинке (см. рис. 5.15), координаты точки, где произведен щелчок, передаются в скрипт. Кнопке-изображению при помощи атрибута №МЕ присвоено имя imap, и в большинстве языков программирования координаты точки именовались бы как imap.x и imap.y. Но так как подобный синтаксис недопустим в РНР, эти имена автоматически заменяются на допустимые - imapx и imapy, что и показано в примере 5.16. Пример 5.16. Определение координатщелчка, phpimap.php <HTML> <HEAD> <Т1ТЪЕ>Координаты точки изображениж/Т1ТЪЕ> ■ </HEAD> <BODY> <CENTER> <Н1>Координаты точки изображениж/Н1> <BR> Вы щелкнули по точке с координатами ( <?php echo $_REQUEST ["imap_x"], ", ", $_REQUEST ["imap_y" ?> ) • </CENTER> </BODY> </HTML> -:-у «.кч'л-лч*»-^ -v-vi- ."Л"</л L* ;>»>л ' о i^Cw-.w^e щ>**: i*v*>vi t г^касылочь-'хачси» tn *у>АА*у?ж*&шт***х:кпш9лмл i iwwunwBWHwaw файл .Правка Вид Избранное Сервис Справка 4-.V -'-■ V"- ■'?) jfc};- ' ■*. "''■/ ..xJfM..p.HH.. 'к" ■-."-:;."Jhttp-//localhost/php/05/phpimap,h1ml "gs C р ,V;i Q Переход ■.: 'Ссылт ^)гото» Кнопка-изображение Щелкните по картинке: Щелкни меня! : Щ$ Местная интрасетк Рис. 5.15. Кнопка-изображение
Загрузка файлов 165 Результат выполнения примера приведен на рис. 5.16. После определения координат можно произвести их анализ и предпринять соответствующие действия. файл Правка £ид избранное Сервис ^правка Ц>Назад - ф - \iQ @ ifj} ГпопсК "Избранное ^, Адресу j@ http://localhosl:/php/05/phpjmap.php |j Переход '-■:-&№ Координаты точки изображения Вы щелкнул! по точке с координатами ( 126, 21). &1 :*ss Местная интрасеть Рис. 5.16. Отображение координат щелчка Загрузка файлов При помощи HTML-форм можно загружать файлы на web-сервер, и РНР полностью поддерживает этот механизм. Для этого используется специальный тип формы с типом данных «multipart/form-data», который задается в атрибуте ENCTYPE тега <FORM>. Метод передачи данных и скрипт-обработчик задаются как обычно. Чтобы добавить к форме поле для выбора имени загружаемого файла, используется тег <INPUT TYPE=FILE>. Пример 5.17 содержит форму, содержащую подобное поле с именем userfile.
166 Глава 5. Элементы управления HTML Пример 5.17. Формадля загрузки файла, phpfile.html лжавх&амямжычхязнаКу, и ■*»—» аяжшаагяак'. <HTML> <HEAD> <TITLE> Загрузка файлов </TITLE> </HEAD> <BODY> <CENTER> <H1> Загрузка файлов </Н1> <TORM ENCTYPE="multipart/form-data" ACTION = "phpfile.php" method = "post"> Выберите файл для загрузки: <INPUT NAME^'useriHe'1 TYPE="file" /> <BRxBR> <INPUT TYPE="submit" VALUE="Загрузить!" /> </FORM> </CENTER> </BODY> </HTML> Форма, описанная в примере 5.17, представлена на рис. 5.17. Следует обратить внимание, что тег <INPUT type=file> описывает одновременно и поле для ввода имени файла, и кнопку «Обзор» для выбора его при помощи диалогового окна. После ввода или выбора имени файла для загрузки следует нажать кнопку « Загрузить!». Э Загрузка файлов - Microsoft Internet Explorer • • _п * * - файл Правка §ид Избранное Сервис Справка @Л« • ©* й Ш €й i .9-"°^ #<р=ннзе ф: ! ! , Ш - Адрес: Щ http ://1ocaJ host/ph p/D5/ph pfile, html y:*|j. Q Переход ■ Загрузка файлов Выбооито сЬаЙЛ ДЛЯ ЗагоуЗКИ: !C\messaaeM '•{ 06jopL.. I \ Загрузить! | ЦЗ гото во ■ ': ** 1 [Честная интрасеть '. |Но§ ■■ Ссыяки." Рис. 5.17. Форма для загрузки файла
Обработка загруженного файла ^Ы Обработка загруженного файла Доступ к загруженным файлам осуществляется по имени (в примере 5.17 задано имя userfile). Но при этом не используется описанные выше массивы $_GET, $ POST и $ REQUEST. Для обработки файлов предназначен специальный суперглобальный массив $_FILES. Данный массив является двухмерным, при этом первым индексом является имя поля для загрузки файла. Второй индекс массива принимает фиксированный набор значений, все его возможные варианты представлены ниже: $_FILES [userfile] ['name' ] Имя исходного файла на компьютере пользователя. $_FILES [userfile] ['type'] MIME-тип файла. Например, для текстовых файлов это «text/plain», а для графических изображений может быть «image/gif». $_FILES [userfile] ['size'] Размер загруженного файла в байтах или 0, если пользователь не выбрал файл для загрузки. $_FILES [userfile] ['tmpname'] Имя временного файла, куда был загружен файл с компьютера пользователя или пустая строка, если пользователь не выбрал файл для загрузки. $_FILES [userfile] ['error'] Код ошибки, возникшей при загрузке файла. Значение 0 говорит об отсутствии ошибки. Элемент присутствует, начиная СРНР4.2.0. Замечание ф - Массив $_FI LES введен, начинаясРНР4.1.0. Доэтой версии использовался гло- jf балычыймассив$ HTTPPOSTFILES, которыйвнутрифункцийтребуетобязателъ- ногообъявленияприпомощиоператорау I о b a I. Начиная с РНР6.0, этотмассивне используется. ■now* уштимнутльшим После успешной загрузки содержимое файла сохраняется в каталоге для временных файлов, а имя этого временного файла помещается в элемент массива $_FILES [ ' userfile ' ] [ ' tmpname ' ] (считаем, что поле для загрузки файла называется userfile). В примере 5.18 показано отображение загруженного файла на экране. Перед тем, как прочесть содержимое файла, его необходимо открыть при помощи функции fopen. Она имеет два параметра — имя файла и строку, которая задает режим открытия. В данном случае файл открывается для чтения, поэтому строка режима выглядит как «г»: $handle = fopen ($_FILES [ 'userfile' ] [ ' tmp_name' ] , " r " ) ;
168 Глава 5. Элементы управления HTML Далее используется цикл whi I e, который повторяется до тех пор, пока не будет достигнут конец файла (этот факт определяется при помощи функции f е о Г). while (ifeof (Shandle))... Для чтения очередной строки файла используется функция fgets: $text = fgets (Shandle); Наконец, после завершения вывода файла его следует закрыть при помощи функции fclose. Хотя после завершения выполнения любого скрипта все принадлежащие ему ресурсы, в том числе и файлы, автоматически освобождаются, рекомендуется закрывать файлы явно. Пример 5.18. Отображение загруженного файла, phpfile.php -» с. иг- .лл^л*. iv^-vs.vx. \~. ZA?/. ■=.-. ьх. so а. су \г. (, „у л ч - о / * алло\им«ькй 'j ;•■ a* fu'j у*& мылепло* ami юпвидедпоишлЮ'1 ■о'мммо деялоичп<хп*дее>гамим д>ч*о'<*#шидч,« илшюувщюлдс <HTML> <HEAD> <Т1ТЬЕ>0тображение загруженного файла</Т1ТЬЕ> </HEAD> <BODY> <CENTER> <Н1>0тображение загруженного файла</Н1> Вы загрузили файл следующего содержания: <BR> <?php $handle = fopen ($_FILES ['userfile']['tmp_name'], "r"); while (ifeof ($handle)) { $text = fgets ($handle); echo $text, "<BR>"; } fclose ($handle); ?> </CENTER> </BODY> </HTML> Результат отображения загруженного файла показан на рис. 5.18. Кнопки:вариант 1 Кнопки часто используются на HTML-страницах. Кнопки отличаются от остальных элементов управления тем, что они не остаются нажатыми после щелчка по ним. Поэтому в тот момент, когда данные посылаются скрипту-обработчику, кнопка уже давным-давно находится в отжатом состоянии. Как же определить, какая именно кнопка была нажата? Для этого можно использовать различные способы, и три из них приведены в этой главе. Одним из возможных вариантов является комбинированное использование PHP, JavaScript и скрытого поля, как показано в примере 5.19. Когда пользователь щелкает по кнопке, функция JavaScript сохраняет соответствующую кнопке строку в скрытом поле и затем использует функцию submit для отправки результатов на web-сервер скрипту phpbuttons.php.
Кнопки: вариант 1 файл .Правка Вид Избранное Сервис Справка ф Нёвщ - 0 j^J \\"\ ifjj | JD ГЫх Л"Избражое ф ' .4 Ц Адрес;, i | § http://locaJhost/php/05/phpfile.php .vi Щ Переход Сеьс*"- Отображение загруженного файла Вы загрузили файл следующего содержания: Поздравляем! Этот файл успешно загружен с клиента на сервер ^Готово ' *JMi естная интрасеть Рис. 5.18. Отображение загруженного файла Пример 5.19. Страница стремя кнопками (вариант 1), phpbuttons 1. html WJOTJJiWmWW» |УЛГ^Я4УД^^ ЛГЯП£Яи*М*Яи**Л*аЛ?-П !ТЛ*Эг»*<-*; # л-Y^Xv > ti^v <*4 <HTML> <HEAD> <Т1ТЬЕ>Кнопки: вариант 1</TITLE> </HEAD> <B0DY> <Н1>Кнопки: вариант 1</Н1> <F0RM NAME="forml" ACTI0N="phpbuttons.php" METH0D="POST"> <INPUT TYPE="HIDDEN" NAME="Button"> <INPUT TYPE="BUTTON" VALUE="KHOnKa 1" ONCLICK="buttonl ()"> <INPUT TYPE="BUTTON" VALUE="Кнопка 2" 0NCLICK="button2 ()"> <INPUT TYPE="BUTTON" VALUE="Кнопка 3" 0NCLICK="button3 ()"> </F0RM> <SCRIPT LANGUAGE="JavaScript"> <! function buttonl () { document.forml.Button.value = "кнопка 1' forml.submit ()
170 Глава 5. Элементы управления HTML function button2 () { document.forml.Button.value forml.submit () } function button3 () { document.forml.Button.value forml.submit () } '' кнопка 2' 1кнопка З' // -> </SCRIPT> </B0DY> </HTML> На рис. 5.19 представлен внешний вид рассмотренной формы с тремя кнопками. файл Правка 1 ид Избранное Сервис Справка ljr"i (j) Ч*] !i li Ргсиос W&patHB Ц [ Ц Щ ' ДЦР<С1 JЦ httpi:NjfcalIhos^php/OS/phpbijttonsl .html _11 В Перепад1 'Ссылки' Кнопки:вариант1 Кнопка "lj[ Кнопка г |j Кнопка 3 | http ://all -ebooks. com <|у Готово. ..i..:;i.v.i: ,;'■:.,; 1> ЛДМертМи^трвсеть;' Рис. 5.19. Страница стремя кнопками: вариант 1 Для определения того, какая кнопка нажата, следует всего лишь прочесть содержимое скрытого поля Button, как показано в примере 5.20. Результат выполнения скрипта в случае, если пользователь щелкнул по второй кнопке, приведен на рис. 5.20.
Кнюпки^ва|эиант_Д 171 Пример 5.20. Отображение загруженного файла, phpbuttons 1. html <HTML> <HEAD> <Т1ТЬЕ>Кнопки</Т1ТЬЕ> </HEAD> <BODY> <CENTER> <Н1>Кнопки</Н1> Нажата <?php if (isset ($_REQUEST ["Button"])) echo $_REQUEST ["Button"], "<BR>"; ?> </CENTER> </BODY> </HTML> файл Правка Цид избранное Cgpanc Справка ©•*«< * ф • a i i i b u поиск i7"^1™ с1 is щ Адрес; J Ц) http://lccalhosVphpAM/phpbuttons.php 'Щ. КПереход -.Ссылки Кнопки Нажата кнопка 2 | fjГотово ; *^V5 Местная интрасеть Рис. 5.20. Отображение нажатой кнопки
172 Глава 5. Элементы управления HTML Кнопки:вариант 2 В предыдущем разделе для определения нажатой кнопки использовался JavaScript. Но того же результата можно достигнуть, если использовать кнопку отправки вместо обычной кнопки. Для этого требуется три web-формы вместо одной, каждая со своей отдельной кнопкой отправки. Для определения того, какая из трех кнопок нажата, в каждой форме используется скрытое поле с одним и тем же именем Button, но с различными значениями в этих трех формах. Это продемонстрировано на примере 5.21. Интересно, что скрипт-обработчик при этом не меняется — он точно так же анализирует одно и то же поле с одним и тем же именем. То, что это поле описано в различных формах, неважно — скрипт всегда обрабатывает данные только той формы, в которой была нажата кнопка отправки. Пример 5.21. Страница с тремя кнопками (вариант2), phpbuttons2. html <HTML> <HEAD> <Т1ТЬЕ>Кнопки: вариант 2</TITLE> </HEAD> <BODYxCENTER> <Н1>Кнопки: вариант 2</Н1> <FORM NAME="forml" ACTION="phpbuttons.php" METHOD="POST"> <INPUT TYPE="HIDDEN" NAME="Button" VALUE="кнопка 1"> <INPUT TYPE="SUBMIT" VALUE="Кнопка 1"> </FORM> <FORM NAME="form2" ACTION="phpbuttons.php" METHOD="POST"> <INPUT TYPE="HIDDEN" NAME= "Button" УАШЕ= " кнопка 2"> <INPUT TYPE="SUBMIT" VALUE="Кнопка 2"> </FORM> <FORM NAME="form3" ACTION="phpbuttons.php" METHOD="POST"> <INPUT TYPE="HIDDEN" NAME="Button" VALUE="кнопка 3"> <INPUT TYPE="SUBMIT" VALUE="Кнопка 3"> </FORM> </SCRIPT> </CENTERx/BODY> </HTML> Внешний вид страницы приведен на рис. 5.21. Она практически ничем не отличается от рис. 5.19, за исключением того, что кнопки расположены по вертикали, а не по горизонтали. Обработчик данной формы полностью идентичен тому, который приведен в предыдущем разделе в примере 5.20 (см. также рис. 5.20).
Кнопки:вариант 3 173 >ft Internet Expl Г- lltj'llXl файл Лравка Bw убранное Сервис £правка Поиск *£> Иэбрагто, $>) ; ,;^ Л ' ^ec;|rhttp://localhost/php/05/phpbLmons2.htrnl Кнопки :вариант2 фГотоцр У* | Местная интрасеть Рис. 5.21. Страница с тремя кнопками: вариант 2 Кнопки:вариант 3 В предыдущем разделе для идентификации нажатой кнопки использовались скрытые поля, но на самом деле можно обойтись без них вовсе. При помощи атрибута "VALUE имеется возможность передать данные о кнопке PHP-скрипту, что делает использование скрытых полей ненужным. Для этого каждой кнопке отправки присваивается одно и то же имя Button (ранее это имя использовалось для скрытого поля). При этом при помощи атрибута "VALUE каждой кнопке присваивается уникальное значение, по которому они и будут различаться. Код страницы, созданной по этой схеме, приведен в примере 5.22, а внешний вид — на рис. 5.22. Обработчик данной страницы полностью идентичен двум предыдущим (см. пример 5.20 и рис. 5.20). Пример 5.22. Страница с тремя кнопками (вариант 3), phpbuttons3. html Л?*Ю^ 1Цг^ш> с Л яырл¥* V' ^-*Л :<Л.- /ЧЖг ,f-jV itVrt'v*; ■: i >_-(£ <*c Г,-* <HTML> <HEAD> <Т1ТЪЕ>Кнопки: вариант 3</TITLE> </HEAD> <BODYxCENTER> <Н1>Кнопки: вариант 3</Н1>
174 Глава 5. Элементы управления HTML <FORM NAME="forml" ACTION="phpbuttons <INPUT TYPE="SUBMIT" NAME="Button" </FORM> <FORM NAME="form2" ACTION="phpbuttons <INPUT TYPE="SUBMIT" NAME="Button" </FORM> <FORM NAME="form3" ACTION="phpbuttons <INPUT TYPE="SUBMIT" NAME="Button" </FORM> </SCRIPT> </CENTERx/BODY> </HTML> php" METHOD=" VALUE="KHonKa php" METHOD=" VALUE="кнопка php" METHOD=" VALUE="кнопка POST 1"> POST 2"> POST 3"> '> > > Файп Правка Вид Избранное Сгроис "правка 0на2Лд:©.д[Ц€И/)поиск/1с Адрес; t S_htlp://tocalhiosVphp/OS/phpbLjllons3|hlml ' в ^ й ш Ссыйкй Кнопки:вариант 3 | кнопка 1 ] [ кнопка2 | [ кнопкаЗ | jjrora»^. ,И\а-Шк '.Щ\ Мастная Hhffpacerb ' Рис. 5.22. Страница с тремя кнопками: вариант 3
175 Итоги В этой главе приведены основные сведения об элементах управления в HTML-формах. Представлены способы доступа к данным, введенным в формах. Ниже перечислены краткие итоги главы: • В описании форма атрибут ACTION задает обработчик данных формы. Если атрибут опущен, в качестве обработчика используется текущая страница. • Атрибут формы METHOD предназначен для указания метода передачи данных обработчику. • Атрибут формы TARGET задает имя фрейма, в котором будут отображен результат выполнения обработчика формы. • Для доступа к данным, введенным в форму, в зависимости от метода передачи данных может быть использован суперглобальный массив $_GET (для метода GET), $_POST (для метода POST) или SREQUEST (для обоих методов). В качестве индекса всех этих массивов выступает имя элемента управления. • Для создания текстового поля внутри формы используется тег <INPUT TYPE=TEXT>. • Многострочные поля в формах создаются при помощи тега <TEXIAREA>. • Выключатели (checkbox) описываются 'при помощи тега <INPUT TYPE=CHECKBOX>. • Списки, в которых можно выбрать один или несколько элементов, описываются при помощи тега <SELECT>. • Скрытые от пользователя данные можно поместить в форму при помощи Tera<INPUT TYPE=HIDDEN>. • Для ввода паролей и иных секретных данных используется тег < INPUT TYPE=PASSWORD>. • Кнопки-изображения создаются при помощи тега <INPUT TVPE=IMAGE>. • Для обеспечения загрузки файлов форма должна содержать атрибут ENCTYPE="multipart/form-data". Само поле для выбора загружаемого файла добавляется в форму при помощи тега <INPUT TYPE=FILE>. • Для того чтобы разместить в форме кнопку, используется тег <BUTTON>. ИТОГИ
Глава 6 **^—2,*й#*": Web-приложения В предыдущей главе описывались различные элементы управления, используемые в HTML-формах: текстовые поля, списки, выключатели и т.п. Эта глава посвящена вопросу разработки web-приложений, которые получают данные, введенные пользователем в форму, проверяют их на корректность и обрабатывают их определенным образом. В этой главе рассказывается, как определить используемый тип браузера, как выполнять проверку различных типов данных, как перенаправить пользователя на различные URL, как разместить все web-приложение в одной форме и многое другое. Ниже рассматривается структура типичного web-приложения. Функция validatedata выполняет проверку всех введенных данных (например, являются ли строки, введенные в поля, предназначенные для ввода чисел, действительно числами). При обнаружении ошибок функция заносит их в глобальный массив $ е г г о г s. Если проверка выявила ошибки, то их перечень выводится при помощи функции displayerrors, а функция displayform вьшодит форму с полями, которые содержат уже введенные пользователем значения. Если же проверка данных прошла успешно, они обрабатываются при помощи функции processdata. validate_data () ; if (count ($errors) > 0) { display_errors ( ) ; display_form (); } else { process data (); } Проверка данных на корректность и предоставление пользователю возможности исправить допущенные ошибки является значительной и весьма важной частью любого web-приложения.
1 Z § ,,^.,^^.^,„^„^„„„ Глава 6. Web-приложения Отображение данных формы В предыдущей главе уже рассматривался вопрос отображения данных, введенных в отдельные элементы управления. Для целей отладки web-приложения полезен скрипт, который может отобразить все введенные в форму данные. При разработке сложной формы можно легко допустить ошибку в названии элемента управления или присвоить двум элементам идентичное название, и такой скрипт поможет выявить подобные ошибки. В примере 6.1 приведена форма, содержащая несколько различных элементов управления. Внешний вид формы изображен на рис. 6.1. Пример 6.1. Пример сложной формы, phpformdata.html <HTML> <HEADxTITLE>npMMep сложной формы</Т1ТЬЕх/НЕА0> <BODYxCENTER> <Н1>Пример сложной формы</Н1> <FORM METHOD="POST" ACTION="phpformdata.php"> Введите Ваше имя <INPUT NAME="Name" TYPE="TEXT" > <BR> <BR> Выберите любимые фрукты: <SELECTNAME="Food[] " MULTIPLE> Апельсин</0РТ10Ы> rpyma</OPTTON> nepcHK</OPTTON> Яблоко</0РТ1СЖ> </SELECT> <BR> <BR> <INPUT TYPE=" SUBMIT" VALUE=" OK" > </FORM> </CENTERx/BODY> </HTML> Для отображения всех данных, введенных в форме, используется цикл foreach по всем элементам массива $ REQUEST. Если какой-либо элемент массива сам является массивом (это может случиться в случае использования списков с множественным выбором), используется вложеный цикл foreach. Скрипт-обработчик формы приведен в примере 6.2, результат его выполнения — на рис. 6.2.
Отображение данных формы 179 файл Правка Вид Избранное Сервис "правка $2) '<*■■* ' С) '" 'Л Li Ф i у^.поиск ^Т Избранное ^у ^ ^ A'1_1"-Utttittpy/localhost/php/06/phpformdabahtrnl ifejrk ■ре/од -ОМгА'- Пример сложной формы ВвеДИТе Ваше ИМЯ ^Сергей 3 Апельсин Выберите любимые фруюы: |явпоко (ой :<UJm" естнан интрасеть Рис. 6.1. Пример сложной формы Примерб. 2. Отображениевсехданныхформы, phpformdata.php <HTML> <HEAD> <Т1ТЪЕ>0тображение всех данных формы</Т1ТЬЕ> </HEAD> <B0DY> <CENTER> <Н1>0тображение всех данных формы</Н1> В форму были введены данные: <BR> <?php foreach ($_REQUEST as $key => $value) { if (is_array ($value)) { foreach ($value as $item) { } } else echo $key, " => ", $item, "<BR>" ;
180 Глава 6. Web-приложения } echo $key, " => ", $value,"<BR>" ; } ?> </CENTER> </B0DY> </HTML> л :«Ki" tX^a X V/ Л *>' ?ЛС*V*TJ3' Файл Правка у ид избранное Сервис Оправка Щ||Наэвд - :Ъ [ж] ygfj .«j: yJ ГЪтх '-Укйрнное -0 ;^ Адресу. Щ http://localhc.5t/php/0eyphpfcxmdata.php а Отображение всех данных формы В форму были введены данные: Name=> Сергей Food => Груша Food => Персик ^Готово i "j^f МосшаЯ'Иктрасатъ Рис. 6.2. Отображение всех данных формы Переменные сервера В РНР существует специальный суперглобальный массив SSERVER, который содержит различные переменные web-сервера, которые могут быть полезны при разработке web-приложений. Например, переменная SSERVER ["PHPSELF"] содержит имя текущего скрипта, переменная SSERVER [ "REQUEST ME I HOD" ] содержит название метода передачи данных («GET» или «POST»), и т.п. Наиболее употребительные серверные переменные в табл. 6.1. Замечание PHfttArtQii»;yi'iw<»»tg*w>a»J*>W««W ■)■>! Щ р Массив $_SERVER введен, начиная с РНР4.1.0. До этой версии использовался гло- J бальный массив $HTTP_SERVER_VARS, которые внутри функций требует обязательного объявления припомощи операторад I о bal .Начиная сверсииРНРб. О, этот массив перестал поддерживаться. i .JJwV п: bi.v^niKCt'w i№p(fHC7CVM<c^<. и--^>0^ь^а^^о^^амя^УГ»0У>С>и1|»МУ<< к» «хдлгумпрц <УЛСТЛГ*Ч> «n< *x&M? 1Ч»и>.»ЖУ»У,«" V
Переменныесервера 181 Таблица 6.1. Серверные переменные Переменная Описание Если РНР используется вместе с web-сервером Apache а режиме модуля, переменная содержит тип аутентификации. 'AUTH TYPE' ' DOCUMENT_ROOT ' Корневой каталог web-сервера, предназначенный для хранения HTML-документов, в соответствии с его конфигурацией — т.н. корень. ' GATEWAY_INTERFACE ' ' PATH—TRANSLATED ' Версия спецификации CCI, которая поддерживается web-сервером, например ' С G I / 1 . 1 ' . Полное локальное имя файла текущего скрипта. PHP_AUTH_PW ' PHP_AUTH_USER ' Если РНР используется вместе с web-сервером Apache в режиме модуля, переменная содержит пароль пользователя, введенный в окне аутентификации. Если РНР используется вместе с web-сервером Apache в режиме модуля, переменная содержит имя пользователя, введенное в окне аутентификации. "PHP_SELF' QUERY_STRING' Путьктекущемускриптуотносугтепьнокорня. Строкаэапроса, переданная скрипту. Задается для метода передачиданныхОЕТ, имеегвид: namel = valuel&name2 = value2... \Р-адресудапенногопопьзоватепя,которыйзапросипданный скрипт. ' REMOTE_ATTR ' Имяузлаудаленногопользователя,которыйзапросилданный скрипт. REMOTE_HOST' ' REMOTE—PORT ' Номер порта удаленного пользователя, который запросил данныйскрипт. 'REQUEST_METHOD' 'REQUEST_URI' ' SCRIPT—FILENAME ' 'SCRIPT_NAME' ' SERVER_ ADM IN ' 'SERVER_NAME' 1SERVER_PORT ' Методпередачи данных, лрипомоиди которого былэагружен данный скрипт — GET', HEAD, POST или PUT. UR/1 текущего скрипта, например '/index, php' . Полное абсолютноелокальное имя скрипта. Путь к текущему скрипту относительно корня. E-mail администратора web-сервера. Имя хоста web-сервера. Порт web-сервера (обычно 80). URI (Uniform Resource Identifier) — универсальный идентификатор ресурса, введен в августе 1998 года стандартом RFC 2396. Расширяет и уточняет введенный ранее URL (RFC 1738 и 1808). Имеет абсолютную и относительную формы. — Прим. ред.
182 Глава 6. Web-приложения Переменная Описание 'SERVER_SIGNATURE' Наименование и версия протокола, используемого\/\/еЬ-сер- ' SERVERPROTOCOL' вером для обмена информацией с браузером, например, 'НТТР/1.0'. _______^__ Строга, содержа щаяверсию\лгеЬ-сервераиназваниехоста, которая добавляется кавтомаллчесюлгенерируемымстраницам. SERVER SOFTWARE' Строка, идентифицирующая название и версию программно- ~~ го обеспечения web-сервера. Серверные переменные могут быть весьма полезны при разработке приложений. Ниже приведен пример отображения имени текущего скрипта: <ШМ1> <НЕАБхТ1ТЬЕ>Идентификация CKprarra</TITLEX/HEAD> <BODY> <Н1Идентификация скрипта</Н1> <?php echo "Текущий скрипт: ", $ SERVER ['PHP SELF']; ?> </BODY> </HTML> В результате выполнения будет выведена строка наподобие: Текущий скрипт: /php/06/phpidentifier.php Заголовки HTTP Кроме элементов, перечисленных в табл. 6.1, массив $_SERVER содержит также информацию из заголовка HTTP-запроса. HTTP-запрос посьшается web-серверу клиентом, а его заголовок содержит полезную информацию о браузере. Например, $_SERVER ['HTTPUSERAGENT'] содержит информацию О версии браузера (определению типа браузера посвящен следующий раздел главы). В табл. 6.2 перечислены те элементы массива SSERVER, которые заполняются на основании заголовка HTTP-запроса. В зависимости от версии протокола и типа браузера те или иные поля в заголовке HTTP-запроса могут отсутствовать. Таблица6.2.ПеременныезаголовкаНТТР-запроса Переменная Поле заголовка Описание 1 HTTP ACCEPT' Accept: Перечисление через запятую MIME-коди- ровок типов данных, которые может обработать браузер. ■ нттр_АССЕРТ_ CHARSET1 А t-Cri ссер Перечисление кодировок, которые поддер- браузер. 1 НТТР_АССЕРТ_ ENCODING ' Accept-Encoding: Способы сжатия информации, которые поддерживает браузер, например, gzip.
183 Переменная Поле заголовка Описание НТТР_АССЕРТ_ LANGUAGE' НТТР_ CONNECTION' Accept-Language: Connection: Обозначениеязыка.которыйможегкор- рею"но отображать браузер, например en (английский) или г и (русский). Полеуправляетсоединениемс\/\/еЬ-сервером, обычно содержал"значение Keep-AI ive. 'HTTP-HOST1 Host: Имя хоста, к которому обращается браузер. ' HTTP-REFERER1 Referer: 'HTTP_USER_ AGENT' User-Agent: Адресстраницы, скоторойосуществляет- сяпереход на запрошенную страницу. Заполняется браузером только в том случае, если переходосуществляетсяпо гиперссылке (а не путем ввода адреса в соответ- ствующее поле браузера). Строка, идентифицирующая браузер. Определение типа браузера При разработке web-приложений очень важно иметь представление о той среде, в которой оно будет функционировать. А эта среда включает в себя браузер, который отвечает за отображение информации на экране компьютера. Различные браузера отличаются между собой по функциональности; например, Internet Explorer поддерживает тег <MARQUEE>, а другие браузеры — нет. Поэтому если нет уверенности, что клиент использует именно браузер Internet Explorer, то не стоит использовать этот тег при построении HTML-страниц. Для определения типа браузера можно использовать элемент массива SSERVER [ ' НИР USER AGENT ]. Например, если значение этого элемента содержит строку ' MSIE' (что проверяется при помощи функции strpos), то используется Internet Explorer. Подобная проверка продемонстрирована в примере 6.3. Пример 6.3. Описание простой формы с одной кнопкой, phpbrowser. html afrW,«ilB«№*MH*»e«lW kT>№4 -:^г,*а =4t4v: /ХЯ&.'. * <RTML> <HEAD> <Т1ТЬЕ>Определение типа 6pay3epa</TITLE> </HEAD> <BODY> <CENTER> <Н1>0пределение типа браузера</Н1> <FORM METHOD="POST" ACTION="phpbrowser.php"> Нажмите кнопку <INPUT TYPE =" SUBMIT" VALUE= "OK" > </FORM> </CENTER> </BODY> </HTML>
184 Глава 6. Web-приложения На рис. 6.3 представлен внешний вид простой формы с кнопкой, после нажатия на которую загружается РНР-скрипт. В скрипте (пример 6.4) производится проверка на тип браузера. В случае Internet Explorer используется тег <MARQUEE>, в противном случае — стандартный тег <Н1>. файл Правка Вт избранное Сервис Справка па« <^ fefemt* 4&] А# iSi * Ацрес; \$ http://locdhost/php/D6/phpbrcwser.hl:ml jg|j Q Гкрежд Сея»» Определение типа браузера Нажмите кнопку И ij£| Готово Щ Мвстиад интрассть II м I ii-iiI ■i^uMJjiiiMM.iMM Рис. 6.3. Определение типа браузера Пример6.4.0пределениетипабраузера,рЬрЬго\мзег.рЬр /d?<vj? рччим i^mni*x»jvsown< t*ri<wxvHa*xrt&v*&>K<wjm<rA v ammo *м я i шяч i ВДА>КЖШПЯСТИ)РИЯЯДГ»0Я»О«Ж|ЦПОИЮ(ЛМ1 <HTML> <HEAD> <Т1ТЬЕ>0пределение типа браузера</Т1ТЬЕ> </HEAD> <BODY> <CENTER> <Н1>0пределение типа браузера</Н1> <BR> <?php if (strpos ($_SERVER ["HTTP_USER_AGENT"], "MSIE")) { echo ("<MARQUEExHl>Bbi используете Internet Explorer</Hlx/MARQUEE>"); } else
jnepejHang^/^HMe^ 185 { echo ("<CENTERxHl>Bbi используете не Internet Explorer</Hlx/CENTER>"); } ?> </CENTER> </B0DY> </HTML> ■штм1>¥Ц1птг«<111гм1'<)>и1Д tfiMiiwn mjiwiiT iwnr ш—> танин firm» ^ticmnafcim^nni immai tn 11 n win ммь'^мпелсямхга кдеичшдоюмчэ л сдочхлф %v йьа: у* * •/nrp лх r-r- w и*.Л"» Результат представлен на рис. 6.4. В реальности надпись будет проплывать слева направо, но на печати этот эффект отобразить затруднительно. файл £1равка Цид Избранное Сервис Справка ©teM • ф- э N Ф: Р"* Л-*~~ 6;1 в Адрес! |§ http://localhost/php/06/phpbrawser.php Q Переезд '-супки Определение типа браузера Вы используете Internet Explorer £j Готово !*Йм. естная имтрасеть Рис. 6.4. Используется Microsoft Internet Explorer Перенаправление Наряду с чтением HTTP-заголовков имеется возможность формировать свои собственные заголовки. Одним из наиболее используемых заголовков является «Location», который осуществляет перенаправление браузера на указанную страницу.
186 Глава6>. Web-прилюжения" Для создания заголовка используется функция header. В частности, для создания заголовка, который перенаправит браузер на заданный адрес, используется вызов header ("Location: URL"). Например, требуется создать страницу с тремя кнопками, каждая из которых осуществит перенаправление на один из примеров из предыдущей главы — phpbuttons, phplistbox или phptextarea. Для этого используется три различных формы, каждая из которых содержит единственную кнопку отправки. В атрибуте "VMJJE каждой кнопки содержится имя скрипта, на который следует осуществить перенаправление. При этом для всех трех форм используется один и тот же скрипт-обработчик. Это продемонстрировано на примере 6.5. Примерб. 5. Описаниеформыдлявыбораварианта перенаправления, phpredirect. html ■ *Оч№<^Э« НО» rIXa^1gy,v б** ч у 'мЩ* ■rrMi иСШ&АШЫКУГКк Щ»! <HTML> <HEAD> <Т1ТЪЕ>Перенаправление пользователж/Т1ТЬЕ> </HEAD> <BODY> <Н1>Перенаправление пользователя;/HI > Выберите скрипт для загрузки <FORM NAME="forml" ACTION="phpredirect.php" METHOD="POST"> <INPUT TYPE="SUBMIT" NAME="Button" VALUE="phpbuttonsl" > </FORM> <FORM NAME="form2" ACTION="phpredirect.php" METHOD="POST"> <INPUT TYPE="SUBMIT" NAME="Button" VALUE="phplistbox"> </FORM> <FORM NAME="form3" ACTION="phpredirect.php" METHOD="POST"> <INPUT TYPE="SUBMIT" NAME="Button" VALUE="phptextarea"> </FORM> </SCRIPT> </BODY> </HTML> .■•.«^^V«*^^.^>-34'«r.reO»>^^>"-»raK^-^^4Vd4U>tri|^>gi№T^1lir«*r»rei^ 1Ш ■!! 1ММИММИ Если пользователь щелкнет по одной из трех кнопок на форме (см. рис. 6.5), имя выбранного скрипта будет передано обработчику, который представлен в примере 6.6. Пример 6.6. Выполнениеперенаправления, phpredirect. php ■V. ■■■<;'* i;'-."-'iL4-:!:. * ■ . -V,- Л" V*.-.^i\l .'.)'.ЧГ*"-'/ .«<**\'Л I I I I I II II ll I l|lll II 141 III! Ш|1 | ll | Ill || III H H M |MI и 1|И Щ Pl> III 1|<>|« W ||I| I II И111 IHIWWI1 Wl 111 IIHlll l<ll P I <?php $redirect = "Location: " . $_REQUEST ['Button'] . ".html1'; echo header($redirect); ?>
Организация полей форм в массивы 187 файл рраека Вид Избранное Сервис Справка Ф -■ О '■ Ш Ш ф'\/)пояа* ТПрэннсе ф\% Ш * Адрес; |"http://localhost/php/06/phpredirect,Mml ujk i 3 Переход ; Ссылки Перенаправление пользователя Выберите скрипт для загрузки ! phpbuttonsi I phplistbox [ phptextarea ФГотово (^^^J^^^j^^^^^ ■ 4;i Местная интрасеть Рис. 6.5. Форма для выбора варианта перенаправления Для выполнения перенаправления скрипт используется функция header1. Например, если пользователь нажал на вторую кнопку, будет загружена страница phplistbox.html (рис. 5.9). Перенаправление, в частности, эффективно для создания областей перехода на кнопках-изображениях. При этом сначала проверяются координаты точки, по которой был произведен щелчок, а потом пользователь перенаправляется на соответствующую страницу: <?php if ($_REQUEST ["imap_x"] > 50 && $_REQUEST ["imap_x"] < 70) { if ($_REQUEST ["imap_^" ] > 3 0 && $_REQUEST ["imap_^" ] < 90) { $redirect = "Location: www.php.net"; header ( $redirect); Заголовки, формируемые функцией header, могут быть отправлены только до начала формирования собственно HTML-страницы. Поэтому если в примере случайно вставить пустую строку до тега <?php, то перенаправление работать не будет, а вместо этого будет выведено сообщение "Warning: Cannot modify header information - headers already sent by". — Прим. ред.
188 Глава 6. Web-приложения Организация полей форм в массивы Существует интересная возможность организации данных, введенных в различные поля HTML-формы, в массивы. Например, имеется форма с двумя текстовыми полями — имя пользователя и его любимый цвет — и требуется запомнить эти данные в элементах массива $ text ['name'] H$text ['color'] соответственно. Для этого в качестве имени поля следует использовать выражение с квадратными скобками вида textdata [name], как показано на примере 6.7. Соответствующая форма представлена на рис. 6.6. 3 lk-ii...n,'.,.ii. о к-кс|.чч.|\ п.чоп -\1kr..v.|iinu'iiK'i I \pl.4vr ■'- файл Правка Цид .Избранное Сервис Справка 'У''1-*' " Й*| ' 1*4 \Щ ■p-tiJ>-JI"~ •■;~;\Шрятх. " Ц^: ф^. ;.Й ' ;'*ряс; JU1 httpi//localhost/php/06/phj)cextarrayJitml -*\ fQ Первжж Использование текстовых полей Введите Ваше ИМЯ: !Сергеи I Ваш любимый цвет: | ОН^Й | ^Готово '."ЩМестнаяиктрасеп» . fcirX: ; .*. ■Ссылки Рис. 6.6. Форма с полями-элементами массива Примерб. 7. Описаниеформысполями-элементами массива, phptextarray. html I и:*жхУХЛГ *«*«■:: i.-.c/j*!4,j4/sW'f'.*iKtowr-m' : мяфри*.*.-*. mi* IX ь *Я' LfvO*: i^ft,- К г. r-<* ". <х*Л1*Х}иаххЬ*#»ф*<пг& -*fl«f. СМС>*аЮЛ <HTML> <HEAD> <TITLE> Использование текстовых полей </ТТТЬЕ> </HEAD> <BODY> <CENTER> <Н1>Использование текстовых полей</Н1>
Организация полей форм в массивы 189 <ГОКМ METHOD="POSr ACTION = "phptextarray.php"> Введите Ваше имя: <INPUT NAME="textdata[name]" TYPE="TEXT"> <BRxBR> Ваш любимый цвет: <INPUT NAME="textdata[ color] " TYPE= " TEXT" > <BRxBR> <INPUT TYPE=SUBMIT VALUE="OK"> </FORM> </CENTER> </BODY> </HTML> 1Щ*»ХЖД\П<уЬ#*СНОиЛ *<дЮЧа/&Х*4й^ЪПЯ^1Л1уЛКЗ*&&>&0НЮ1**я0>1О&Ю& Х»* оМКДОсЧУз) f&)l 1УМсфОУЛИ'.^Су^^/Л!. V. с k лл 14 Для того чтобы сохранить введенные данные в массиве Stext, используется соответствующий элемент массива $_REQUEST, как показано на примере 6.8. Результат выполнения примера приведен на рис. 6.7. Л II.'. файл ©" Адрес я формы - ..км.пи.1 миссии.. - \licr..s..|i In Правка у ид избранное Сервис ^правка ид * Ш ' U Ш № : Т",П0,,СК iiff] http:>/localhost/php/06/phptextarray.php Поля формы 01П01 1 ЛрК1 AlWpamO» '01' eu^ & ШШШ *■ V.' ДД Переход £СИЯ~У. - элементы массива Ваше имя: Ваш любимый •I Готово Сергей цвет: синий ■ *з Устная интрасеть Рис. 6.7. Содержание формы с полями-элементами массива
190 Глава 6. Web-приложения Пример 6.8. Поля формы — элементы массива, phptextarray.php .■:.■.-.•:'. - " .i.ii' н Г.1 "ГГ Ti r-firiliiTiriill 1П ГГП nrri.i.ij I JI juili i; I l.'i * 14 Л Л «»i:«i|iw»l.i:i:ninmif ilIipW»^>4llHi llllli» ЧЦПЦиИл <HTML> <HEAD> <TITLE> Поля формы - элементы массива </ТТТЬЕ> </HEAD> <B0DY> <CENTER> <Н1>Поля формы - элементы массива</Н1> Ваше имя: <?php $text = $_REQUEST ['textdata']; echo $text ['name'], "<BR>"; ?> Ваш любимый цвет: <?php echo $text ['color'], "<BR>"; </CENTER> </B0DY> </HTML> *.■■•■€' * .г i г • i i г. i i г ц- it i •пччттптггг'гттшп i..r ) p щг итш;л' nij|]..iiiiiii.>ifi|iiiii|ifn^rfi'тгиищц щи \ц} т\\\1\Щшчк\тплшт\ Организация данных в массивы может быть удобна для построения сложных форм с большим количеством полей. Приложение из одной страницы До этого момента все рассмотренные web-приложения использовали два файла — статическую HTML-страницу, содержащую описание формы для ввода данных, и скрипт-обработчик на РНР. Но большое количество web-приложений используют единственный PHP-файл, который содержит весь необходимый код. Например, требуется разработать приложение, которое запрашивает имя пользователя и затем отображает его — все при помощи одного скрипта. Для этого требуется уметь определять, первый ли это запуск скрипта, и в этом случае показывать форму для ввода данных (часто ее называют заглавной страницей). С другой стороны, если пользователь уже ввел данные, то их требуется обработать. В данном примере используется текстовое поле с названием "Name", в которое пользователь вводит свое имя. Для проверки на наличие данных в этом поле используется функция isset. Если пользователь ввел данные, они будут содержаться в элементе массива SREQUEST [ "Name" ]. Если же это первый запуск скрипта, следует сформировать форму для ввода данных, как это сделано в примере 6.9.
Приложение из одной страницы 191 Пример 6.9. Web -приложение в одном скрипте, phpsingle.php 1*К|Щ|»итМ1ИЦ*Лри»И«1'*Г l»*l"*l^llJlLlO«m*tM IWUMItftlMWfllwWplCinWKIMfUll.WiPllfrnrnTlWfiri Г*.ИГцТГ—•ЦПИИГГиГЦНПГТПГ •11>-|[*-мГ1ТГ|1И|1Т-|ГПГГТГ1^1ТТГЩ«ПН1И1ИИ~*11Т <HTML> <HEAD> <Т1ТЬЕ>Ввод и отображение имени пользователя^Т1ТЪЕ> </HEAD> <B0DY> <CENTER> <?php if (isset ($_REQUEST ["Name"])) { ?> <Н1>0тображение имени пользователж/Н1> Ваше имя <?php echo $_REQUEST ["Name"]; } else { ?> <Н1>Ввод имени пользователж/Н1> <F0RM METHOD="POST" ACTION="phpsingle.php"> Введите Ваше имя <INPUT NAME="Name" TYPE="TEXT"> <BR> <BR> <INPUT TYPE=SUBMIT VALUE="OK"> </FORM> <?php } ?> </CENTER> </BODY> </HTML> Следует отметить, что использование атрибута ACTION в теге КЖМ является необязательным, так как в случае его отсутствия управление при нажатии кнопки отправки «ОК» будет передано текущему документу. Результат первого запуска скрипта приведен на рис. 6.8, а после ввода имени пользователя и нажатия кнопки «ОК» экран примет вид, изображенный на рис. 6.9.
Глава 6. Web-приложения £айл Правка Дид Избранное Сервис Справка '"-ilpecL:, j ij http://localhost/php/06/phpsjngle.php Фш. m ?*;:r fcj Переход'- -Ссылки Ввод имени пользователя Введите Ваше имя [Одяш!,_ ■£]ГОТОВО Местная интрасеть Рис. 6.8. Запрос имени пользователя файл Правка Вид Избранное Сервис Справка фн«.-ф Й Ш Ф ;Рпоиск %"*— 0Ч* & - ► е-' i ё] http://localhost/php/06/phpsjngle.php C Отображение имени пользователя Ваше имя Cqjrefl YjjsJrofnUo :*JM естнаяинтрасеть Рис. 6.9. Отображение имени пользователя
Проверка данных 193 Проверка данных При разработке приложений весьма важной является проверка введенных данных на корректность и отображение адекватных сообщений об ошибках ввода при их наличии. В этом и следующих разделах рассматриваются вопросы проверки корректности данных различных типов. В предыдущем разделе данные в текстовом поле использовались для проверки факта повторного вызова скрипта. Подобный прием не всегда является корректным, так как поля данных могут быть не обязательными для заполнения. Вместо этого для этой цели часто используется скрытое поле. Если поле не определено, следовательно, это первый запуск скрипта, и необходимо сформировать заглавную страницу. В коде это выглядит следующим образом: if (isset ($_REQUEST [ 'seen_already' ] ) ) { } else { displayform () ; } Если форма для ввода информации уже была заполнена, следует произвести проверку введенных данных на корректность. Для этого предлагается использовать функцию validatedata, которая при обнаружении ошибок заносит их описание в глобальный массив Serrors. Если после вызова validatedata массив Serrors не является пустым (что легко проверить при помощи функции count), осуществляется вывод всех сообщений и повторное отображение формы для ввода данных для того, чтобы пользователь имел возможность исправить допущенные ошибки. Если же ошибок не обнаружено, можно перейти к обработке данных: $errors = array () ; if (isset ($_REQUEST ['seen_already'])) { validate_data ( ) ; if (count ($errors) > 0) { display_errors () ; display_form ( ) ; } else { process_data ( ) ; } } else { display form (); } В следующих разделах будут рассмотрены различные реализации функции для проверки данных validatedata, в зависимости от структуры формы. Функция displayerrors предназначена для отображения всех сообщений 06 ошибках и может выглядеть следующим образом: 7 РНР в примерах
194 ___^ ___^_^^. м^Х£2.в51ё,^'ЛЬЛЕ^лс,жения function displayerrors () { global Serrors; foreach (Serrors as $err) { ■i echo $err . ' <BR> ' ; } Функция processdata для обработки данных может иметь любой вид в зависимости от решаемой прикладной задачи. Наконец, функция displayform отображает форму для вводаданных. Форма может содержать любую комбинацию полей, но в любом случае в ней должно присутствовать скрытое поле seenalready, которое используется для определения факта повторного запуска скрипта: function displayform () { echo "<FORM МЕГНОЕ^ГСЖГ ACTION='phpvalidate.php'>"; echo "<INPUT TYPE=' SUBMIT' VALUE =• OK '>" ; echo "<INPUTTYPE='HIDDEN1 NAME='seen_already' VALUE= ' data ' >" s echo "</FORM>"; } Обязательное для заполнение поле Проверка на наличие данных в определенном поле требуется достаточно часто. Например, приложение запрашивает у пользователя его имя (см. рис. 6.8) и отображает его (см. рис. 6.9). Если поле заполнено, все функционирует корректно. Но что делать в том случае, если пользователь оставил текстовое поле пустым? Для этого функция validatedata выполняет проверку на наличие данных в поле Name и в случае, если это не так, добавляет сообщение об ошибке в массив Serrors: Функция processdata просто отображает введенное имя, а функция displayform выводит форму с единственным текстовым полем. Все приложение целиком приведено в примере 6.10. Примерб. 10. Поле, обязательное для ввода, phpvalidate.php *»^^P*Wi»|iWl^M»4r>j^W|Mg.*W«C'r»l'**^4'*t^ <HTML> <HEAD> <Т1ТЬЕ>0бязательное поле</Т1ТЬЕ> </HEAD> <BODYxCENTER> <Н1>0бязательноеполе</Н1> <?php $errors = array () ; if (isset ($_REQUEST ["seen_already"])) { validate_data ( ) ;
Обязательное для заполнение поле 195 if (count ($errors) > 0) { display_errors (); display_form (); } else { process_data() ; } } else { display_form (); } function validate_data () { global Jerrors; if ($_REQUEST ["Name"] == "") { $errors[] = "<FONT COLOR='RED'>Имя обязательно для BBOfla</F0NT>"; } } function display_errors' () { global $errors; foreach ($errors as $err) { echo $err, "<BR>"; } } function process_data() { echo "Ваше имя ".$_REQUEST ["Name"]; } function display_form() { echo "<F0RM METHOD='POST' ACTION='phpvalidate.php'>"; echo "Введите Ваше имя"; echo "<BR>"; echo "<INPUT NAME='Name' TYPE='TEXT'>"; echo "<BRxBR>"; echo "<INPUT TYPE=SUBMIT VALUE='OK'>"; echo "<INPUT TYPE=HIDDEN NAME='seen_already' VALUE= 'dataV' ; echo "</F0RM>"; </CENTERx/BODY> </HTML>
196 Глава 6. Web-приложения Теперь, если пользователь не ввел ничего в текстовое поле, будет отображено сообщение об ошибке, как показано на рис. 6.10. Ц Обязательнее поле - Microsoft Internet Explorer с£аил £|равка Вид избранное Сервис Справка fj) Назад - -,v-i_ ■■ >\Г ib]\ . j Vy- Псиж . "V ИЭфа+ое -Q/ : " mi _ пЬТ":_ \4U rfflp://tocalhcBt/php/Q6/phpvalidate.php Обязательное поле Имя обязательно для ввода Введите Ваше имя III •J?] Готово .,■..'■.■.■■.'.'.' i ■■,.:'- .-.' uMl® :.#. 'у |. Q Передо, : Ссьтек- http://all-ebooks.com ■ * Местная интрасеть . ..-.! Рис. 6.10. Обязательное поле не заполнено Проверка числовых полей Часто требуется проверить, что в поле введено целое или вещественное число, а не просто строка. Одним из наиболее простых способов является преобразование строки в число (при помощи функции intval или floatval для целых или вещественных чисел соответственно) и затем обратно в строку, а затем сравнение исходной и полученной двойным преобразованием строки. Если они совпадают, то исходная строка содержит корректное число1. Для сравнения строк можно использовать функцию strcmp, которая возвращает ненулевое значение, если заданные ей как параметры строки различны. Ниже в примере 6.11 приведена подобная проверка для целых чисел. * iAW'J.:^..|V: JbgyTTWgK^J W!<rJe.Ka*Als:><^*^?J&4**r«rJ4M>neA!y]V4OVS0<4MrfrB^:^'-^}w**AiM^**^M»* Для проверки строки на предмет того, представляет ли она число, можно также использовать функцию is numeric. Но при этом нет возможности различить целочисленные и вещественные значения. —Прим. ред.
JDfi9SE5!SJlt!!£iI2.BblxI12£!E^_. „ ^^ Пример 6.11. Поле, обязательное для ввода, phpinteger.php кяшмштшш дистыц—нт Им» и и* *1*тс*жс*&&*&*Хму***ж&л&з&г**Фу*-яяттль y»a-»"m^<w*>^<г- ■'»--v*>e**r»w**?/■- <HTML> <HEAD> <Т1ТЬЕ>Целочисленное поле</TTTLE> </HEAD> <BODYxCENTER> <Н1>Целочисленное поле</Н1> <?php $errors = array ( ) ; if (isset ($_REQUEST ["seen_already"])) { validate_data (); if (count ($errors) > 0) { display_errors () ; display_form (); } else { process_data (); } else { display_form (); } function validate_data () { global $errors; if (strcmp ($_REQUEST ["Number"], strval (intval ($_REQUEST ["Number"]) ) ) ) { $errors[] = "<FONT COLOR='RED'>Следует ввести целое 4Mcno</FONT>"; } } function display_errors () { global $errors; foreach ($errors as $err) { echo $err, "<BR>"; } } function process_data() { echo "Целое число равно ".$_REQUEST ["Number"]; ■}
198 Глава 6. Web-приложения function display_form(I echo "<FORM METHOD='POST' ACTTON='phpinteger.php'>"; echo "Введите целое число"; echo "<BR>"; echo "<INPUT NAME='Number' TYPE='TEXT'>"; echo "<BRxBR>"; echo "<INPUT TYP'E=SUBMIT VALUE =' OK1 >" ; echo "<INPUT TYPE=HIDDEN NAME='seen_already' VALUE='data'>"; echo "</FORM>"; } ?> ■</CENTERx/BODY> </HTML> Если пользователь ввел некорректное число, то будет отображено соответствующее сообщение об ошибке, как на рис. 6.11. "Goft Intel net Explorer $айп Правка бид Избранное Сервис Оправка @Назад ■ § Л§ [| |л;/~>Поиск лу= )Л£щне ф \ /Jj AAP«t|"http://localhost/php/06/phpinteger,php Ы№ gi щ7- S"\ Н'.Шрвхсш. Ссылки (("Готово Целочисленное поле Следует ввести целое число Введите целое число еж : ^Г*СТ«ЧЯ ИМТрквть Рис. 6.11. Целоечисло не введено
строковых полей 199 Проверка строковых полей Нередко возникает задача проверить текстовое поле на соответствие определенным критериям. Например, требуется проверить, содержит ли заданное текстовое поле слово «РНР». В РНР имеется мощный механизмрегулярныхвыражений, который позволяет решать подобные задачи. Полный обзор регулярных выражений выходит за рамки данной книги (дополнительную информацию можно получить, например, по адресу www. php.net/manual/ru/ref.pcre.php). Данную же задачу можно решить при помощи регулярного выражения ' /php/i'. Для этого используется функция pregmatch, как показано в примере 6.12. Пример 6.12. Проверкастроковогополяприпомощи регулярноговыражения,рпргеди!агexpressions, php <HTML> <HEAD> <Т1ТЬЕ>Использование регулярных выражений</Т1ТЬЕ> </HEAD> <BODYxCENTER> <Н1>Использование регулярных выражений</Н1> <?рпр $errors = array () ; if (isset ($_REQUEST ["seen_already"])) { validate_data (); if (count ($errors) > 0) { display_errors () ; display_form (); } else { process_data ( ) ; } } else { display_form (); } function validate_data () { global $errors; if (!preg_match (' /php/i' , $_REQUEST ["Text" ] ) ) { $errors [] = "<FONT COLOR='RED'>B тексте должно быть слово \"PHP\"</FONT>"; } }
200 Главаб, Web-приложения function display_errors () { global $errors; foreach ($errors as $err) { echo $err, "<BR>"; } } function process_data () { echo "Вы сказали: ".$_REQUEST ["Text"]; } function display_form () { echo "<F0RM METH0D='POST' ACTI0N='phpregular_ expressions.php'>"; echo "Скажите что-нибудь про PHP:"; echo "<BR>"; echo "<INPUT NAME='Text' TYPE='TEXT' >" ; echo "<BRxBR>"; echo "<INPUT TYPE=SUBMIT VALUE= ' OK ' >" ;. echo "<INPUT TYPE=HIDDEN NAME='seen_already' VALUE='data'>"; echo "</F0RM>"; } ?> </CENTERx/B0DY> -J/HTMI> Если пользователь ввел строку, не содержащую слово «РНР», то будет отображено соответствующее сообщение об ошибке, как на рис. 6.12. Удаление тегов HTML При обработке введенного текста необходимо обратить внимание на следующую деталь, в особенности, если строку потом планируется отображать. Пользователь может использовать при наборе текста теги HTML (в том числе и выражения на JavaScript) что может повлиять на корректность работы приложения при использовании этого текста для формирования страницы. Для предотвращения этой ситуации можно использовать функцию striptags, которая удаляет из заданной строки все теги, что и продемонстрировано в примере 6.13.
Удаление тегов HTML с£айл Правка Вид .Избранное Сервис Справка ©Назад Ц ■ gj [jg fjj I рПонск -"Избранное ф Адрес; i"http://localhosyphp/06/phpregularexpressions.php * -gi Щ Переход Ссыпке Использование регулярных выражений В тексте должно быть слово "РНР" Скажие что-нибудь про РНР: ® £Готск ittt^miHimiMamliiiiiiim ■*± естнан интрасеть Рис. 6.12. Введена некорректная строка Примерб. 13. Удаление тегов из введенного текста, phpstrip.php <•£»«*-яг. *j*MM<WHI*A«Cm-<faw;U4W4ЯЛЛиСМХг?хЖ0^еЮ&УъЯГ*У&&ЙГ^ГРГЯЛЩ1У**Ю<г&Ж11&ЯХэ4*'-- <HTML> <HEAD> <Т1ТЬЕ>Удаление тегов</Т1ТЬЕ> </HEAD> <BODYxCENTER> <Н1>Удаление тегов</Н1> <?php $errors = array ( ) ; if (isset ($_REQUEST ["seen_already"])) { validate_data ( ) ; if (count ($errors) > 0) { display_errors ( ) ; display_form () ; else {
202 Глава 6. Web-приложения process_data(); } } else { display_form (); } function validate_data () { global $errors; if ($_REQUEST ["Name»] == "") { $errors [] = "<F0NT COLOR='RED'>Имя обязательно для BBOfla</F0NT>"; } } function display_errors () { global $errors; foreach ($errors as $err) { echo $err, "<BR>"; } } function process_data() { echo "Ваше имя: " ; $ok_text = strip_tags ($_REQUEST ["Name"]); echo $ok_text; } function display_form() { echo "<F0RM METH0D='POST' ACTI0N='phpstrip.php'>"; echo "Введите Ваше имя"; echo "<BR>"; echo "<INPUT NAME='Name' TYPE='TEXT'>"; echo"<BRxBR>"; echo "<INPUT TYPE=SUBMIT VALUE='OK'>"; echo "<INPUT TYPE=HIDDEN NAME='seen_already' VALUE='data'>"; echo "</F0RM>"; } ?> </CENTERx/B0DY> </HTML>
Удаление тегов HTML 203 Теперь, если пользователь введет текст, содержащий HTML-теги (как на рис. 6.13), то при формировании страницы теги будут удалены, и потенциальная угроза безопасности приложения будет устранена (см. рис. 6.14). файл Бравка ср< избранное сервис Справка ■;"* - iLULU #й ! £ЗГОлх. '^№фв+се Ж& "■ >& ш_ AAB'YfSI] Ht1p://localhosyphp/06/phps1rip.php Л ЛьМ,!Зайя&..«йа1№". Удаление тегов Введите Ваше имя |<Ь>Сергей</Ь>| | ЭК Рис. 6.13. Попытка ввода HTML-тегов файл Правка Вид Избранное Сервис ^правка OH»«*1-33mti;"J-;™fj"*— е 4Ь ш Адрес;. [U_http:№caJhosVphp/06/php5lrip.php ■?з1 Б Переход ;. Ссылки Удаление тегов Ваше имя: Сергей jfl Гогрво. ': Щ Местная Иилрасеть Рис. 6.14. Текст отображается без тегов
204 Глава 6. \Л/еЬ; приложения Кодирование тегов HTML В предыдущем разделе теги просто удалялись из текста. Но что делать, если требуется отобразить текст, содержащий HTML-теги, но при этом еще и обеспечить безопасность приложения? В этом случае уместно использовать функцию htmlentities, которая осуществляет кодирование тегов, преобразовывая их в последовательность специальных символов. Например, текст "<В>Васж/В>" будет преобразован в строку " &lt; B&gt; Bacn&lt; /B&gt; ", которая при отображении ее браузером будет выглядеть как исходная строка. Использование этой функции приведено в примере 6.14. Замечание * J iv«4iv ....^-тч^-^ УЛ1. . ■»—*№вШТЧ1»,Ч»..ИЩЦ|1]|Л1иЛР |l Iff^WIWH Ш'ШИПК'щП 1И>||11 Щ ^ Начиная с РНР 4.0.3, в функцию добавлен второй необязательный параметр f quote_style, который задает способ преобразования кавычек. Возможные его значенияприведенывтабл.6.3. Начиная с РНР 4.1.0, в функцию добавлен третий необязательный аргумент charset, задает используемую кодировку текста. При обработке англоязычных данных это не так важно, но при работе с кириллицей кодировка должна быть задано явно' (по умолчанию используется кодировка ISO-8859-IJ. Наиболее употреби- тельныезначенияпараметраприведенывтабл.6.4. v: 'w^i—vr i п i ц- у in 11 in iii biii ir ii i in наг ■• i "i n iff ■ I || i" f nrun n" rirmiiinim immi чм|||ЧЧ1 n n n ними и imiiipi mip Таблица 6.3. Возможныезна чения аргумента guote_style Значение , ENT_QUOTES ENT_NOQUOTES Описание Преобразуются двойные кавычки, одиночные (апострофы) остаются без изменении. Преобразуются и двойные, и одиночные кавычки. Двойные и одиночные кавычки остаются без изменений Таблица6.4.Возможныезначенияаргументас\\атье\. Кодировка ISO-8859-1 ISO-8859-15 U T F и В Псевдонимы IS08859-1 IS08859-15 Описание Западно-европейская Lafin-1. Западно-европейская taf/n-9. К кодировке Latin-1 добавлены знак евро, французские и финские буквы. 8-битная кодировка Unicode, совместимая с ASCII. В оригинальном примере указание кодировки отсутствовало, что привело к некорректной обработке строк со знаками кириллицы. — Прим.ред.
Кодирование тегов HTML 205 Кодировка Псевдонимы Описание cpbbb Ibrnbbb, 8156 Кодировка кириллицы, применяемая в Введена в ФНР, начиная с версии 4.2.2. Кодировка кириллицы, применяемая ■nri-! WindOWS-12 51, .Г,- J и nun ср 1251 -1 1 о с -I B Vv/naows. Введена в РНР, начиная с вер- сии4.3.2. ср1252 Windows-12 52, Западно-европейская кодировка, приме- 12 52 няемая в Windows. KDIS-R koi8-ru koi8r кодировка кириллицы, применяемая в UN/X ' Введена в РНР, начиная с версии 4.3.2. Примерб. 14. KoflnpoBaHHeHTML-TeroB,phpencode.php *<&ф $v***> <&'*r>icito*v*&*<<**ta*&j&jy*<w>cvr*.v-l&-> «vw.: <HTML> <HEAD> <Т1ТЬЕ>Кодирование тегов</Т1ТЬЕ> </HEAD> <B0DYxCENTER> <Hlкодирование тегов</Н1> <?php $errors = array ( ) ; if (isset ($_REQUEST ["seen_already"])) { validate_data (); if (count ($errors) > 0) { display_errors () ; display_form () ; } else { ■i process_data ( ) ; } else { display_form (); function validate_data () { global terrors; if ($_REQUEST ["Name"] == "") { $errors [] = "<F0NT COLOR='RED'>Имя обязательно для BBOfla</F0NT>"; } }
206 Глава 6. Web-приложения function display_errors () { global $errors; foreach ($errors as $err) { echo $err, "<BR>"; } function process_data() { echo "Ваше имя: " ; $ok_text = htmlentities ($ REQUEST ["Name"], ENTJtTOQUOTES, Cpl2 51'); echo Soktext; } function display_form() { echo "<F0RM METH0D='POST' ACTI0N='phpencode.php'>"; echo "Введите Ваше имя"; echo "<BR>"; echo "<INPUT NAME='Name' TYPE='TEXT'>"; echo "<BRxBR>"; echo "<INPUT TYPE=SUBMIT VALUE='OK'>"; echo "<INPUT TYPE=HIDDEN NAME='seen_already' VALUE='data'>"; echo "</F0RM>"; </CENTERx/B0DY> <ДТГМ1> На этот раз, если пользователь введет текст, содержащий HTML-теги (как на рис. 6.15), то при формировании страницы теги сохранятся, но в этом случае они будут представлять из себя просто текст (см. рис. 6.16).
файл Правка §ид Избранное Сервис Справка 0НВ1*Д .. €д , ш ш €Л,>.^иск ^f^^ 4^;^ jaj Дцрж,1щ| hrttp://tocalhost/ptip/06/phpencode,php Я ВА**** ■'.: ?М1 Кодирование тегов Введите Ваше имя | <Ь><i>CeprefK/ix/b> ] •j j Местная интрасеть Рис. 6.15. Попытка ввода HTML-тегов файл Правка |ид избранное Сервис Сдравка /^рес; | Ц httpi//tocalhos^php/06/phpencode,php .^.fife.. Ш flJIePaJ"W' Кодирование тегов Ваше имя: <b><i>Cepreft</iX/b> ^Готово *й Мвстп»й интраст. Рис. 6.16. Теги отображаются как простой текст
208 Глава 6. Web-приложения Сохранение данных Если форма для ввода данных содержит несколько полей, а ошибку пользователь допустил при заполнении только некоторых из них, разумно сохранить корректные данные при повторном выводе формы, чтобы пользователю не пришлось бы вводить верные данные заново. Этот подход продемонстрирован в примере 6.15, который содержит форму из двух полей, обязательных для ввода. Если пользователь заполнит только одно поле из двух, то при нажатии кнопки «ОК» будет сформировано соответствующее сообщение об ошибке, но уже введенное значение сохранится, и пользователю не придется набирать его повторно. Пример 6.15. Сохранение введенных данных, phprestore.php <HTML> <HEAD> <Т1ТЬЕ>Кодирование тегов</Т1ТЬЕ> </HEAD> <BODYxCENTER> <Н1>Кодирование тегов</Н1> <?php $errors = array () ; if (isset ($_REQUEST ["seen_already"])) { validate_data ( ) ; if (count ($errors) > 0) { display_errors () ; displayforin () ; } else { process_data(); } } else { displayform (); } function validate_data () { global $errors; i f($_REQUEST [" FirstName" ] == "") { Serrors [] = "<FONT COLOR='RED'>Hmh обязательно для BBOfla</FONT>"; } if(S_REQUEST ["LastName"] == "")
Сохранение данных ,« „ ?.??. { $errors [] = "<F0NT C0L0R='RED'>Фамилия обязательна для BBOfla</F0NT>"; } } function display_errors () { global $errors; foreach ($errors as $err) { echo $err, "<BR>"; } } function process_data () { echo "Ваше имя: "; echo $_REQUEST ["FirstName"]; echo "<BR>Bama фамилия: " echo $_REQUEST ["LastName"]; } function display_form () { $first_name = isset ($_REQUEST ["FirstName"]) ? $_REQUEST ["FirstName"] : "" ; $last_name = isset ($_REQUEST ["LastName"]) ? $_REQUEST ["LastName"] : ""; echo "<F0RM METH0D='POST' ACTI0N='phprestore.php'>"; echo "Введите Ваше имя"; echo "<INPUT NAME='FirstName' TYPE='TEXT' VALUE='", $first_name, "'>"; echo "<BR>"; echo "Введите Вашу фамилию"; echo "<INPUT NAME='LastName' TYPE='TEXT" VALUE='", $last_name, "'>"; echo "<BR>"; echo "<INPUT TYPE=SUBMIT VALUE='OK'>"; echo "<INPUT TYPE=HIDDEN NAME='seen_already' VALUE='data'>"; echo "</F0RM>"; } ?> </CENTERx/BODY> </HTML> i y^tjH*HHCw«p &атгр**мгл*.. ■*.тц*члюжеуущр|иг'1 у&жлж&шжютт На рис. 6.17 приведен пример результата выполнения этого скрипта в том случае, если пользователь не ввел фамилию. Видно, что введенное имя сохранилось в форме.
Глава 6. Web-приложения файл Хлавка 13нд Избранное Сервис ^правка 0 IfaHl * &'!' ' L " J'L " " iff '■»•■"■"'■ ^„/'Избранно: -^ ; 4 " ,Q ' длрес, ;$] Mtp:f flocatiostlptalMJptierntare.phj) Кодирование тегов Фамилия обязательна для ввода Введите Ваше имя|сергей_ _ ] Введите Вашу фамилию! 1 а " щ| Гаюю ■ .'.'■.-,-.' ■■■■.■!■'..'.■'.;'■■.'-..'■ -J" '■':'i- .A% г • • * ШВ^^и^-.*^**. ■ МктмаяНнтрасать .. Рис. 6.17. Сохранениеданныхвформевслучае ошибок ввода Использование JavaScript для проверки данных Наряду с РНР, который производит проверку данных на стороне сервера, можно также использовать JavaScript, при помощи которого данные могут быть проверены на стороне клиента. Использование JavaScript уменьшает нагрузку на сервер, а также сокращает трафик. Данный раздел не относится к РНР, но для полноты охвата темы он включен в книгу. В то же время, если пользователь отключил использование JavaScript, всегда можно использовать проверку на стороне сервера. К примеру, требуется проверить корректность ввода даты, которая может быть представлена в одном из двух форматов — «ДД-ММ-ГТ» или «ДД-ММ-1 I'll». Если дата введена неверно, выводится сообщение об ошибке, и отправкаданных формы блокируется. Для проверки даты написана функция на JavaScript под названием checker, которая вызывается непосредственно перед отправкой данных на сервер. В ней используются регулярные выражения, как и в примере 6.12 (использование регулярных выражений не является обязательным, строка может быть проверена на корректность любым другим способом). В случае некорректного формата даты выводится сообщение об ошибке, и поле для ввода очищается. Если же дата введена верно, они отправляются на web-сервер (см. пример 6.16).
HTTP-ауте нти ф и ка ци я 211 Пример 6.16. Проверка корректности ввода даты при помощи JavaScript, phpjavascript.html ■мммюукаив'r*m»ci мршгш u лдншм ■■; 'mm пшжк wxtn». О <HTML> <HEAD> <Т1ТЬЕ>Проверка ввода даты</Т1ТЪЕ> <SCRIPT LANGUAGE="JavaScript"> <! function checker() { var regExpl = Г (\d{l,2})-(\d{l,2})-(\d{2})$/ var regExp2 = Г (\d{l,2})-(\d{l,2})-(\d{4))$/ var resultl = document.forml.datel.value.match (regExpl) var result2 = document.forml.datel.value.match (regExp2) if (resultl == null && result2 == null) { alert("Дата введена неверно. Корректный формат - ДД-ММ-ГТ или ДД-ММ-ГГГГ") document.forml.datel.value = "" return false } else { document.forml.submit() } } </SCRIPT> </HEAD> <BODYxCENTER> <Н1>Проверка ввода даты</Н1> <FORM NAME="forml" ACTION="somepage.php" METHOD="POST" ONSUBMIT="return checker() " > Введите дату: <INPUT TYPE="TEXT" NAME="datel"> <INPUT TYPE="SUBMIT" VALUE="OK"> </FORM> </CENTERx/BODY> <HTML> Пример ввода некорректной даты приведен на рис. 6.18. Как видно, при нажатии на кнопку «ОК» отображается сообщение об ошибке. НТТР-аутентификация Часто перед тем как разрешить пользователю вводить какие-либо данные, следует осуществить его регистрацию. Большинство серверов (например, Apache) позволяют ограничивать доступ к определенным разделам web-сайта. Путем соответствующей настройки доступ получат только пользователи, перечисленные в конфигурационном файле сервера. При попытке доступа к защищенной части сервера будет отображено диалоговое окно, в котором следует ввести имя пользователя и его пароль, как показано на рис. 6.19.
212 Глава 6. Web-приложения Ш!ШЩ^,^Ф JSW .-Д'&ичМ- И*>» »tf.f *j>lorti. Ад^гг: i"]http://localhc3st/php/06/phpjavascript.html * вдГотово Проверка ввода даты Введитедату: [Г Э-1-97Г шчцмЕма .-■t\ оццпсэтпгсанцаммю^^^н Дата введена неверно. Корректный фермат' с ок 1 ДЦ мжт илиДД-ИКГСТТ Рис. 6.18. Введена дата в неверном формате игомизм workgroup Поа"эователь: Оароль: j 0 Сергей Q Сохранить пароль. | ск || <У'-; Отмоиа ] Рис. 6.19. Диалоговое окно авторизации пользователя Для того чтобы определить введенное таким образом имя пользователя, в РНР следует обратиться к элементу массива $_SERVER с именем "PHP AUTH USER". Ниже приведен пример использования авторизации. Если пользователь введет имя и пароль, его имя будет отображено. Если же регистрационное имя не будет задано, доступ будет запрещен, а выполнение скрипта прервано при помощи функции exit.
<? if (! isset (S_SERVER ['PHP_AUTH_USER'])) { header ('WWW-Authenticate: Basic realm = "workgroup'"); header ('HTTP/1.0 401 Unauthorized'); echo 'Неавторизованный доступ запрещен'; exit; } else { echo "Добро пожаловать, {$_SERVER ['PHP_AUTH_USER']}."; } ?> На этом рассказ о возможных вариантах проверки корректности данных заканчивается. В следующей главе рассказывается об объектно-ориентированном подходе к программированию и об обработке файлов. Итоги В этой главе описаны разнообразные приемы проверки данных, вводимых в HTML-формах. Ниже перечислены краткие итоги главы: • Суперглобальный массив SSEKVER содержит большое количество информации о программной среде, в которой функционирует web-приложение. Например, элемент $_SERVER [ ' PHP SELF ' ] содержит имя текущего PHP-скрипта, SSERVER [' REQUEST METHOD' ] —название метода доступа данных, a $_SERVER [ ' HTTP USERAGENT ] — тип используемого браузера. Полный перечень элементов массива приведен в табл. 6.1 и табл. 6.2. • Для перенаправления браузера используется специальный заголовок HTTP-ответа, например: header ("Location: new_url.html"). • Для определения факта повторного запуска скрипта после заполнения данных в HTML-форма можно использовать скрытое поле, наличие которого проверяется при помощи функции isset. • В РНР имеется широкий спектр способов по проверке значений полей форм, включая использование регулярных выражений. • Для исключения побочного влияния HTML-тегов во вводимых данных используются функции striptags и htmlentities.
Глава7 ^-v >^- ОФП и файлы В этой главе рассматриваются две достаточно важные темы — объектно-ориентированное программирование (ООП) и работа с файлами. Использование РНР вполне возможно и без объектно-ориентированного программирования. Но при создании больших сложных проектов, а также при работе в команде использование ООП является весьма серьезным преимуществом. ООП было предназначено для упрощения построения объемных приложений. Как показано в гл. 4, функции используются для разбиения кода на отдельные независимые фрагменты. ООП делает еще один шаг в этом направлении, позволяя объединять данные и обрабатывающий их код в объекты. Объекты позволяют скрывать от внешнего мира детали своего внутреннего устройства. При этом реализация объектов может быть изменена без необходимости внесения модификаций в использующий их код. Объекты позволяют строить сложные, комплексные приложения, распараллеливая работу программистов в команде, а также используя значительные объемы кода повторно. Помимо ООП, в данной главе описывается работа с файлами. Возможность обработки файлов на стороне сервера является одним из важных достоинств РНР. Например, при создании гостевой книги на сайте ее настройки и внешний вид могут быть размещены в отдельном файле для удобства ее модификации. В данной главе описывается создание и открытие файлов, чтение и запись данных различными способами. Классы и объекты Для того, чтобы начать работать с объектами, требуется сперва описать некоторый класс. Класс представляет собой тип объекта точно так же, как integer или string являются типом переменной. Пусть требуется создать класс Animal, который будет содержать данные о животных. В классе будут описаны две функции (называемые методами класса): setname и getname. Также в классе описывается одна переменная (называемая свойством класса). Описание класса Animal приведено ниже; далее в главе оно будет объяснено подробнее.
216 Глава/ГООПифайлы class Animal { var $name; function set_name ($text) { $this->name = $text; } function get_name () { return $this->name; } } Для создания объектов используется оператор new. Созданный объект может быть сохранен в переменной точно так же, как и обычное значение или массив. После создания объекта доступ к его свойствам и методам осуществляется при помощи оператора —>. Создание и использование объекта выглядит следующим образом: $lion = new Animal; $lion->set_name ("Бонифаций"); echo "Имя созданного льва: ", $lion->get_name(), ". " ; При выполнении этих фрагментов кода будет отображена следующая строка: Имя созданного льва: Бонифаций Ниже вопросы создания и использования объектов описываются более подробно. Создание класса Класс является набором переменных и функций, или, в терминах ООП, свойств и методов. Класс является одним из типов данных. Создавая объекты определенного класса, их можно сохранять в переменных. В предыдущем разделе в качестве примера был приведен класс Animal, который будет подробно рассмотрен ниже. Описание класса начинается с ключевого слова class, за которым следует имя создаваемого класса: class Animal { } Класс предназначен для хранения имени животного, и для этой цели объявляется локальная переменная, называемая в ООП свойством. Свойство декларируется при помощи оператора var. Несмотря на то, что в описании указывается знак $, свойство традиционно обозначается просто своим именем, в данном случае name. class Animal { var $name; }
Создание класса 217 В РНР переменная не требует явного объявления и создается при первом упоминании о ней. Но для свойства класса этот принцип недействителен, и для его описания требуется использовать оператор var. После описания свойство класса доступно для всех его методов, в частности, для метода set name, который предназначен для запоминания имени животного. class Animal { var $name; function set_name ( $text) { } } Для получения доступа к свойству класса изнутри его метода используется встроенная переменная $this , которая указывает на текущий объект данного класса. Переменная содержит указатель и используется совместно с оператором - >, таким образом, для ссылки на свойство name необходимо использовать следующий синтаксис: $this->name (следует обратить внимание, что перед именем свойства отсутствует знак $, синтаксис $this->$name является некорректным). class Animal { var $name; function set_name ($text) { $this->name = $text; } Другой метод класса, getname, возвращает текущее имя животного: class Animal { var $name; function set_name ($text) { $this->name = $text; } function get_name () { return $this->name; } На этом описание класса Animal завершено, и в следующем разделе будет продемонстрировано его использование. Имеется возможность инициализации свойств класса при помощи константы, при этом использование любого вида выражений недопустимо:
218 » » Глава 7 ООП и файлы class Animal { var $name = "Leo"; // Корректный оператор var $name = "L"."e"."o"; // Ошибочный оператор } Описание класса не может быть разорвано HTML-кодом; весь класс целиком должен быть описан в рамках единой секции <?php. . . ?>. Кроме того, поскольку в РНР имеются ряд встроенных методов, названия которых начинаются с символов (два подчеркивания), не следует использовать их в начале названий собственных методов. Создание объекта В предыдущем разделе был создан класс Animal, но для того, чтобы его ис- пользовать, следует вначале создать объект данного класса. Обычные переменные в зависимости от своего содержимого имеют определенный тип данных. Класс также является типом данных, и объект класса может быть сохранен в переменной. Для создания нового объекта заданного класса используется оператор new. Этот оператор требуется только при создании объектов, а не для обычных скалярных типов данных. Например, для создания объекта класса Animal и сохранения его в переменной Slion используется следующий синтаксис (класс Animal описан в предыдущем разделе): $lion = new Animal; После создания объекта доступ к его методам обеспечивает оператор —>. Например, для присвоения имени может использоваться метод setname: $lion->set_name ("Бонифаций"); Для того, чтобы считать присвоенное имя, используется метод getname, как показано ниже: echo "Имя нового льва: ", $lion->get_name () , "."; Доступ к свойствам класса осуществляется точно также, как и к его методам. Ниже приведен пример доступа к свойству name: echo "Имя нового льва: ", $lion->name () , "."; В результате выполнения этого фрагмента кода будет отображена строка Имя нового льва: Бонифаций Оператор -> открывает доступ как к методам класса, так и к его свойствам. Хорошим тоном в ООП является присвоение значений свойствам класса при помощи соответствующих методов, в этом случае в зависимости от конкретных данных могут быть осуществлены дополнительные действия. Такие методы называются методами доступа. Например, следующий метод ограничивает длину имени животного 10 символами:
Управление доступом к свойствам и методам „„___^™_„ ^ 19 function set_name($text) { if (strlen(Stext) <= 10) { $this->name = $text; } } Управление доступом к свойствам и методам По умолчанию доступ к свойствам и методам класса ничем не ограничен, но не всегда это является допустимым. Например, метод setname из предыдущего раздела не позволяет присвоить свойству name значение, превышающее по длине 10 символов. function setname (Stext) { if (strlen( Stext) <= 10) { $this->name = $text; } Но при этом остается возможность присвоения некорректного значения свойству name напрямую, например: $this->name = "слишком длинное имя"; Решение заключается в ограничении доступа к свойствам и методам класса при помощи модификаторов доступа. В РНР существуют три модификатора доступа: • public — нет ограничений на доступ. • private — доступ разрешен только изнутри класса. • protected — доступ разрешен только изнутри класса и всех его потомков. По умолчанию все свойства и методы объявляются как public, что означает отсутствие ограничений на доступ к ним снаружи класса. Но если свойство или метод объявлено как private, доступ к нему из кода за пределами класса будет заблокирован. Ниже приведен пример попытки доступа к приватному свойству name: <?php class Animal { private $name; function set_name ($text) { $this->name = $text; } function getjame () {
220 return $this->name; } } Slion = new Animal; $lion->set_name ("Бонифаций"); echo "Имя нового льва: ", $lion->name, "."; ?> При выполнении данного кода будет выведено следующее сообщение об ошибке: Fatal error: Cannot access private property Animal::$name in test.php on line 19 Наряду с приватными свойствами можно объявить и приватные методы класса. Например, метод getname может быть объявлен как приватный: <?php class Animal { var $name; function set_name ($text) { $this->name = $text; } private function get_name () { return $this->name; } } $lion = new Animal; $lion->set_name ("Бонифаций"); echo "Имя нового льва: ", $lion->get_name () , "."; ?> Fatal error: Call to private method Animal:: get_name () from context '' in test.php on line 19 При использовании ключевого слова protected свойства и методы класса будут доступны только изнутри данного класса, а также из всех классов, порожденных на основе данного. Порождение классов и наследование свойств и методов будет описано в следующих разделах данной главы. Конструкторы объектов Как было показано выше, для инициализации свойств классов можно использовать соответствующие методы доступа. Но существует и другой способ присвоения значений свойствам класса при создании объекта — использование конструкторов. В РНР конструктором является метод класса со специальным Глава/. ООП и файлы
Конструкторы объектов 221 именем construct (имя начинается с двух подчеркиваний), и при создании объекта ему могут быть переданы соответствующие данные. Ниже приведен пример конструктора для класса Animal, который выполнят начальную инициализацию имени животного точно так же, как это реализовано в методе setname: function construct ($text) { $this->name = $text; } При создании объекта класса Animal данные для конструктора могут быть переданы с использованием скобок после имени класса, например: $lion = new Animal ("Бонифаций"); Пример 7.1 демонстрирует использование конструктора для инициализации свойства класса. Пример 7.1. Использование конструктора, phpconstructor.php <HTML> <HEAD> <TITLE> Использование конструктора для инициализации объекта </Т1ТЪЕ> </HEAD> <BODY> <CENTER> <Н1> Использование конструктора для инициализации объекта </Н1> <?php flass animal var $name; function construct ($text) } $this->name = $text; function set_name ($text) $this->name = $text; function get_name () return $this->name; }
222 _ Глава7. ООП и файлы $lion = new animal ("Бонифаций"); echo "Имя нового льва: ", $lion->get_name (), "."; ?> </CENTER> </BODY> </HTML> Результат выполнения этого примера приведен на рис. 7.1, из которого видно, что значение, переданное конструктору, было успешно сохранено в свойстве класса. 3 Использование конструктора Для инициализации объекта файл Правка Вид Избранное Сервис Справка ■ if a 0/_ ' -"■■— V.S ьП i^i : :_Й '■ >..-'Поиск "'-,избранное ^Jj) \ £ф \Щ£ й-Л*.--_\ ■ <£ http //localhost/php/07/phpconstnjctor.php ijjjjl El Переход.; Сайки" Использование конструктора для инициализации объекта Имя нового льва: Бонифаций. Рис. 7.1. Использование конструктора для инициализации объекта Для уничтожения объекта используется тот же самый оператор unset, при помощи которого можно уничтожить и обычную переменную: unset $lion; Наследование классов Зачастую удобно не разрабатывать новый класс заново, а основать его на каком-либо другом классе. Например, предположим, что разработан класс Vehicle, в котором содержатся разнообразные методы управления транспортным средством, например, start, run, steer и stop. Далее, пусть требуется создать классы, описывающие специфические типы транспортных средств, например, Car, Truck, Helicopter, Oceanliner и т. п.
Наследование классов" 223 Можно скопировать существующие методы start, run, steer и stop из класса Vehicle в каждый из вновь создаваемых классов, а можно создать эти классы на основе базового класса при помощи механизма наследования. Путем наследования все свойства и методы базового класса (например, Vehi с 1 е) становятся доступными для всех его потомков (Саг и т. д.). Кроме того, каждый из порожденных классов может иметь свои собственные свойства и методы. В примере 7.2 на основе базового класса Animal создается порожденный класс Lion. Он будет наследовать все свойства и методы базового класса; кроме того, в нем описывается новый метод — roar. Поскольку далеко не все животные рычат, наличие такого метода в базовом классе было бы некорректным. В то же время львы рычат, и метод roar отлично вписывается в класс Lion. Для порождения одного класса от другого используется ключевое слово extends, после которого указывается имя базового класса. После создания объекта класса Lion доступным является не только его собственный метод roar, но и метод setname, описанный в базовом классе Animal. Пример 7.2. Наследование классов, phpinheritance.php <HTML> <HEAD> <TITLE> Наследование методов класса </TITLE> </HEAD> <BODY> <CENTER> <H1> Наследование методов класса </FU> <?php class Animal { var $name; function set_name ($text) { $this->name = $text; } function get_name () { return $this->name; } } class Lion extends Animal { var $name; function roar () {
21L. {i1 \174 9Я01$22ль|. echo $this->name, " рычит!<BR>" echo "Создание нового льва...<BR>"; $lion = new Lion; $lion->set_name ("Бонифаций") ; $lion->roar ( ) ; ?> </CENTER> </BODY> </HTML> Результат выполнения примера представлен на рис. 7.2. Применение наследования позволяет повторно использовать значительные объемы кода. Файл Правка Вид Забранное Сервис "правка Ж>->л • €_> • Щ Ш№™ Ь"***" Q Щ Адрес! '\iifhttp://localhost/php/07/phpinherttanc».prip • Д Q Переход . Ссьтки Наследование методов класса Создание нового льва.. Бонифаций рычит! Рис. 7.2. Наследование классов Наследование и защищенные методы Как было показано выше, публичные (public) свойства и методы доступны для вызова извне объекта, а приватные (private) — нет. Но если свойство или метод объявлены как защищенные (protected), доступ к ним разрешен не только изнутри класса, где они описаны, но также изнутри всех классов, порожденных на основе данного. Например, если метод setname класса Animal будет объявлен как protected, непосредственный его вызов снаружи класса будет невозможен и приведет к возникновению ошибки, что и продемонстрировано ниже (используется также класс Lion, описанный в примере 7.2).
Наследование и защищенные методы 225 class Animal { var $name; protected function setname ($text) { $this->name = $text; } } echo "Создание нового льва...<ВК>"; Slion = new Lion; Slion->set_name ("Бонифаций"); Выполнение данного фрагмента кода приведет к программной ошибке: Fatal error: Call to protected method Animal::set_name() from context " in test.php on line 31 С другой стороны, защищенный метод setname доступен не только внутри базового класса Animal, но и внутри порожденного класса Lion, поэтому его можно использовать, например, в конструкторе класса lion для инициализации имени животного, что показано на примере 7.3. Пример 7.3. Использование защищенных методов, phpprotected.php <HTML> <HEAD> <TITLE> Защищенные методы </TITLE> </HEAD> <BODY> <CENTER> <H1> Защищенные методы </Н1> <?php class animal var $name; protected function set_name ($text) { $this->name = $text; } function getname () { return Sthis- >name; } 8 PHP в примерах
226 Глава 7. ООП и файлы class Lion extends Animal { var $name; function roar () < echo $this->name, " рычит!<BR>"; function construct ($text) { $this->set_name($text); echo "Создание нового льва...<BR>"; $lion = new Lion ("Бонифаций"); $lion->roar (); </CENTER> </B0DY> </HTML> иди cfffUjno^qF] ih^tVpi) ч*тм яихаплжиоуапчк 1»*ялскм\ж1шж*ся& at» *r *■■ Выполнение данного примера показано на рис. 7.3. файл Дравка Дид Избранное Сервис ^правка о*5>5Д ф"шшт\р™-~й--*— &\ш Адрес! | гЦ http://localhost/pripAO/pripprotected.prip | Ej Перахед Защищенные методы Создание нового льва... Бонифаций рычит! Рис. 7.3. Вызов защищенного метода
1ерекрытие методов 227 Перекрытие методов При наследовании одного класса от другого в порожденном классе имеется возможность создать метод с точно таким же именем, что и в базовом классе. В этом случае метод базового класса будет перекрыт, и объекты порожденного класса будут использовать новый метод вместо перекрытого метода базового класса. Например, в классе Lion, порожденном на основе класса Animal, можно описать метод set name, который будет преобразовывать буквы имени в заглавные. function set_name ( $text) { $this->name = strtoupper($text) ; } При вызове метода setname объекта класса Lion будет вызван этот новый метод, что и подтверждает пример 7.4. Пример 7.4. Перекрытие методов, phpoverride.php <HTML> <HEAD> <TITLE> Перекрытие методов </ТТТЬЕ> </HEAD> <BODY> <CENTER> <Н1> Перекрытие методов </Н1> <?php class Animal { var $name; function set_name ($text) { $this->name = $text; } function get_name () { return $this->name; } } class Lion extends Animal { var $name;
228 Глава 7. ООП и файлы function roar () { echo $this->name, " рычит!<ВИ>"; } function set name ($text) ( $tMs->name = strtoupper($text); echo "Создание нового льва...<BR>"; $lion = new Lion; $lion->set_name ("Бонифаций"); $lion->roar () ; </CENTER> </BODY> </HTML> ымуч&яж/*жжм:уг*Ф1т&*&>*^[ЮА*ж^&*)&>и#ею>-1^^ На рис. 7.4 можно увидеть, что в результате выполнения примера 7.4 был вызван именно метод порожденного класса, а не базового. /Перекрытие мете файл Правка Вид Избранное Сервис Справка ф '■=-•■ о й is ■& ■ Рпакх &***» ©! % на Алрь^! :_л j hHp./7,l°ca'host/php/07/phpoverrJde.php Щ' Q Переезд ; Семга Перекрытие методов Создание нового льва... БОНИФАЦИЙ рычит! Рис. 7.4. Перекрытие методов
Доступ к методам базового класса 229 Доступ к методам базового класса При использовании наследования может возникнуть необходимость вызова перекрытого метода базового класса. Например, пусть метод setname в классе Animal описан следующим образом: function set name(Stext) { $this->name = $text; Одноименный метод в порожденном классе Lion может вызвать этот метод при помощи префикса Animal: :, содержащего имя базового класса. Соответствующее описание выглядит следующим образом: function setname(Stext) { Animal: :set_name (strtoupper (Stext)); } Пример 7.5 использует этот прием. Пример 7.5. Использование перекрытыхметодов базового класса, phpbasemethods.php <HTML> <HEAD> <TITLE> Доступ к методам базового класса </ТТТЬЁ> </HEAD> <BODY> <CENTER> <Н1:> Доступ к методам базового класса </Н1> <?php tlass Animal var $name; function set_name ($text) } $this->name = $text; function get_name () { return $this->name; } }
230 Глава 7. ООП и файлы class Lion extends Animal { var $name; function roar () { echo $this->name, " рычит!<ВК>"; function set_name ($text) { Animal::set_name($text); echo "Создание льва...<BR>"; $lion = new Lion; $lion->set_name ("Бонифаций"); $lion->roar () ; </CENTER> </B0DY> </HTML> ФчмЫмхЛцт' uphill ^*M*i&^*A^ijrmtb*l**'W*X:m)u4*nb>k4AMmJtoW1kU^^ Результат выполнения данного примера приведен на рис. 7.5. Эк Доступ к методам базового класса - Microsoft Internet Explorer Евйл 0 AAtlXif Правка Вид Избранное Сервис Справка ",л0й]ШС*)|/,П0^^«*^ .Sjhttp://1ocalhost/php/07/phpbasemethods.php Доступ к методам Создание Бонифаций ф(&а§_:- базового льва... рычит! :>"■!*. класса http ://all -ebooks com Рис. 7.5. Доступ к методам базового класса
Открытие файла: f open 231 Использование оператора : : позволяет задать имя базового класса непосредственно, но зачастую требуется сослаться на метод непосредственного предка данного класса. Для этой цели в РНР предусмотрено ключевое слово parent, которое может быть использовано вместо имени базового класса. С его использованием вызов метода set name выглядит следующим образом: parent::set name (Stext). Открытие файла: fopen Возможность использования файлов для хранения данных является значительным преимуществом РНР, и в нем предусмотрен полный набор функция для работы с файлами. Наиболее важные из них описываются в оставшейся части данной главы. Начать их изучение следует с функции fopen, которая открывает заданный файл для чтения или записи. Синтаксис этой функции приведен ниже: fopen (string filename, string mode [, int use include pat.h [, resource zcontext]]) Здесь filename — имя открываемого файла, mode задает режим открытия файла (для чтения или записи), параметр use incl udeja th может быть установлен в значение 1 или TRUE для поиска файла по каталогам, указанным в параметре include path конфигурационного файла php. ini. Необязательный параметр zcon text задает контекст файла, который предназначен для дополнительной обработки потоков данных в файл и из файла (в данной книге контексты не рассматриваются). Параметр mode, определяющий режим открытия и возможные операции с файлом, может принимать следующие значения: ' г' Файл открывается только для чтения. 1 г+ ' Файл открывается для чтения и записи. ' w' Файл открывается только для записи. Если файл существует, он усекается до нулевой длины. Если файл не существует, он создается. Tw+' Файл открывается для чтения и записи. Если файл существует, он усекается до нулевой длины. Если файл не существует, он создается. ' а' Файл открывается только для записи, указатель файла устанавливается на конец файла. Если файл не существует, он создается. 1 а+ ' Файл открывается для чтения и записи, указатель файла устанавливается на конец файла. Если файл не существует, он создается. 'х' Файл создается и открывается для записи. Если файл уже существует, функция fopen возвращает значение FALSE, свидетельствующее об ошибке. 'х+ ' Файл создается и открывается для чтения и записи. Если файл уже существует, функция fopen возвращает значение FALSE, свидетельствующее об ошибке.
232 Глава 7. ООП и файлы Следует иметь в виду, что в различных операционных системах действуют различные соглашения по обозначению конца строки в текстовых файлах. При записи в текстовый файл следует соответствующим образом корректировать символы конца строки в соответствии с той операционной системой, под которой выполняется скрипт. В Unix/Linux концом строки считается символ \п, в Windows — \r\n, а в Macintosh — \г. В РНР предусмотрена системная константа PHPEOL, которая хранит представление конца строки для текущей операционной системы. При работе в Windows можно использовать флаг текстового режима обработки файла (' t'), который задает преобразование символа \п в \г\п при записи данных в файл (и, соответственно, выполнение обратного преобразования при чтении). Также можно использовать флаг двоичного режима обработки файла (' Ь'), при котором данные преобразовываться не будут. Для использования любого из этих флагов его надо просто дописать к строке mode, например ' wt'. Режим по умолчанию — текстовый или двоичный — зависит от используемой версии и модуля РНР, поэтому рекомендуется в любом случае задавать режим в явном виде. В следующем примере файл /home/ file, txt открывается для чтения: Shandle = fopen ("/home/file.txt", "г"); При успешном открытии файла функция fopen возвращает дескриптор файла, который используется для дальнейшей работы с файлом. После открытия файла данные могут быть, например, считаны при помощи функции fread, которая описана несколько ниже. Следующая строка открывает текстовый файл для записи: Shandle = fopen ("/home/file.txt", "wt"); To же самое для двоичного режима работы: Shandle = fopen ("/home/file.txt", "wb"); При работе под Windows следует экранировать все обратные слеши, как показано ниже (или использовать прямые слеши): Shandle = fopen ("с : WdataWfile. txt", "г"); При работе с файлами можно не ограничиваться локальной файловой системой. Например, можно открыть файл, находящийся на web-сервере, указав его URL: $handle = fopen ("http://www.orioner.ru/index.html", "г") ; Для работы также доступен и FTP-протокол с заданием имени пользователя и пароля: Shandle = fopen ("ftp ://user: password® ftp. relcom.ru/incoming/file", "w"); Как уже сказано выше, при открытии файла возвращается дескриптор, который используется всеми остальными функциями работы с файлами. Эти функции рассмотрены в следующих разделах главы.
Чтение строк текста: fgets Для чтения строки текста из файла используется функция fgets, ниже приведен ее синтаксис: fgets (resource handle [, int length]) В качестве аргументов функции передаются дескриптор открытого файла и необязательный параметр 1 ength. Функция возвращает строку символов длиной до length-1. Считывание символов прекращается при достижении length-1 символа, при считывания конца строки (он также включается в возвращаемый результат) или при достижении конца файла, в зависимости от того, что произойдет первым. Если параметр length не задан, то по умолчанию его значение принимается равным 1024 байт. В примере рассматривается использование этой функции для чтения содержимого текстового файла. Например, существует файл file.txt следующего содержания: Это файл с текстом. Требуется отобразить содержимое этого файла. После открытия файла он считывается построчно при помощи функции fgets. Для организации цикла используется оператор while и функция feof, которая возвращает значение TRUE при достижении конца файла: <?php $handle = fopen ("file.txt", "r" ) ; while (Ifeof ($handle)) { } ?> В теле цикла производится чтение строки текста при помощи fgets и ее отображение: <?php $handle = fopen ("file.txt", "r" ) ; while (Ifeof ($handle)) { $text = fgets($handle); echo $text, "<BR>"; } ?> После завершения работы с файлом его следует закрыть при помощи функции fclose:
234 -■ _«..._....»■■«■ ™.. .._■__; ;„._„_ Глава J7 ..,., OO Г1. и,.файл ы <?php $handle = fopen ("file.txt", "r") ; while (Ifeof ($handle)) { $text = fgets ($handle); echo $text, "<BR>"; } fclose ($handle); ?> Пример 7.6 демонстрирует использование всех этих функций для отображения файла. Пример 7.6. Чтение текстового файла, phpreadfile.php iMHTT¥tMnira«¥Wiiiftrnmi«TffHMiifmairTrm'mrittrriTt^ Iibhp<i iwiiIiiih и «ииничш inniiiiiiiiiniiii HwIiiiihihii hi» <HTML> <HEAD> <TITLE> Чтение файла </TITLE> </HEAD> <BODY> <CENTER> <H1> Чтение файла ■</Н1> <?php $handle = fopen ("file.txt", "r") ; while (! feof ($handle)) { $text = fgets ($handle); echo $text, "<BR>"; } fclose ($handle); ?> </CENTER> </B0DY> </HTML> Результат выполнения данного примера приведен на рис. 7.6. Чтение символов: fgetc Зачастую требуется считать из файла не целую строку, а отдельный символ. Для этого предназначена функция fgetc. Пример 7.7 демонстрирует использование этой функции для посимвольного чтения и отображения содержимого файла. Следует обратить внимание, что символ конца строки заменяется на тег <BR>. На рис. 7.7 приведен результат выполнения этого примера.
Чтение символов: fgetc файл Правка Вид избранное Сервис С/раека ■***%. ■ /Ы*"% ГТ-Л 'лЙ -^ПЛ * <СЧ "Л-" '- * * * * О »т**^Я Адрес; Д http://taca]host/php/07/phpreadFi!e,php_ Ш ' £J Переход С«*пк« Чтение файла Это файл с текстом. Рис. 7.6. Отображение текстового файла Пример 7.7. Посимвольное чтение файла, phpfgetc.php <HTML> <HEAD> <TITLE> Посимвольное чтение файла </TITLE> </HEAD> <BODY> <CENTER> <Hl> Посимвольное чтение файла </Н1> <?php $handle = fopen ("file.txt", "rb") while ($char = fgetc ($handle)) { ?> </CENTER> </BODY> </HTML> if ($char == "\n") { $char = "<BR>"; } echo $char; } fclose ($handle);
Глава 7, ООП и файлы файл Правка Цид избранное Сервис ^правка ^:1^.-:л..-- ". J rr.V.j. " http://localhosyphp/CI7/phpfgetc,php  Д.ЛИЮРД ■ Посимвольное чтение файла Это файл с текстом. Рис. 7.7. Посимвольное отображение файла Двоичное чтение файла: fread Читать содержимое файла необязательно по строкам или символам. Данные из файла могут быть прочитаны в любом необходимом объеме при помощи функции fread. Функция fgets рассматривает файлы как текстовые, а функция fread рассматривает их как двоичные, не обрабатывая специальным образом концы строк и не выполняя никаких других преобразований данных — файл считается простой последовательностью байт. Синтаксис функции fread приведен ниже: fread (resource handle, int length) Функция считывает до 1 ength байт из файла, заданного своим дескриптором handle. Чтение прекращается, если достигнут конец файла, или если считано заданное количество байт. В операционной системе Windows для использования функции fread файл должен быть открыт в двоичном режиме (' г b' ) . Так как добавление режима Ъ" не имеет негативного эффекта в других операционных системах, то имеет смысл использовать его всегда в целях совместимости: <?php $handle fopen ("file.txt', 'тЬ"); ?>
Двоичное -jjeHJ*ejJ^a4read_ _ _ ___ 237 При помощи fread можно считать весь файл целиком в одну строку. Для определения фактического размера файла используется функция file size: <?php $handle = fopen ("file.txt", " rb " ) ; $text = fread ($handle, filesize ("file.txt")); После выполнения этого кода файл будет считан в переменную $text. Если при выполнении возникнет какая-либо ошибка, то переменная будет содержать пустую строку. Для преобразования символов концов строк в теги <BR> используется функция strreplace: <?php $handle = fopen ("file.txt", " rb " ) ; $text = fread ($handle, filesize ("file.txt")); $br_text = str_replace ("\n", "<BR>", $text); Все, что остается сделать после этого — вывести преобразованный текст при помощи функции echo и закрыть файл, что и продемонстрировано на примере 7.8. Пример 7.8. Чтение двоичного файла, phpread.php ияммшояееткэе ч^м^хомдодемм cwMw^w**tAoy- 7*к»хч<» *&у1ынх***+&ч. s^w^jv ф i» ■■; -, ■»; >- <HTML> <HEAD> <TITLE> Чтение файла при помбщи fread </ТТТЬЕ> </HEAD> <BODY> <CENTER> <H1> Чтение файла при помощи fread </Н1> <?php $handle = fopen ("file.txt", " rb " ) ; $text = fread ($handle, filesize ("file.txt")); $br_text = str_replace ("\n", "<BR>", $text); echo $br_text; fclose ($handle); ?> </CENTER> </BODY> </HTML> Результат выполнения этого примера приведен на рис. 7.8.
238 Глава 7. ООП и файлы И Чтение файла при помощи fread soft Internet Explorer файл Правка gu избранное Сервис Справка [§ Ф!РПВТМ фи*р«« 4&Щ& ^*ДР»-А1http://localhost/php/07/phpread.php ■-•'■ ^^- ■'■ • "■•'- -- Чтение файла при помощи fread Это файл с текстом. Рис. 7.8. Отображение двоичного файла Чтение файла целиком: file get contents В предыдущем примере для считывания файла целиком использовалось несколько вызовов функций. Того же результата можно добиться и более простым способом — используя функцию f ilegetcontents. В качестве единственного параметра ей передается путь к файлу, а в результате возвращается содержимое файла в виде строки — не требуется даже использование дескриптора файла. Пример 7.9 показывает использование этой функции. Пример7.9.Чтениефайлацеликом,рМргеас1.рЬр <HTML> <HEAD> <TITLE> Чтение содержимого файла при помощи file_get_contents </TTTLE> </HEAD> <BODY> <CENTER> <H1> Чтение содержимого файла при помощи file_get_contents
Синтаксический разбор файла: fscanf 239 </Н1> <?php $text = filegetcontents ("file.txt"); Sbrtext = strreplace ("\n", "<BR>", $text) echo Sbrtext; ?> </CENTER> </BODY> </HTML> На рис. 7.9 приведен результат выполнения этого примера. вайл Правка Ёид Избранное Сервис Справка 0*-. » о й \Й -Й1 /- $>"*>««» <£ ! % |3 Адрм; !"Й httpy/localhosVphp/OT/phpfllegetcontents.php жм Переход : Ссыпки Чтение содержимого файла при помощи file_get_contents Это файл с текстом. Рис. 7.9. Отображение файла целиком Синтаксический разбор файла: fscanf Для облегчения считывания данных из файла он может быть отформатирован, например, при помощи табуляций, а для выборки отдельных элементов данных разумно применить функцию fscanf. Ее синтаксис представлен ниже: fscanf (resource handle, string format)
240 ^^ ^^_»^. ^w_^ ~~ Глава 7. ООП д файлы Аргументами функции являются дескриптор файла и формат, заданный в виде строки. Формат задается в том же виде, что и для функции sprint f, которая описана в гл. 3. «Строки и массивы». Например, пусть в файле tabs . txt хранятся имена и фамилии людей, разделенные символом табуляции: George Washington Benjamin Franklin Thomas Jefferson Samuel Adams Анализ подобного файла при помощи fscanf достаточно прост. Вначале файл следует открыть: <?php $handle = fopen ("tabs.txt", "rb"); В данном случае строка, задающая формат данных, будет следующей — " %s\t%s\n" (строка, символ табуляции, строка, символ конца строки). При помощи функции fscanf осуществляется считывания очередной строки из файла, а результат размещается в массиве $ names: <?php $handle = fopen ("tabs, txt", "rb"); while ($names = fscanf ($handle, "%s\t%s\n")) Выделение отдельных элементов из массива производится при помощи функции list: <?php $handle = fopen ("tabs.txt", "rb"); while ($names = fscanf ($handle, "%s\t%s\n")) { list (Sfirstname, Slastname) = Snames; } ?> Наконец, результат обработки файла отображается в окне браузера, что демонстрирует пример 7.10. Пример7.10. Чтение файла при помощиfscanf, phpfscanf.php <HTML> <HEAD> <TITLE> Чтение файла при помощи fscanf </ТТТЬЕ> </HEAD> <BODY> <CENTER>
Синтаксический разборфайла: fscanf 241 <Н1> Чтение файла при помощи fscanf </Hl> <?php $handle = fopen ("tabs.txt", " rb" ) ; while ($names = fscanf ($handle, "%s\t%s\n) { list ($firstname, $lastname) = $names; echo $firstname, " ", $lastname, "<BR>"; fclose ($handle); ?> </CENTER> </BODY> </HTML> Как видно из рис .7.10, файл разобран и отображен корректно. файл Правка £ид убранное Сервис Cjipasxa ^"''■■'"": UJ ^П '£?3 "-Г :-*** : Л Поиск уУ<,Йзбранное 4f) ! *^ £Sj ■tipeji/. i" | http://localhost/php/CI7/phpfscanf.php fv,,i £2 ЛвРвх°л Чтение файла при помощи fscanf George Washington Benjamin Franklin Thomas Jefferson SamuelAdams Рис. 7.10. Отображение файла при помощи fscanf
242 Глава 7. ООП и файлы Запись в файл: fwrite Для записи данных в файл предназначена функция fwrite, которая имеет следующий синтаксис: fwrite (resource handle, string string [, int length]) Функция осуществляет запись строки string в файл, заданный своим дескриптором handle. Если указан третий необязательный аргумент 1 ength, то запись завершается после вывода заданного количества байт (если до тех пор не встретится конец строки). Функция возвращает количество записанных байт или значение FALSE в случае возникновения ошибки. В случае работы в операционной системе Windows (или в любой другой, в которой текстовые и двоичные файлы различаются) файл должен быть открыт в двоичном режиме. В примере 7.11 показывается использование этой функции. В данном случае в файл выводится несколько строчек текста. Для начала следует открыть файл в двоичном режиме при помощи функции f open (если файл не существует, он будет автоматически создан): $handle = fo'pen ("text.txt", "wb") ; После этого при помощи функции fwrite осуществляется вывод в файл текста, предварительно записанного в переменную $text. В случае возникновения ошибки выводится соответствующее сообщение. Из рис. 7.11 видно, что запись в файл успешно завершена. Легко убедиться в том, что файл text, txt содержит следующие строки: Просто строка текста. Пример 7.11. Запись в файл при помощи fwrite, phpfwrite.php <HTML> <HEAD> <TITLE> Запись в файл при помощи fwrite </TITLE> </HEAD> <BODYxCENTER> <H1> Запись в файл при помощи fwrite </Н1> <?php $handle = fopen ("text.txt", "wb") ; $text = "Просто\пстрока\птекста.\n"; if (fwrite ($handle, $text) == FALSE) { echo "Ошибка записи в файл 'text.txt'.";
Добавление к файлу: fwrite 243 } else { echo "Файл 'text.txt' успешно создан. } fclose ($handle); </CENTERx/BODY> </HTML> файл Правка |Эид ^бранное Сервис "правка '''■""'■ "' .:■-.■■'-. ..... г^ цзбрвнное Ч? '■ '-*& УФ ^<Р IJ1 'l!1 'i. J" : V- n""" ^ ("DCCjjjgl http//localhost/php/07/phDfwrtte.php V>j  Переход Запись в файл при помощи fwrite ФайпЧехих^успешносоздан. Рис. 7.11. Запись в файл при помощи fwrite Добавление кфайлу: fwrite В предыдущем разделе был создан новый файл. Но часто требуется не создавать файл заново, а дописать в его конец какую-то информацию, не перезаписывая уже существующих данных. В таком случае при открытии файл следует использовать режим 'а': $handle = fopen ("text.txt", " ab" ) ;
244 Глава 7. ООП и файлы Пусть требуется дописать к файлу несколько строк текста. Для этого также может использоваться функция fwrite, что демонстрирует пример 7.12. Отличие от предыдущего примера состоит только в режиме открытия файла. Пример 7.12. Добавление к файлу при помощи fwrite, phpappend.php .<:■?- ->^,."^.<vV6;;--*S--:*.-&*Yj-.V-.'W- ?V й'.ЛА'Л "-iW ■!•-_■ ■ ■ - r-|- — ■ г Т"ГГ""'"ТГГ*Г1Т"ТГ 1~1ГГ ПГГМЛИ|ППГГ .11 ПТ| ТИПУГИи.и цППИПТТППЛТ'СГ I.T УЧИ УЧИиШ.рНУ *МЦап:<ц <HTML> <HEAD> <TITLE> Добавление к файлу при помощи fwrite </TITLE> </HEAD> <BODY> <CENTER> <Hl> Добавление к файлу при помощи fwrite </Н1> <?php $handle = fopen ("text.txt", " ab " ) ; $text = "Это\пдобавленный\птекст.\n"; if (fwrite ($handle, $text) == FALSE) { echo "Ошибка записи в файл text.txt."; } else { echo 'Текст добавлен к файлу text.txt."; } fclose (Shandle); ?> </CENTER> </BODY> </HTML> В результате выполнения примера выводится сообщение об успешной операции записи — см.рис. 7.12 . При помощи стандартных средств операционной системы можно проверить, что сейчас файл text, txt содержит следующие строки: Просто строка текста. Это добавленный текст.
Запись файла целиком: fileputcontents 245 файл Правка Вид Избранное Сервис Справка *$ \-Ъ>П:: -те 1 ' ^;ж! IS \i : ' i-J Поиск "УИзбранное 431:Q»' S3 >rv\: gfht-tp.//lcca[hcst/php/07/phpappend.php i jQ Переход Добавление к файлу при помощи fwrite Текст добавлен к файлу test.txt. Рис. 7.12. Добавление к файлу при помощи fwrite Запись файла целиком: fileputcontents Для формирования файла необязательно открывать его, записывать данные и закрывать. Существует сокращенный способ (аналогично чтению файла целиком, рассмотренному выше) для выполнения этой операции — использование функции fileputcontents. Ее синтаксис приведен ниже: fileputcontents (string filename, string data [, int flags [, resource context]}) В параметре fl 1 ename задается имя файла, в который будет производиться запись данных, data представляет собой текстовую строку для записи в файл. Необязательный параметр flags задает дополнительные режимы открытия файла, он может принимать значение FILEUSEINCLUDEPATH, FILEAPPEND или их сумму. Значение FILEUSEINCLUDEPATH задает поиск файла по каталогам, указанным в параметре includepath конфигурационного файла php.ini. Значение FILEAPPEND включает режим добавления к файлу (по умолчанию существующий файл будет перезаписан). Последний необязательный параметр context задает контекст файла, который предназначен для дополнительной обработки потоков данных в файл и из файла (в данной книге контексты не рассматриваются).
246 Глава 7. ООП и файлы Эта функция осуществляет последовательное открытие файла (как fopen), запись в него (как fwrite) и закрытие (как fclose), при этом не требуется работать с дескриптором файла. В примере 7.13 приводится использование этой функции для формирования файла text. txt. В случае возникновения ошибки выводится соответствующее сообщение. Иначе выводится сообщение об успешной записи текста в файл, как на рис. 7.13. Пример 7.13. Созданиефайлапри помощи file_put_contents, phpfileputcontents.php ал*«овдл»ил> пася Hww»Hwu"%ufi:4ri.'iH»v*»«»p<«M»" чшп ***1Ш*<0лмты*4**0*эФ***»тт1Ф*Фа**н*ШФ&йФштеш**м*юга^^ i Ш Ми из ш i *m '■^пимям <HTML> <HEAD> <TITLE> Создание файла при помощи file_put_contents </TITLE> </HEAD> <BODY> <CENTER> <H1> Создание файла при помощи file_put_contents </Н1> <?php $text = "Просто\пнемного\птекста.\п"; if (file_put_contents ("text.txt", $text) == FALSE) { echo "Ошибка записи в файл text.txt."; } else { . echo "Текст записан в файл text.txt."; ?> </CENTER> </BODY> </HTML> В результате выполнения этого примера файл text.txt содержит следующие строки: Просто немного текста. На этом описание объектно-ориентированного программирования и работы с файлами закончено. В следующей главе будет рассмотрена более сложная работа с данными с использованием баз данных и языка SQL.
файл Правка Вод Избранное Сервис Справка О''--* 'Й'л1' 'Л ]Г*\ 3^ ; i:J* Поиск л-?;Ш5ранно ■weuj (■■§] hr>p://loc3lhost-/php/0"/phptleputeorTtents.php :^ ["Щ \Л Q Период Создание файла при помощи file_put_contents Текст записан в файл texttxt. Рис. 7.13. Формирование файла при помощи file_put_contents Итоги В этой главе описаны основы объектно-ориентированного программирования, а также работа с файлами. Функции предназначены для разбиения программы на отдельные законченные фрагменты. ООП предлагает сделать следующий шаг путем объединения данных и обрабатывающего их кода в объекты. Обработка файлов позволяет реализовать различные прикладные задачи, от создания гостевой книги до ведения простого инвентарного списка. Ниже перечислены краткие итоги главы: • Классы создаются при помощи оператора class. • Объекты создаются при помощи оператора new. • Данные и методы класса доступны при помощи оператора - >. • Доступ public подразумевает доступность данных и методов класса для всех. • Доступ private подразумевает доступность данных и методов только внутри того же класса. • Доступ protected подразумевает доступность данных и методов для всех наследников данного класса, включая его самого.
248 _ " Глава", ООП и файлы • Конструкторы представляют собой специальные методы для инициализации объектов. • Наследование позволяет базировать один класс на другом. • Метод базового класса может быть перекрыт другим одноименным методом в классе-наследнике. • Файлы открываются при помощи функции fopen. • Функция fgets считывает строку из открытого файла. • Функция f read предназначена для чтения двоичных данных из файла. • Для считывания файла целиком предназначена функция f ilegetcont ent s. • Для записи в файл следует использовать функцию fwrite. • Функция fileputcontents позволяет записать данные в файл, используя всего один вызов функции.
Глава 8 ВДМШ5»«В«*К*1»«»Ч»«У(ТО«5^^ Базы данных В РНР включена обширная поддержка разнообразных серверов баз данных, что позволяет создавать комплексные приложения, обрабатывающие значительные объемы данных. Все типы серверов баз данных, которые поддерживаются РНР, приведены в табл. 8.1. Таблица 8.1. СУБД, поддерживаемые в РНР Adabas Front Base Ingres MySQL PostgreSQL Unix dbm dBase Hyperwave InterBase ODBC Solid Velocis Direct Empress IBMDB2 mSQL Oracle SQLIte FilePro Informix MS-SQL Ovrimos Sybase Как видно, количество поддерживаемых типов баз данных достаточно велико, и охватить их в рамках одной книги затруднительно. Ниже будет детально рассмотрена работа широко распространенным и в то же время бесплатным для использования сервером баз данных MySQL, который часто используется совместно с РНР для создания web-приложений. Его можно загрузить с сайта www.mysql.com. В настоящее время последняя версия сервера — 5.1. Помимо MySQL, в данной главе рассматривается модуль DB, который предназначен для работы с различными типами серверов баз данных при помощи одного и того же набора функций. Модуль создает промежуточный уровень абстракции , позволяя разрабатывать переносимые приложения, которые не зависят от конкретного сервера. Платой за переносимость является некоторое (зачастую незначительное) снижение производительности. Описания функций РНР, предназначенных для поддержки разнообразных серверов баз данных, можно найти в Интернете по адресу www.php.net/dbraame, где dbname — имя сервера базы данных, например mysql, Sybase, mssql и т.п. Для ODBC следует использовать имя uodbc, для Oracle — oci8. Использование
250 Глава 8. Базы данных непосредственной поддержки конкретного сервера базы данных (вместо модуля DB) может в лучшую сторону сказаться на производительности приложения, а также предоставить возможность использования специфических особенностей базы данных. Базы данных Что же такое база данных? База данных представляет собой централизованное хранилище, предназначенное для хранения, доступа и обработки данных под управлением прикладной программы. Чаще всего базы данных строятся на основе таблиц. Чтобы описать концепцию таблицы, рассмотрим следующий пример. Пусть требуется составить реестр экзаменационных оценок студентов в группе. Он может выглядеть, например, как табл. 8.2. Таблица 8.2. Реестр экзаменационных оценок Имя Андрей Борис Василий Екатерина Иван Максим Сергей Филипп Оценка 4 5 5 4 4 3 4 3 Эта таблица практически полностью соответствует таблице базы данных. Но, в отличие от бумажного документа, таблица базы данных предоставляет гораздо больше возможностей для обработки информации, в частности, сортировку, поиск, добавление, изменение и удаление строк. Имеется возможность связывать различные таблицы между собой путем создания отношений (англ. relations). Базы данных, допускающие создание отношений между таблицами, называются реляционными. Каждый отдельный элемент данных в таблице, например, оценка студента, является полем таблицы. Объединение полей (в рассматриваемом примере это имя и оценка) представляет собой запись. Каждая запись в таблице представлена отдельной строкой, а каждый столбец в строке представляет собой поле. Набор строк, каждая из которых содержит один и тот же набор полей, образует таблицу базы данных. Так что же такое база данных? В простейшей форме база данных представляет собой набор из одной или нескольких таблиц. Для доступа к данным в таблицах обычно используется язык SQL, который рассматривается в следующем разделе.
Основы SQL 251 Основы SQL Для работы с базами данных обычно используется язык SQL (Structured Query Language), и РНР не является исключением. В данном разделе рассматриваются базовые конструкции SQL, которые требуются для выполнения основных действий с базами данных в РНР. Читатели, уже имеющие опыт работы с SQL, могут пропустить данный раздел. Предположим, существует таблица базы данных с именем fruit, которая содержит данные о складе фруктов. Таблица содержит два поля: пате, содержащее название фрукта, и number, содержащее количество данного фрукта на складе. Чтобы считать данные из этой таблицы для последующей обработки в скрипте, необходимо выполнить следующий оператор языка SQL (запрос): SELECT * FROM fruit Если в качестве сервера базы данных используется MySQL, то для выполнения запроса используется функция mysqlquery, например: $query = "SELECT * FROM fruit"; $result = mysqlquery ($query) or die ("Ошибка при выполнении запроса: ".mysql error ()); Оператор SELECT используется для выборки данных из заданной таблицы. После ключевого слова SELECT указывается перечень полей, которые возвращаются в качестве результата выполнения запроса. Выше использован символ « * », который означает, что вернуть следует все поля таблицы, указанной после ключевого слова FROM Можно также перечислить все поля в явной форме (в данном случае эти конструкции эквивалентны): SELECT name, number FHCM fruit Запросы, приведенные выше, возвращают все строки таблицы. Имеется возможность выбрать только те записи таблицы, которые удовлетворяют заданному условию. Для этого используется ключевое слово WHERE Например, для выборки всех записей, у которых в поле «name» указано «яблоки», используется следующий запрос: SELECT * FROM fruit WHERE name= "яблоки" Помимо сравнения, в запросах можно использовать следующие операторы: • < (меньше); • <= (меньше или равно); • > (больше); • >= (больше или равно). Кроме того, с использованием ключевого слова IN можно задать перечень значений, среди которых должно находиться значение поля для выполнения условия. Например, для выборки всех записей о яблоках и апельсинах можно использовать следующий запрос: SELECT * FROM fruit WHERE name IN ("яблоки", "апельсины") Для построения условия можно использовать также и логические операторы. Например, требуется выбрать все записи из таблицы, удовлетворяющие следующим двум условиям: в поле «name» указано «яблоки» или «апельсины», а поле «number» содержит какое-либо значение (считается, что поле, которое не содержит никакого значения, содержит специальное значение NULL):
252 _. " „ Глава 8. Базы данных SELECT * FROM fruit WHERE name IN ("яблоки", "апельсины") AND number IS NOT NULL Для построения сложных условий используются три логических оператора — AND, OR и NOT. Если два простых условия объединены при помощи AND, то результирующее условие выполняется только в том случае, когда оба простых условия выполняются. Если же два простых условия объединены при помощи OR, то результат является истинным, если хотя бы одно из простых условий истинно. Оператор NOT производит логическую инверсию условия — истинное становится ложным и наоборот. Результат, возвращаемый оператором SELECT, может быть отсортирован по заданному критерию. Например, для сортировки записей по алфавиту по наименованию фрукта может быть использован следующий запрос: SELECT * FROM fruit ORDER BY name Этот оператор производит упорядочение по возрастанию. Для сортировки по убыванию используется ключевое слово DESC: SELECT * FROM fruit ORDER BY name DESC Для удаления записей используется оператор DELETE. Ниже приведен запрос, который удаляет все записи из таблицы fruit, которые не относятся к яблокам или апельсинам: DELETE FROM fruit WHERE name NOT IN ("яблоки", "апельсины") Для изменения записей используется оператор UPDATE Например, для изменения количества яблок в таблице fruit может быть использован следующий запрос: UPDATE fruit SET number = 006" WHERE name = "яблоки" Наконец, для добавления новых записей в таблицу используется оператор INSERT. К примеру, следующий запрос служит для добавления в таблицу fruit сведений об абрикосах: INSERT INTO fruit (name, number) VALUES ('абрикосы', '203') На этом краткий обзор SQL-запросов заканчивается. В следующем разделе рассматривается вопрос настройки РНР для работы с базами данных. Настройка РНР для работы с базами данных Настройка РНР для работы с базами данных может быть несколько утомительной и зависит от используемой операционной системы. Ниже описываются наиболее часто встречающиеся случаи. Если используются операционные системы Unix, Linux или Mac, то для подключения поддержки баз данных следует указать соответствующие параметры при установке РНР. Подробно этот процесс описывается в руководстве по установке, которое можно получить в Интернете по адресу www.php.net/dbname. Например, для подключения поддержки MySQL 4.0 используется опция конфигурации -with-mysql [=DIR], где DIR задает каталог, в котором установлен MySQL (по умолчанию это /usr/local/mysql). Начиная с версии 4.1, параметр
Создание базы данных в My_SQL^^_ _^__ 253 DIR должен указывать на каталог, в котором расположен конфигурационный файл MySQL с именем mysqlconfig. Для подключения поддержки Oracle используется опция -with-осi8 [=DIR], где DIR задает каталог расположения Oracle (по умолчанию используется переменная среды ORACLEHOME). Хостинг-провайдеры обычно предлагают web-серверы с уже настроенным доступом к тем или иным базам данных, так что подобными настройками придется заниматься только при локальной установке РНР для разработки web-приложений. В Windows поддержка баз данных осуществляется при помощи библиотек расширения, которые располагаются в подкаталоге ext каталога, в который установлен РНР (обычно это С: \PHP\ext). Этот каталог задается в конфигурационном файле php. ini в параметре extensiondir. Для подключения того или иного расширения следует добавить в конфигурационный файл php. ini строку вида extension=name, гделате — имя соответствующей библиотеки. Обычно все необходимые строки уже присутствуют в файле php. ini, но отключены при помощи символа комментария («;»). Поэтому достаточно удалить этот символ в соответствующей строке файла. Если РНР подключен как модуль web-сервера, то после этого требуется перезапуск службы web-сервера. Например, для подключения поддержки MySQL следует убрать символ «;» в строке, подключающей библиотеку phpmysql. dll: ; extension=php_mime magic . dll ; extension=php_ming.dll ; extension=php_mssql.dll ;extension=php_msql.dll extension=php_mysql.dll ;extension=php_oci8.dll ; extension=php_openssl.dll ;extension=php_oracle.dll ; extension=php_pgsql.dll Создание базы данных в MySQL Ниже описывается процесс создания базы данных средствами MySQL. Если MySQL не запущен как системный сервис, то его можно запустить вручную из командной строки. Для этого следует перейти в каталог mysql/bin и ввести следующую команду1: %mysqld —console Для доступа к серверу используется утилита mysql.Чтобы запустить ее, необходимо перейти в каталог mysql/bin и ввести следующую команду (параметр —и задаетимя пользователя, а параметр—р осуществляет запрос пароля): %mysql -u root -p Enter password: ******* Welcome to the MySQL monitor. Commands end with ; or \g. mysql> Если MySQL уже запущен как системная служба, при попытке повторного запуска будет выдано сообщение об ошибке, например: "Do you already have another mysqld server running on port: 3306?". Прим.ред.
254 Глава 8. Базы данных В командной строке MySQL в качестве первого запроса можно ввести следующую команду, которая отобразить версию сервера и текущую дату: mysgl> SELECT VERSION! ) , CURRENT_DATE; Н 1 h I VERSION() I CURRENT_DATE I I 4.0.20a I 2004-09-06 I 1 row In set @.05 sec) Для просмотра списка уже имеющихся баз данных используется оператор SHOW DATABASES: mysql> SHOW DATABASES ; H h I Database I I mysql I 1 test I 2 rows in set @.01 sec) В поставку MySQL включены две базы данных — mysql, которая содержит служебные данные, и test, которая является примером. Для разработки собственных приложений имеет смысл создать отдельную базу данных, например, с именем db, что осуществляется при помощи команды CREATE DATABASE mysgl> CREATE DATABASE db; Query OK, 1 row affected @.01 sec) Для того чтобы сделать вновь созданную базу данных текущей, используется оператор USE: mysql> USE db Database changed Можно убедиться в том, что созданная база не содержит еще ни одной таблицы. Попытка использования команды SHIXV TABLES вернет результат «Empty set», что означает, что результат выполнения запроса не содержит ни одной строки ( в данном случае таблицы): mysql> SHOW TABLES; Empty set @.01 sec) Для создания таблицы используется запрос CREATE TABLE, в котором следует перечислить все поля таблицы с указанием их типа. Существует большое количество типов данных, ниже приведены те из них, которые используются в примерах в данной главе: • \ARCHAR {length). Строка символов переменной длины, максимальная длина строки равна length. • INT. Целое число. DECIMAL (totaldigits, decimalplaces). Десятичное число, общее количество цифр — totaldigits, количество знаков после запятой — decimalplaces. ш DATETTME. Дата и время, например «2006-04-02 22:00:00».
Добавление данных 255 Оператор, приведенный ниже, создает таблицу fruit, которая содержит два поля — пате и number, оба — строкового типа: mysql> CREATE TABLE fruit (name VARCHARB0), number VARCHARB0)) Query OK, 0 rows affected @.13 sec) mysql> SHLW TABLES; + + I Tables_in_db I I fruit I 1 row in set @.00 sec) Для вывода структуры созданной таблицы используется команда DESCRIBE: mysql> DESCRIBE fruit; 4 И 4 У 4 1 + I Field I Type I Null I Key I Default I Extra I ч ч ч ч н i + I name I varcharB0) I YES I I NULL I I 1 number I varcharB0) I YES I I NULL I I ч и ч ч 1 i + 2 rows in set @.01 sec) Добавление данных В предыдущем разделе была создана база данных db, содержащая единственную таблицу fruit. В данном разделе описывается процесс добавления данных в эту таблицу. Пусть требуется занести в базу данные, приведенные в табл. 8.3. Таблица содержит два поля — пате, содержащее наименование фрукта, и number, содержащее количество соответствующего фрукта. Таблица 8.3. Данные по фруктам name яблоки груши бананы апельсины number 1020 3329 8582 235 Для ввода этих данных можно воспользоваться командной строкой MySQL (порядок ее запуска приведен в предыдущем разделе). После перехода к базе данных db при помощи команды USE для добавления данных используется оператор INSERT: mysql> USE db Database changed mysql> INSERT INTO fruit VALUES ( 'яблоки1, '102 0 ' ) ; Query OK, 1 row affected @.00 sec) mysql> INSERT INTO fruit VALUES ('груши', '3329') ;
256 Глава 8. Базы данных Query OK, I row affected @.00 sec) mysql> INSERT INTO fruit VALUES ('бананы', -8582'); Query OK, 1 row affected @.00 sec) mysql> INSERT INTO fruit VALUES ('апельсины', '235'); Query OK, 1 row affected @.00 sec) Для проверки того, что все данные внесены корректно, используется запрос SELECT, который отображает все строкитаблищ^г u i t. Послеэтого сеанс работы с MySQL можно закончить при помощи команды QUIT: ntysql> SELECT * ШСМ fruit; j „ _ -J- i- 1 name I number | I apples I 1020 I 1 oranges I 3329 I I bananas I 8582 I pears 123 5 I 4 rows in set @.00 sec) mysql> QUIT Доступ к базе MySQL После предварительной подготовки можно переходить к использованию возможностей MySQLnpn помощи РНР. Для этого необходимо иметь запущенный сервер базы данных. Если сервер не запущен как системный сервис, его можно запустить при помощи команды my s q 1 d, расположенной в каталоге ту s q 1 /bi n: %mysqld —console Для остановки сервера может быть использована следующая команда: %mysqladmin -u root —p shutdown Для установления соединения с сервером базы данных из скрипта РНР используется функция mysqlconnect, которой на вход передаются имя узла, на котором запущен сервер, имя пользователя и пароль: Sconnection = mysgl_connect ("localhost", "user", "password") or die ('Ошибка соединения с сервером"); После успешного установления соединения для выбора текущей базы используется (pyHKin«imysql_select_db: $db = mysqlselectdb ("db", Sconnection) or die ("Ошибка при выборе базы данных"); Наконец, для выбора всех строк из таблицы fruit можно выполнить SQL-запрос при помощи функции mysqlquery.B случае возникновения ошибки функция mysqlerror возвращает ее развернутое текстовое описание: Squery = 'SELECT * H£M fruit"; Sresult = mysql_query( Squery) or die("Query failed: " . mysql_error()); Помимо этих функций для работы с MySQL предназначен целый набор различных средств. Ниже приведен перечень наиболее часто употребительных функций:
Доступ к базе MySQL 257 • mysql affected rows. Количество строк, затронутых последним запросом INSERT, UPDATE ИЛИ DELETE (но не SELECT). • mysgl change user. Регистрация от имени другого пользователя. • mysql client епс о di ng. Текущая кодировка, используемая на клиенте. • mysqlclose. Завершение соединения с сервером базы данных. • mysql connect. 'Установление соединения с сервером базы данных. • mysql create db. Создание базы данных. • mysqldataseek. Перемещение указателя в наборе данных результата запроса SELECT. • mysql db name. Имятекущей базы данных. • mysql db query.Выполнениепроизвольного8(ЗЬ-запросакзаданнойбазе данных. • Tysql drop db .Удаление базы данных. • mysql error. Текст сообщения об ошибке, возникшей в результате предыдущей операции. • mysqlfetcharray. Формирование строки из набора данных результата запроса SELECT, в виде массива, проиндексированного номерами полей, именами полей или одновременно обоими индексами. • my s qlfetchassoc. Формирование строки из набора данных результата запроса SELECT, в виде массива, проиндексированного именами полей. • mysql fetch row. Формирование строки из набора данных результата запроса SELECT, в виде массива, проиндексированного номерами полей. • my s ql _fi eld len. Длина заданного поля результата запроса SELECT. • mysql field name. Имя заданного поля результата запроса SELECT. • mysql field seek. Перемещение указателя на заданное поле результата запроса SELECT. • mysql field table. Имя таблицы заданного поля результата запроса SELECT. • mysql f i e 1 dtyp e. Тип заданного поля результата запроса SELECT. • mysql get server info. Информация о сервере базы данных. • mysql info. Информация о последнем выполненном запросе. • mysql list db s. Список баз данных MySQL-сервера. • mysql list fields. Список полей заданной таблицы. • mysql list tables. Список таблиц заданной базы данных. • mysql num f i elds. Количество полей в результате запроса SELECT. • mysql num rows.Количествострокврезультатезапроса8ЕЕЕСТ. • my s ql p connect. Установление постоянного соединения с сервером базы данных. • mysql query. Выполнение произвольного SQL-запроса к текущей базе данных. • mysql result. Результат запроса SELECT. • mysql select db. Выбор текущей базыданных. • mysql table name. Имятаблицы,содержащейуказанноеполе. 9 PHP в примерах
258 Глава 8. Базы данных Создание базы данных Первым шагом при работе с SQL-сервером является создание базы данных. Для этого необходимо установить соединение с MySQL, что осуществляется при помощи функции mysqlconnect (при необходимости следует задать другие имя и/или пароль пользователя): Sconnection = mysqlcoimect ("localhost", "user", "password") or die ("Ошибка соединения с сервером"); Далее при помощи функции mysqlquery выполняется SQL-запрос, который создает базу данных. $query = "CREATE DATABASE IF NOT EXISTS dt>"; $result = mysgl_guery ($query) or die("Ошибка при выполнении запроса: ".mysql_error ()); Наконец, происходит выбор только что созданной базы данных при помощи функции mysqlselectdb. После завершения работы с базой данных необходимо разорвать соединение с SQL-сервером, для чего предназначена функция mysqlclose. Порядок создания базы данных продемонстрирован на примере 8.1, а результат его выполнения представлен на рис. 8.1. После того как база данных будет успешно создана, можно переходить к созданию таблиц, о чем рассказывается в следующем разделе. 3 Созданиебазыданных-MicrosottlnternetExniorer |_ |[П|[х| файл Правка вид ^бранное Сервис (^правка ■ ,ЕР CJ...... €> • @ [И €237)по к -й'Иа6еанное Ф\ш Ш - ... W\ |Ц| Переход [ Сшцкк Создание базы данных База данных 'db' успешно создана Рис. 8.1. База данныху спешно создана
Создание новой таблицы 259 Примере. 1. Создание базы данных, phpdatacreatedb.php <HTML> <HEAD> <TITLE> Создание базы данных </TITLE> </HEAD> <B0DY> <CENTER> <Н1>Создание базы данных</Н1> <?php $connection = mysql_connect ("localhost" , "user", "password") or die ("Ошибка соединения с сервером"); $query = "CREATE DATABASE IF NOT EXISTS db"; $result = mysql_query ($query) or die("Ошибка при выполнении запроса: ".mysql_error О) ; $db = mysql_select_db ("db", $connection) or die ("Ошибка при выборе базы данных") ; echo "База данных 'db' успешно создана"; mysql_close ($connection); ?> </CENTER> </BODY> </HTML> Создание новой таблицы Для создания таблицы требуется установить соединение с SQL-сервером и выбрать базу данных, в которой она будет размещена. Эти операции уже были рассмотрены выше. После этого необходимо сформировать SQL-запрос, который описывает структуру создаваемой таблицы, и исполнить его при помощи функции mysqlquery: Squery = "CREATE TABLE fruit (name VARCHARB0), number INT)"; Sresult = mysqlquery (Squery) or die ("Ошибка при выполнении запроса: ".mysql error ()); Полностью скрипт для создания таблицы приведен в примере 8.2, а на рис. 8.2 показан результат его выполнения. Как видно, таблица успешно создана, и можно переходить к наполнению ее данными, о чем рассказывается в следующем разделе.
Глава 8. Базы данных файл Правка Вид Избранное Сервис Справка fli5C*^l'i(E| htSp://localhost/php/08/phpdatacreate.php * *3 И Переход Создание таблицы Таблица Trait' успешно создана Рис. 8.2. Таблица успешно создана Пример8.2.Созданиеновойтаблицы,рЬрс1а1асгеа1е.рЬр <HTML> <HEAD> <TITLE> Создание таблицы </TITLE> </HEAD> <BODY> <CENTER> <Н1>Создание таблицы</Н1> <?php $connection = mysql connect ("localhost", "user", "password") or die ("Ошибка соединения с сервером"); $db = mysql select db ("db", $connection) or die ("Ошибка при выборе базы данных"); $query = 'CREATE TABLE fruit (name \S\RCHARB0), number INT)" ; $result = mysql query (Squery) or die ("Ошибка при выполнении запроса: ".mysql error ());
Добавление данны£_ 261 echo "Таблица 'fruit' успешно создана"; mysql_close ($connection); ?> </CENTER> </B0DY> </HTML> iwhi i— И1ИИИШ Hi hwhiiihhhw— imiimi ■imih«1ммм]ци^«>.^1<|«ц||1ииiiMiniiiP нищими ищи i.m.mi iwim ikiiiii in «» i m i r>rt*v*умнлг-о*t'■*.env-*-:.<ляп*я■i-*v«>'>vjv■w-kt.о*'*-. Добавление данных Созданная в предыдущем разделе таблица пуста. Чтобы наполнить ее данными, можно воспользоваться SQL-запросом INSERT. После установления соединения с SQL-сервером и выбора базы данных формируется запрос на добавление строки в таблицу, который исполняется при помощи уже знакомой функции mysql_query: $query = "INSERT INTO fruit (name, number) VALUES ('яблоки1, ' 2 0 3 ■)" ; $result = mysql_query ($query) or die ("Ошибка при выполнении запроса: ".mysql_error ()); В примере 8.3 в таблицу fruit добавляются три строки, содержащие сведения про яблоки, груши и персики. На рис. 8.3 демонстрируется успешное завершение этих операций. Как же теперь просмотреть содержимое базы данных? Об этом — в следующем разделе. Пример 8.3. Добавление данных в таблицуКи'Л, phpdatainsert.php <HTML> <HEAD> <TITLE> Добавление данных </TITLE> </HEAD> <BODY> <CENTER> <Н1>Добавление данных</Н1> <?php $connection = mysql_connect ("iocalhost", "user", "password") or die ("Ошибка соединения с сервером"); $db =mysql_select_db ("db", $connection) or die ("Ошибка при выборе базы данных") ; $query = "INSERT INTO fruit (name, number) VALUES ( ' яблоки' , '203 ' ) " ; $result = mysql_query ($query) or die ("Ошибка при выполнении запроса: ".mysql_error ()); $query = "INSERT INTO fruit (name, number) VALUES ( ' груши' , '431')";
262 Глава 8. Базы данных $result = mysql_query ($query) or die ("Ошибка при выполнении запроса: ".raysql_error 0); $query = "INSERT INTO fruit (name, number) VALUES ( ' персики' , '961')"; $result = mysql_query ($query) or die ("Ошибка при выполнении запроса: ".mysql_error ()); echo "Данные добавлены успешно"; mysql_close ($connection); ?> </CENTER> </BODY> </HTML> ■i A«f 'J*. *^fiW*V'i^b:><.,^*T.Ai>«*C«",?>-iT'ii<v.'>*=i>i >i >--;,-* h-OC Ш' -X ^Mi'/A» Л! «VCW. К *M3Mt>*i MO M>; файл Правка Вид Избранное Сервис Справка .. * Поиск V..V Избранно» ^j$ ,>^. i-jj » Адрес; \Щ http://tocalhost/php/08/phpdatainsert.php 7Щ |Ц Переход Ссыпки Добавление данных Данные добавлены успешно Рис. 8.3. Добавление данных в таблицу Отображение данных В предыдущих разделах была создана база данных и таблица fruit, содержащая три строки. Чтобы отобразить все строки этой таблицы в виде HTML-документа, используется SQL-запрос SELECT. В результате выполнения этого запроса формируется набор данных, содержащий все строки требуемой таблицы.
Отображение данных 263 $query = "SELECT * FROM fruit"; $result = mysql_query ($query) or die ("Ошибка при выполнении запроса: " .mysql_error ()); Для последовательного отображения всех строк таблицы используется цикл while в сочетании с функцией mysqlfetcharray. Эта функция возвращает очередную строку из набора данных в виде массива, проиндексированного именами полей таблицы: while ($row = mysgl_fetch_array ($result)) { echo "<TD>", Srow ['name'], "</TDxTD>" , Srow ['number'], "</TD>"; echo "<TR>"; echo "<TD>", /TD>"; echo "</TR>"; Пример 8.4 демонстрирует использование всех вышеупомянутых функций, а на рис. 8.4 приведен результат работы этого примера. 9 ОгоОдошенне данных файл Правка £ид избранное Сервис Справка 9- ч}  i*S "k'ti ■ у ■"■"•■•■ <!;гm«p»«o».-0 . °;£ ^ Нзр-с: № .http :"IOLsJhost/php/OS/phpdatahablaphp v I ЛПЕрвдц Отображение данных ^Наименование; Количество яблоки ,20i |груши ;431 персики ;961 Рис. 8.4. Отображение таблицы fruit
264 Плавав. Базы данных npMMep8.4.0To6pa)KeHMeflaHHbix,phpdatatable.php ■Ччжлллол*pv. к x/»^x^s^* cuM№r**i ?е*лак ча» л&улыжмс&цулльвн*!'. и япалстл «ломим <HTML> <HEAD> <TITLE> Отображение данных </ТТТЬЕ> </HEAD> <BODY> <CENTER> <Н1>0тображение данных</Н1> < ?php Sconnection = mysqlconnect ("localhost", "user", "password") or die ("Ошибка соединения с сервером"); Sdb = mysqlselectdb ("db", Sconnection) or die ("Ошибка при выборе базы данных"); Squery = "SELECT * FROM fruit"; Sresult = mysqlquery (Squery) or die ("Ошибка при выполнении запроса: ".mysqlerror ()); echo "<TABLE BORDER='l'>"; echo "<TR>"; echo "<ТН>Наименование</ТНхТН>Количество</ТН>" ; echo "</TR>"; while ($row = mysql_fetch_array ($result)) { echo "<TR>"; echo "<TD>", $row ['name'], "</TDxTD>", $row ['number'], "</TD>"; echo "</TR>"; } echo "</TABLE>"; mysql_close ($connection); ?> </CENTER> </BODY> </HTML> Изменение данных Данные, которые нельзя скорректировать, будут лежать мертвым ненужным грузом. Для изменения данных требуется всего лишь написать соответствующий SQL-запрос. Например, требуется изменить количество яблок в таблице fruit. Для начала следует установить соединение с базой данных аналогично тому, как это сделано в предыдущих разделах. Потом выполняется SQL-запрос, изменяющий заданную строку в таблице:
Изменение данных 265 $query = "UPDATE fruit SET number = 234 WHERE name = 'яблоки'"; $result = mysql_query ($query) or die ("Ошибка при выполнении запроса: " .mysql_error () ) ; Наконец, измененная таблица отображается в окне браузера. Пример 8.5 демонстрирует возможность изменения данных в базе MySQL при помощи РНР, а результат выполнения этого кода приведен на рис. 8.5. Видно, что количество яблок в таблице изменилось по сравнению с рис. 8.4. Примере. 5. Изменение да HHbix,fDhfDdataufDdate.fDhfD <HTML> <HEAD> <TITLE> Изменение данных </TITLE> </HEAD> <BODY> <CENTER> <Н1>Изменение данных</Н1> <?php Sconnection = mysql connect ("localhost", "user", "password") or die ("Ошибка соединения с сервером"); $db = mysql select db ("db", $connection) or die ("Ошибка при выборе базы данных"); Squery = "UPDATE fruit SET number = 234 WHERE name = 'яблоки'"; {result = mysql_query (Squery) or die ("Ошибка при выполнении запроса: ".mysqlerror ()); Squery = "SELECT * FROM fruit"; Sresult = mysqlquery (Squery) or die ("Ошибка при выполнении запроса: ".mysql error ()); echo "<TABLE BORDER=' 1 ' >" ; echo "<TR>"; echo "<ТН>Наименование</ТНхТН>Количество</ТН>" ; echo "</TR>"; while ($row = mysql_fetch_array ($result)) { echo "<TR>"; echo "<TD>", $row ['name'], "</TDxTD>", $row ['number'], "</TD>"; echo "</TR>"; } echo "</TABLE>"; mysql_close ($connection); ?> </CENTER> </BODY> </HTML>
266 Глава 8. Базы данных файл Правка |}ид Избранное Сервис ^правка I j j !'.*.!.№ • i,,j ;*j :*j ,;. ,3 ^,/Покк -ту- Ифвжзе «Ц| ■ , , л Щ Адрес., | ") http://localhost/php/OS/phpdataupdal:e.php * .-V"! "J Переход . 0"i: Изменение данных Наименование Количество / ;яблоки ;234 I :груши :431 персики :961 Рис. 8.5. Изменение количества яблок в таблице fruit Сортировка данных В примере 8.4 данные выводятся в том порядке, в каком они были добавлены в таблицу. Но гораздо удобнее видеть данные, упорядоченные по какому-либо критерию. Для этого в запросе SELECT используется конструкция ORDER BY. В ней задается поле, перечень полей или выражение, которое используется для сортировки данных. Необязательный параметр DESC задает сортировку в обратном порядке. Ниже приведен фрагмент кода, который возвращает список фруктов, отсортированный по их наименованию: $query = "SELECT * FROM fruit ORDER BY name"; $result = mysql_query ($query) or die ("Ошибка при выполнении запроса: " .mysql_error ( ) ) ; Этот фрагмент использован в примере 8.6, а результат его работы представлен на рис. 8.6. Отображение упорядоченных данных гораздо более комфортно для пользователя.
Сортировка данных 267 файл Правка В^д Избранное Сервис "правка :ifJ !£3 1"* |j : >■-' Поисй "■ .'^;'Избранное Л*л ,.' '■.. j?^i -леес=.! ^ hkkp:/ikcdhoftt^hpfOB/plhpd«lta5art.pki» V 1 ЁJ Пфавд ^''^-* Сортировка данных Наименование Количество, ;груши i-131 ; ;персики j.»fil Ляблоки ;234 Рис. 8.6. Отображение отсортированных данных Примере. 6. CopTHpoBKaflaHHbix,phpdatasort.php "J* H>. ■" -.'.- '.< гч; к*^:? а«,ч* *>Лл1 i i.-fi у; -^ i» <HTML> <HEAD> <TITLE> Сортировка данных </TITLE> </HEAD> <BODY> <CENTER> <Н1>Сортировка данных</Н1> <?php $connection = mysgl_.connect ("localhost", "user" or die ("Ошибка соединения с сервером"); "password") $db = mysql_select_db ("db", $connection) or die ("Ошибка при выборе базы данных") ; $query = "SELECT * FROM fruit ORDER BY name' $result = mysql_query ($query) or die ("Ошибка при выполнении запроса: .mysql_error ( ) ) ; echo "<TABLE BORDER='1''>"; echo "<TR>" ; echo "<ТН>Наименование</ТНхТНЖоличество</ТН>" ; echo "</TR>";
268 ^ ^ Глава 8. Базы данных while ($row = mysql_fetch_array ($result)) { echo "<TR>"; echo "<TD>" , $row ['name'], "</TDxTD>" , $row ['number'], "</TD>"; echo "</TR>"; } echo "</TABLE>"; mysql_close ($connection); ?> </CENTER> </B0DY> </HTML> Г i rJJIKW ?■ ?&.'■& Уд ал ение данных Для удаления данных из таблицы используется SQL-запрос DELETE. В запросе обычно присутствует условие WHERE, идентифицирующее те данные, которые следует удалить. Если по ошибке опустить условие, то будут удалены все записи из таблицы, так что в этом случае следует быть особенно внимательным. Например, удаление из таблицы f rui t заданного фрукта естественным образом производится по его названию, как показано ниже: $query = "DELETE FROM fruit WHERE name = 'яблоки'"; $result = mysql_query ($query) or die ("Ошибка при выполнении запроса: " .mysql_error ( ) ) ; Пример 8.7 демонстрирует удаление одной строки в таблице fruit и отображение всех оставшихся в ней записей, а на рис. 8.7 представлен результат выполнения этого примера. Следует обратить внимание на то, что если условию отбора строк для удаления не удовлетворила ни одна запись из таблицы, это не является ошибкой, а такую ситуацию следует диагностировать отдельно при помощи функции mysqlaf fectedrows. Примере. 7. Удаление данных, phpdatadelete.php <HTML> <HEAD> <TITLE> Удаление данных </TITLE> </HEAD> <BODY> <CENTER> <Н1>Удаление данных</Н1> <?php Sconnection = mysqlconnect ("localhost", "user", "password") or die ("Ошибка соединения с сервером");
Удаление данных 269 0); 0); $db = mysql_select_db ("db", $connection) or die ("Ошибка при выборе базы данных") ; $query = "DELETE FROM fruit WHERE name = 'яблоки'"; $result = mysql_query ($query) or die ("Опибка при выполнении запроса: ".mysql_error $query = "SELECT * FROM fruit"; $result = mysql_query ($query) or die ("Ошибка при выполнении запроса: " .mysql_error echo "<TABLE B0RDER='1'>"; echo "<TR>"; echo "<ТН>Наименование</ТНхТН>Количество</ТН>" ; echo "</TR>"; while ($row = mysql_fetch_array ($result)) { echo "<TR>"; echo "<TD>" , $row ['name' ['number'], "</TD>"; echo "</TR>"; } echo "</TABLE>"; mysql_close ($connection); ?> </CENTER> </B0DYx/HTML> '</TDxTD>" , $row те&л*иу***а&ж(яюжачлч*&:ааю*АЫ1глг*'-; «vikhw*.* >: whm <**. bqvj «MSforiM^: к ^/■^ч«>; ■ »■* >л<т» < г?жыя&кл.**х?х>, файл Правка £ид Избранное Сервис Справка фныл • ф • Q Q U ) рПоиск «"Избрвннэе ф\ ЛЩ АДР«'/ \Ш http://kxaJhost/php/08/phpdatadelete.php uf Щ Переход . Ссыжи Удаление данных Наименование! Количество I !груши ;431 персики J961 ; Рис'. 8.7. Удаление строки таблицы
270 Глава 8. Базы данных Установка модуля DB Наряду с непосредственной поддержкой различных серверов баз данных, РНР предлагает модуль DB, который создает промежуточный слой абстракции между приложением и базой данных. При помощи DB, можно работать с различными серверами, используя один и тот же набор функций. Это позволяет создавать переносимые приложения, не зависящие от того, какая база данных используется в конкретном случае. При изменении типа базы данных требуется всего лишь указать ее тип при подключении — все остальные функции останутся теми же самыми. DB является расширением РНР, которое управляется при помощи PEAR (РНР Extension and Application Repository — репозиторий расширений и приложений РНР). Обычно PEAR устанавливается вместе с РНР (о его наличии свидетельствует файл pear .php в каталоге РНР). Если же он не установлен, можно воспользоваться сайтом go-pear.org, на котором размещен скрипт для загрузки PEAR, или (в случае Windows-установки) командным файлом go-pear, bat, который всегда устанавливается в каталоге РНР1. После выполнения скрипта или командного файла появится возможность вызвать PEAR при помощи одноименной команды PEAR (в случае Windows она представляет собой ВАТ-файл). При запуске без параметров выдается краткий список команд PEAR. При установке РНР или PEAR некоторые модули могут быть уже загружены на компьютер, поэтому имеет смысл проверить перечень имеющихся модулей. Для этого используется команда PEAR LIST: %> pear list INSTALLED PACKAGES, CHANNEL PEAR.PHP.NET: PACKAGE VERSION STATE Archive Tar 1.3.1 st ab 1 e Console Getopt 1.2 stable PEAR 1.4.6 stable Поскольку в списке нет модуля DB, придется его установить (если модуль уже загружен, повторно загружать его не требуется). Для этого используется следующая команда: %> pear install DB В PEAR содержится достаточно много программных пакетов и приложений, полный перечень их выводится по следующей команде (список достаточно длинный, приведен его фрагмент). В списке указана последняя доступная версия пакета (LATEST) и версия, установленная на данном компьютере (LOCAL). Для установки самого PEAR и любых модулей с его помощью требуется подключение к Интернету, так как все программные компоненты и пакеты загружаются непосредственно из сети. — Прим. ред.
Отображение данных при помощи DB 271 %> pear list-all ALL PACKAGES: PACKAGE pear/Auth_HTTP pear/Auth pear/Auth_SASL pear/LiveUser pear/Auth_PrefManager pear/Auth_RADIUS pear/Auth_PrefManager2 pear/LiveUser_Admin pear/Benchmark pear/Cache pear/Cache_Lite pear/Config pear/Console_Getopt pear/System_Command pear/Console._Table pear/Console_Color pear/Console_ProgressBar pear/Console_Getargs pear/DB_Pager pear/DB LATEST 2.1.6 1.3.0RC6 1.0.1 0.16.9 1.1.4 1.0.4 2.0.Odevl 0.3.7 1.2.5 1.5.5RC4 1.7.0 1.10.6 1.2 1.0.4 1.0.2 0.0.3 0.2 1.3.0 0.7 1.7.6 LOCAL 1.2 1.7.6 Для использования модуля из состава PEAR в начало скрипта достаточно поместить оператор require. Например, для подключения модуля DB используется следующая команда: require 'DB.php'; Вместо этого можно было бы использовать оператор include, но их семантика несколько различна. Если файл, который требуется использовать, не найден, то оператор require вызовет критическую ошибку, и выполнение скрипта будет прекращено. Оператор include а аналогичном случае только сформирует предупреждение. В следующем разделе будет описано практическое использование модуля DB. Отображение данных при помощи DB В этом разделе приведен пример использования модуля DB для отображения содержимого таблицы в базе данных MySQL. Для начала следует подключить модуль к скрипту при помощи оператора require: require 'DB.php'; Для подключения к базе данных используется метод DB: : connect (как показано в гл. 7, «::» используется для указания на класс, к которому принадлежит метод). Его полный синтаксис приведен ниже: DB::connect!'dbname://username:password@server/databasename);
272 Глава 8. Базы данных" При этом dbname задает тип используемого сервера баз данных, username — регистрационное имя пользователя, password — его пароль, server — имя узла сервера (localhost для локальной установки), и, наконец, databasename — имя базы данных. Например, для подключения к локальной базе MySQL с именем db используется следующий вызов: $db=DB::connect('mysql://user:password@localhost/db); После успешного установления соединения можно использовать метод query для выполнения произвольных запросов к серверу. Например, для чтения всех записей из таблицы fruit используется следующий фрагмент кода: $query = "SELECT * FROM fruit"; $result = $db->query ($query); Пример 8.8 демонстрирует отображение данных при помощи средств пакета DB. Для доступа к отдельным строкам таблицы используется метод f etchRow, который возвращает массив, проиндексированным именами полей из таблицы (такой режим работы задается параметром DB № 1CHMODE ASSOC1). Остальной код аналогичен примеру 8.4, приведенному выше. Результат выполнения примера показан на рис. 8.8. Пример 8.8. ОтображениеданныхприпомощиDB, phpdb.php |5,?л#.-*«0^.Ytv.ftv^.A>-*V4■*. ■??>■—JrCtf'.-J.^ ГГ" 1 ""-- ГГТ •Т1ПТ~Т"ПЯТ|ГИ"МГГ1"ШГ—ТМПЧГТГШТМтТППТИТ"! Г<1У11)Х<И1»1М1.1ГцГ||1|ри»1Р«ИТП¥ЛШ[Г"~ IIIIHII HUT <HTML> <HEAD> <TITLE> Отображение данных при помощи DB </ТТТЬЕ> </HEAD> <BODY> <CENTER> <Н1>0тображение данных при помощи DB </Н1> <?php require 'DB.php ; $db = DB::connect ('mysql://root:@localhost/db'); $query = "SELECT * FROM fruit"; $result = $db->query ($query); echo "<TABLE BORDER='1'>"; echo "<TR>"; echo "<ТН>Наименование</ТНхТН>Количество</ТН>" ; echo "</TR>"; while ($row = $result->fetchRow (DB_FETCHMODE_ASSOC)) ЭготпараметрможетприниматьтакжезначениеОВ FETCHMODE ORDERED,прикотороммассив будет пронумерован, начиная с 0, но этот режим гораздо менее удобен, так как при любых модификациях запроса требуется аккуратно отслеживать корректность числовых индексов. — Прим. ред.
Добавление данных при помощи DB 273 ( echo "<TR>"; echo "<TD>" , $row ['name'], "</TDxTD>", $row ['number'], "</TD>"; echo "</TR>"; } echo "</TABLE>"; ■ </CENTER> </B0DY> </HTML> г*/*-**** * rC ■ ЛЛМТ *r*S. №'/0MI tVi Л**0'. Wt* *V ^/^ OrtBui^luV / -YV1 ЛчУ -.■*,*?* i-i* W09S-. V>' .Ъ !л L-;- Г/ г ЛСЛ n>V^\ -.i*W-^-'-->S* NY"-" it~S"« фэйп .Правка Вид избранное Сервис Справка ffvf*1:.;. !■ * hHp ://localhost/php/05/phpdb.php :-Избранное $&' v .;;tf . # ' oy Q Переход Спь:™ Отображение данных при помощи DB Наименование Количество; груши 431 тшрсики ;961 Рис. 8.8. Отображение данных при помощи DB Добавление данных при помощи DB Добавлять данные при помощи DB столь же легко, как и отображать их. Для этого следует всего лишь составить соответствующий SQL-запрос и исполнить его при помощи метода query: Squery = "INSERT INTO fruit (name, number) VALUES ('персики', '631')"; Sresult = Sdb->query (Squery);
274 ^ __ o_^_ Глава 8. Базы данных После добавления новой строки к таблице имеет смысл посмотреть на получившийся результат. Пример 8.9 отображает всю таблицу fruit после добавления данных. За исключением SQL-запроса, остальная часть кода аналогична предыдущему примеру. Результат выполнения примера представлен на рис. 8.9. Пример 8.9. Добавление данныхпри помощи DB, phpdbinsert.php <HTML> <HEAD> <TITLE> Добавление данных при помощи DB </TITLE> </HEAD> <BODY> <CENTER> <Н1>Добавление данных при помощи DB</H1> <?php require 'DB.php ; $db = DB::connect ('mysql://user:password@localhost/db'); $query = "INSERT INTO fruit (name, number) VALUES('абрикосы' , ' 631') " ; $result = $db->query ($query); $query = "SELECT * FROM fruit"; $result = $db->query ($query); echo "<TABLE BORDER= ' 1 ' >" ; echo "<TR>"; echo "<ТН>Наименование</ТНхТН>Количество</ТН>" ; echo "</TR>"; while ($row = $result->fetchRow (DB_FETCHMODE_ASSOC)) { echo "<TR>"; echo "<TD>" , $row ['name'], "</TDxTD>" , $row ['number'], "</TD>"; echo "</TR>"; } echo "</TABLE>"; ?> </CENTER> </BODY> </HTML>
Изменение данных при помощи DB 275 !Г£Т«1 файп Правка Вид Мгбрэнное Сереис Справка 1J* 1 ^ шУ" '■-.=, -.'1-- Х- 'Поис" "V,.'/избранное ^yi Mf f.*:http //localhosf/php/08/phpdbrnsert.php J Переход Добавление данных при помощи DB ^Наименование ; груши лерсики !абрикосы Количество 431 961 1631 Рис. 8.9. Добавление данных при помощи DB Изменение данных при помощи DB Изменение данных тоже не составит особого труда. SQL-запрос UPDATE, выполненный при помощи все того же метода query, сделает все необходимые действия: Squery = "UPDATE fruit SET number = 531 WHERE name = 'абрикосы'"; Sresult = $db->query (Squery); Для того чтобы увидеть результат выполнения запроса, используется такой же код, как и в предыдущем случае. В примере 8.10 отображается таблица fruit после изменения строки данных. Результат выполнения примера представлен на рис. 8.10. Пример8.10. Изменение данных при помощи DB, phpdbupdate.php <HTML> <HEAD> <TITLE> Изменение данных при помощи DB </TITLE> </HEAD> <BODY> <CENTER>
276 Глава 8. Базы данных <Н1>Изменение данных при помощи DB</Hl> <?php require 'DB.php'; абрикосы' $db = DB::connect ('mysql://user:password@localhost/db') $query = "UPDATE fruit SET number = 531 WHERE name = $result = $db->query ($query); $query = "SELECT * FROM fruit"; $result = $db->query ($query); echo " <TABLE BORDER='1'>"; echo echo "<TR>"; echo "<ТН>Наименование</ТНхТН>Количество</ТН>" ; echo "</TR>"; while ($row = $result->fetchRow (DB_FETCHMODE_ASSOC) ) { echo "<TR>"; echo "<TD>", $row ['name'], "</TDxTD>", $row ['number'], "</TD>"; echo "</TR>"; } echo "</TABLE>"; DB::close ($db); ?> </CENTER> </BODY> </HTML> '-■ s-n: т» ■ vwv rt --; L-v, *,v> ■.' *cw*'4H4>tf7 • oiv. la/ «aw < 'ftf •"*№>v. v&~-:j5*nev£ < л*м »wm."«" файл £1равка Вид избранное Сервис .Справка ■"■ ..;:-■ ■ " :.- ■■ '.'У-* -.0} ■■■$■ f- ' Поиск "*_J,> Избранное "jp f ; "гд \Щ ■\-'е:-.:. i."J http://localhost/php/OS/phpdbupdate.php Щ Переход '. Ссылки Изменение данных при помощи DB Наименование Количество ;груши '431 персики ;961 ; абрикосы 2М j Рис. 8.10. Изменение данных при помощи DB
Итоги 277 Предыдущие примеры были разработаны в надежде на то, что при выполнении операций с базой данных не возникает никаких ошибок. В реальности это далеко не так, и в модуль DB включен метод DB: : isError, который предназначен для обработки ошибок. Результат, возвращенный любым методом DB, может быть передан на вход методу DB: :isError, и если он вернул значение TRUE, это свидетельствует о возникновении ошибки в процессе выполнения предыдущего запроса. В таком случае можно обратиться к методу getMessage, чтобы получить развернутое текстовое описание ошибочной ситуации. Ниже приведен пример обработки ошибки при соединении с базой данных: $db = DB: :connect ( 'mysql://user:wrongpassword@localhost/db') ; If (DB::isError (Sdb)) { die($db->getMessage ()); } При помощи различных запросов к базе данных можно разрабатывать произвольные приложения, а при использовании модуля DB они еще и будут переносимыми между различными типами серверов баз данных. При смене типа сервера потребуется только соответствующим образом изменить строку, передаваемую методу DB::connect. Итоги В этой главе описаны основы работы с базами данных и те возможности, которые РНР предлагает для взаимодействия с различными типами серверов. Хранение данных в базах обеспечивает богатые возможности по их обработке. Ниже перечислены краткие итоги главы: • Для соединения с сервером базы данных MySQL используется функция mysqlconnect, а для выбора базы данных — функция mysqlselectdb. • Создание базы данных осуществляется при помощи SQL-запроса CREATE DATABASE. • Создание таблицы в выбранной базе данных выполняется при помощи SQL-запроса CREATE TABLE. Структура создаваемой таблицы описывается в запросе. • Добавление данных в таблицу осуществляется при помощи SQL-запроса INSERT. В MySQL запросы выполняются при помощи функции mysqlquery. • Выборка данных из таблицы осуществляется при помощи SQL-запроса SELECT. Для получения доступа данных из РНР может использоваться функция mysqlf etcharray. • Изменение данных осуществляется при помощи SQL-запроса UPDATE • Удаление данных их таблицы осуществляется при помощи SQL-запроса DELETE. Для создания переносимых приложений, независимых от типа сервера базы данных, используется объектно-ориентированный модуль DB.
Cookie, сеансы, FTP, e-mail В этой главе описываются весьма мощные средства программирования web-приложений: cookie1, FTP (File Transfer Protocol — протокол передачи файлов), электронная почта, работа с сеансами и т.п. начало главы посвящено работы с cookie — текстовыми строками, которые могут быть сохранены на компьютере клиента. Использование cookie позволяет отслеживать деятельность пользователя, а также передавать данные между скриптами. Далее рассматривается FTP — универсальное средство передачи файлов через Интернет. В РНР имеются все возможности для установления соединения с удаленными узлами, просмотра каталогов, загрузки и выгрузки файлов. Электронная почта — удобное и быстрое средство связи, и в РНР имеется возможность отправлять электронные письма, что может быть весьма полезным, например, при разработке Интернет-магазина, электронной газеты, подтверждения регистрации пользователя и т.п. В конце главы рассматривается работа с сеансами. В обычном режиме при запуске скрипта значения переменных являются неопределенными. При помощи cookie можно передавать данные между различными скриптами, но использование сеансов значительно облегчает этот процесс. Наиболее яркий пример применения — Интернет-магазин, в котором при перемещении между различными его разделами должно сохраняться содержимое корзины покупателя. Установка cookie Cookie — текстовые строки, которые могут быть сохранены на компьютере клиента и затем передаются web-серверу при каждом обращении к нему. Таким образом можно организовать передачу данных между различными скриптами, Дословный перевод — «печенье» — ничего не говорит о существе понятия, поэтому в профессиональной среде принято использование английского слова. — Прим. ред.
280 Глава 9. Cookie, сеансы, FTP, e-mail не используя форм или передачу через URL. Для установки значения cookie используется функция setcookie, которая имеет следующий синтаксис: bool setcookie (string name [, string value [, int expire [, string path [, string domain [, bool securej]]]]) Функция описывает cookie, который должен быть сохранен на компьютере клиента. Ниже приведено описание параметров этой функции: • пате. Наименование cookie. • value. Значение cookie. Так как оно сохраняется на компьютере клиента, не рекомендуется использовать cookie для хранения конфиденциальной информации. • expire. Срок действия cookie. Если задан, то cookie удаляется после того, как срок его действия истек. Если не задан, то cookie удаляется после закрытия окна браузера. Срок действия задается в Unix-стиле времени (количество секунд, прошедших с 1 января 1970 года). Для формирования срока истечения можно прибавить требуемое количество секунд к результату, возвращаемому функцией time (текущее время), или использовать функцию mktime для формирования абсолютного времени. • path. Путь на сервере, в рамках которого cookie будет доступен. Для того чтобы cookie был доступен в пределах всего домена, следует указать строку '/' • По умолчанию используется текущий каталог скрипта, в котором происходит установка значения cookie. • domain. Домен, для которого доступен cookie. • secure. Признак того, что cookie следует использовать только при безопасном соединении по протоколу HTTPS. По умолчанию cookie доступен для соединений как по HTTPS, так и по HTTP. Следует иметь в виду, что cookie являются частью заголовка HTTP-запроса, который отправляется браузеру, поэтому их значения должны быть установлены до начала формирования HTML-кода. Это означает, что вызов setcookie должен быть расположен до любых HTML-тегов и до любого оператора echo. Если не соблюдать это правило, то вызов setcookie вернет значение FALSE, что означает ошибку при формировании cookie. При успешном формировании cookie функция возвращает значение TRUE, но это не гарантирует того, что cookie будет принят клиентом. Браузер может быть настроен так, что будет игнорировать все или определенные cookie, и на стороне сервера нет способа узнать это заранее. Пример 9.1 иллюстрирует установку значения cookie. В нем создается cookie с именем message и текстом «Привет». Пример 9.1. Установка значения cookie, phpsetcookie.php <?php setcookie("message" , "Привет ") ; ?> <HTML> <HEAD> <TITLE> Установка cookie </TITLE>
Установка cookie 281 </HEAD> <BODY> <CENTER> <Н1>Установка cookie</Hl> Cookie установлен! Для просмотра следует перейти по ссылке <А HREF="phpgetcookie.php">phpgetcookie.php</A>. </CENTER> <BODY> </HTML> Соответствующая страница представлена на рис. 9.1. В момент просмотра страницы браузером cookie уже установлен. OSIffi файл Правка Дид Избранное Сервис С_правка Адресу \^Uhttp://localhost/php/09/phpsetcookJe. php ?~' №6рмюе -0, ; t:-fy ,-Jj • : fc-j Переход Установка coolde Cookie установлен! Для просмотра следует перейти по ссылке php yet cookie php. Рис. 9.1. Установка значения cookie Cookie установлен, но как получить к нему доступ? Если пользователь перейдет по указанной ссылке, для этой цели будет исполнен скрипт phpgetcookie.php, который рассматривается в следующем разделе.
282 Глава 9. Cookie, сеансы, FTP, e-mail Чтение cookie Сразу после того, как значение cookie установлено, оно не будет доступно скрипту до тех пор, пока страница не будет перезагружена. Это происходит потому, что cookie хранятся на компьютере пользователя и отправляются на web-сервер браузером при запросе очередной страницы. Кроме того, cookie отправляются только в том случае, если домен cookie совпадает с доменом запрошенного у сервера документа. Для получения доступа к cookie используется суперглобальный массив SCOOK1E. В качестве индекса массива используется имя cookie, использованное ранее. Массив заполняется автоматически при загрузке скрипта аналогично массивам $_GET, $_POST и SREQUEST (см. гл. 5). Замечание фр Массив $_С00К1Е введен, начиная с PHP 4.I.O. До этой версии использовался гло- / бальный массив $HTTP_COOKIE_VARS , который внутри функций требует обязательного объявления при помощи оператора global. Начиная с версии РНР 6.0, этот массив более не поддерживается. Перед использованием cookie имеет смысл удостовериться в том, что его значение установлено. Для этой цели идеально подходит функция isset. В примере 9.2 продемонстрирована такая проверка, и в случае наличия cookie с именем message его значение будет отображено, как показано на рис. 9.2. Пример9.2.Чтениезначениясоок1е,рЬрде1соок1е.рЬр .'k>vV,\".'I^.'.:<,;'.v:-, ет .-•>»:><!■ л>Л'т-г^>-L\^-^^ivii.^w.»iy*^T.:^/>:£w^v/к--^^ <HTML> <HEAD> <TITLE> Чтение значения cookie </TTTLE> </HEAD> <BODY> <CENTER> <Н1>Чтение значения cookie</Hl> Cookie содержит значение: <?php if (isset ($_COOKIE ['message'])) { echo 'Cookie содержит значение: ' . $_COOKIE ['message' ] ; } else { echo 'Cookie не установлен' ; } ?> </CENTER;. <BODY> </HTML>
Срок действия cookie файл Правка ^ид Избранное Сервис Справка 0НЮМ • ^ ■ Й [^ €Ь. ' Р™ *$?"**■««» 0 ! % $ ' .; Ц [ О Переход ; Ссылки Чтение значения cookie Cookie содержит значение: Привет Рис. 9.2. Чтение значения cookie Cookie могут быть также организованы в массивы, если использовать в их именах квадратные скобки. Например, можно установить три cookie следующим образом: setcookie ("cookie[one]" , "Сегодня"); setcookie ("cookie[two] ", "жизнь"); setcookie ("cookie[three] ", "прекрасна!") ; В результате будет сформирован массив SCOOKIE ['cookie'] из трех элементов, который может быть отображен, например, при помощи следующего фрагмента кода: if (isset ($ COOKIE ['cookie'])) { foreach ($_COOKIE'['cookie'] as $data) { echo "$data <BR>"; Срок действия cookie Помимо простой установки значении cookie, функция setcookie может установить и срок его действия. Срок действия задает временной интервал, в течение которого cookie будет сохраняться на компьютере пользователя. Если срок действия не задан, то cookie будет удален после завершения сеанса работы (то есть после закрытия текущего окна браузера и всех окон, открытых из него). Срок действия определяется третьим аргументом функции setcookie:
284 Глава 9. Cookie, сеансы, FTP, e-mail bool setcookie (string name [, string value [, int expire [, string path [, string domain [, bool secure]]]]]) Параметр expire задает время, когда cookie должен быть удален с компьютера клиента. Время задается в стиле Unix и представляет собой количество секунд, прошедших с 1 января 1070 года (эта дата традиционно считается началом эпохи Unix). Для формирования значения expire можно воспользоваться функцией time, которая возвращает текущее время в стиле Unix. Например, если cookie должен быть удален через час после его установки, параметр expire может быть задан как t ime () + 3 600: <?php setcookie("mycookie", $value, time() + 3 60 0); ?> В примере 9.3 создается cookie со сроком действия 5 секунд для демонстрации того, что значение cookie будет удалено, если нажать на ссылку спустя это время. Пример 9.3. Установка срока действия cookie, phpsetconfiguredcookie.php . №>>№ *'.?*»:<.'»iinvov«»-*<лмяйсч«то*уч.'.-;: т'чу" "г у~|гит1 'fi т*~ Tir" -1—г it in rr'T'iVHrnr-irrrr'iTViITT]"—1-f^rr n,-^~i "-тгтинпггтттгш' пчмпг' <?php setcookie("message", "Привет", time ()+5); ?> <HTML> <HEAD> <TITLE> Срок действия cookie </TTTLE> </HEAD> <BODY> <CENTER> <Н1>Срок действия cookie</Hl> Срок действия cookie установлен в 5 секунд. Поторопитесь перейти по ссылке <А HREF="phpgetcookie.php">phpgetcookie.php</A>! </CENTER> <BODY> </HTML> Внешний вид этой страницы приведен на рис. 9.З. Если нажать на ссылку до истечения 5 секунд, будет отображено значение cookie, как на рис. 9.2. Если же перейти по ссылке после истечения срока действия cookie, то будет выведено сообщение о том, что значение cookie не определено (см. рис. 9.4). В этом примере срок действия cookie был очень небольшой. В реальной практике срок действия устанавливается достаточно протяженным, чтобы cookie сохранился и после завершения сеанса работы пользователя. Если же срок действия не установлен, то время жизни cookie ограничено только текущим сеансом.
Срок действия cookie £айл Правка Вид Избранное Сервис ^правка нк _ /\ in н л н . /)по (Г-« • 0-Ш1С1 ;/,no-/s**"~ e i a Адрес,-, 1 jj] httpy/localhost/phpASI/phpsetconfiguredcookiephp ]_fj Переход Срок действия cookie Срок действия cookie установлен в 5 секунд. Поторопитесь перейти по ссьшке phosetcookie.plip! Рис. 9.3. Установка cookie со сроком действия файл Правка Вид .Избранное Сервис "правка & ■ [iT $ f, ■■>■:■■- ■ :",';;Иэбранюе ^р} v ^3 Переход Чтение значения cookie Cookie не установлен Рис. 9.4. Срок действия cookie истек
286 Глава?- Cookie, сеансы, FTP, e-mail Удаление cookie Иногда возникает необходимость удалить установленный ранее cookie. Для этого следует вызвать функцию setcookiec теми же параметрами, что и при установке cookie, но передать в качестве аргумента value пустую строку "". Следует обратить особое внимание на то, что все остальные аргументы, заданные при установке cookie, должны обязательно присутствовать с теми же значениями, иначе требуемый результат не будет достигнут. Ниже приведен пример удаления cookie: <?php setcookie ("message", ""); ?> Так как cookie удаляется браузером, а разные браузеры могут обрабатывать cookie по-разному, то для гарантированного удаления cookie рекомендуется также задавать истекший срок действия cookie: <?php Setcookie ("message", "", time () - 3600); ?> Ниже приведен пример удаления cookie с перенаправлением пользователя на скрипт phphgetcookie.php. <?php setcookie("message", "", timed - 3 600); ?> <HTML> <HEAD> <TITLE> Удаление cookie </TITLE> </HEAD> <BODY> <CENTER> <H1> Удаление cookie</Hl> Cookie удален. Перейдите по ссылке <А HREF="phpgetcookie.php">phpgetcookie.php</A>. </CENTER> <BODY> </HTML> После перехода по гиперссылке будет выведено сообщение об отсутствии cookie (см. рис. 9.4). Использование FTP Протокол FTP предназначен для передачи файлов через Интернет, и в РНР встроена полная поддержка этого протокола. Если используется Unix-версия РНР, то для использования функций работы с FTP следует добавить опцию -enable-ftp при установке пакета. В версии для Windows поддержка FTP является встроенной.
Использование FTP " 287 Для того чтобы начать работы с FTP, необходимо установить соединение с FTP-сервером, что осуществляется при помощи функции ftpconnect: ftpconnect (string host [, int port [, int timeout]]) Эта функция устанавливает соединение с заданным FTP-сервером (строка host задает доменное имя сервера, без префиксов «ftp://» и без завершающих слэшей, например ftp. relcom. ru). Необязательный параметррогС задает альтернативный TCP-порт для подключения (если значение не задано или равно нулю, используется стандартный порт 21). Третий необязательный параметр timeout задает время ожидания завершения обмена данными по сети (по умолчанию оно равно 90 с). При успешном соединении функция возвращает дескриптор FTP-соединения, при неудаче — значение FALSE. После соединения при помощи ftpconnect следует произвести аутентификацию при помощи функции ftplogin: ftplogin (resource ftp stream, string username, string password) Функция пытается осуществить вход на сервер, используя заданное имя пользователя и пароль, и возвращает TRUE при успехе и FALSE в случае ошибки. Замечание Щ ,, Традиционно публичные h I Н-серверы допускают анонимный входе именем пользова- / теля ftp или anonymous. В качестве пароля указывается адрес e-mail пользователя. IW"Ji»J*P»JHl Ниже приведен типичный фрагмент кода для начала сеанса работы по FTP1: <?php $connect = ftp_connect ("ftp.ispname.com"); $result = ftp_login ($connect, $username, $password) ; Этот фрагмент будет часто использоваться в следующих разделах главы. Наряду с ftpconnect и ftplogin, в РНР для работы с FTP имеется большое количество функций, наиболее употребительные из которых приведены в списке ниже. ftpalloc. Выделение дискового пространства для загрузки файла. ftpedup. Переход к вышестоящему каталогу. ftpchdir. Переход к заданному каталогу на FTP-сервере. ftpchmod. Назначение прав доступа к файлу на FTP-сервере. ftpclose. Завершение FTP-соединения. ftpconnect. Установка FTP-соединения. ftpdelete. Удаление файла на FTP-сервере. ftpexec. Запрос выполнения программы на FTP-соединения. ftpfget. Прием файлас FTP-сервера и сохранение его в открытом файле. ftpfput. Передача открытого файла на FTP-сервер ftpgetoption. Определение текущих параметров FTP-соединения. ftpget. Прием файлас FTP-сервера. ftplogin. Аутентификация пользователя на FTP-сервере. Здесь и далее используется вымышленное имя FTP-сервера ft p. ispname. com. — Прим.ред.
288 Глава 9. Cookie, сеансы, FTP, e-mail ftp mdtm. Определение времени последнего изменения файла. ftp mkdir. Создание каталога. ftp nb continue. Продолжение приема/передачи файла. ftp nb fget. Асинхронный1 прием файл с FTP-сервера и сохранение его в открытом файле. ftp nb fput. Асинхронная передача открытого файла на FTP-сервер. ftp nb get. Асинхронный прием файла с FTP-сервера. ftp nb put. Асинхронная передача файла на FTP-сервер. ftpnlist. Получение списка файлов заданного каталога на FTP-сервере. ftp put. Передача файла на FTP-сервер ftp_pwd. Текущий каталог ftp quit. Завершение FTP-соединения. ftp raw. Отправка произвольной команды на FTP-сервер. ftp rawl i st. Получение детального списка файлов заданного каталога на FTP-сервере. ftp rename. Переименование файла на FTP-сервере. ftp rmdir. Удаление каталога на FTP-сервере. ftp set option. Установка параметров FTP-соединения. ftp site . Отправка команды SITE на FTP-сервер. ftp size. Определение размера заданного файла, ftp ssl connect. Установление безопасного соединения SSL-FTP. ftp systype. Определение системного идентификатора FTP-сервера. Многие из этих функций используются в следующих разделах главы. Список файлов каталога Перед тем, как осуществлять операции по обмену файлами с FTP-сервером, имеет смысл просмотреть его содержимое. Функция ftpnlist предназначена для получения списка файлов заданного каталога на сервере: array ftp nlist (resource ftp stream, string directory) Эта функция возвращает массив имен файлов каталога directory или значение FALSE при какой-либо ошибке. Прежде чем обращаться к этой функции, следует установить соединение и выполнить аутентификацию на FTP-сервере, что показано в следующем фрагменте кода: <?php $connect = ftp_connect ("ftp.ispname.com"); $result = ftp_login ($connect, "username", "password"); $a = ftp_nlist ($connect, "directory"); Асинхронный режим обмена с FTP-сервером позволяет продолжить выполнение программы, в то время как данные пересылаются по FTP. — Прим. ред.
Загрузка файла с FTP-сервера 289 В примере 9.4 выполняется отображение полученного списка файлов заданного каталога. В случае ошибки при получении списка файлов выводится соответствующее сообщение. Пример 9.4. Отображение списка файлов каталога, phpftp.php MUVOPtt ищи**? 44>»LF4ti~*.lN>4 ■»c: ■': <HTML> <HEAD> <TITLE> Список файлов каталога </TITLE> </HEAD> <BODY> <CENTER> <Н1>Список файлов каталога</Н1> <?php $connect = ftp_connect ("ftp.ispname.com"); $result = ftp_login ($connect, "username", "password" ) ; $a = ftp_nlist ($connect, "directory"); if (is_array ($a)) { echo "Список файлов каталога: : <BRxBR>" ; foreach ($a as $value) { echo Svalue, "<BR>"; ) ) else { echo "Ошибка при получении списка файлов"; } ?> </CENTER> <BODY> </HTML> Результат выполнения примера приведен на рис. 9.5. Загрузка файла с FTP-сервера Одной из наиболее часто употребительных операций с БТР является загрузка файла с сервера. Перед загрузкой следует перейти в каталог, где расположен нужный файл. Для этого предназначена функция ftpchdir: ftpchdir (resource ftp stream, string directory) После вызова этой функции каталог directory становится текущим. Функция возвращает TRUE при успехе или FALSE в случае какой-либо ошибки. 10 РНР в примерах
290 Глава 9. Cookie, сеансы, FTP, e-mail файл Правка frit избранное Сцтис "правка фнал/Ю - О ' | | ~ ! "рГЬмск <П/ВфЕН-се -<В> \ ~ LH АДре" i ffi^ http://bcalhost/php/09/phpf1p.php Ш.Ш ПФЮМ г.ояп: Список файлов каталога Списокфайловкаталога: readme, txt reniote.txt index.html Рис. 9.5. Списокфайловкаталога Чтобы загрузить файл из какого-либо каталога, применяется функция ftpget: ftp_get (resource ftp_stream, string local_file, string remote_file, int mode [, int resumepos]) Функция осуществляет загрузку файла remote file (аргумент должен содержать только имя файла без каталога) с F IP-сервера и сохраняет его в локальный файл local^file (этот аргумент может включать в себя имя устройства и каталога). Параметр mode задает режим передачи файлов и может принимать два значения — FTPASCII и FIPBINARY. В случае FTPASCII при передаче файлов между разнородными системами (например, между Unix и Windows) производится автоматическое преобразование символов, задающих конец строки. Последний необязательный параметр resumepos задает позицию, начиная с которой следует осуществить передачу файла, и используется при докачке в случае обрыва соединения. Функция возвращает TRUE при успехе или FALSE в случае какой-либо ошибки. Пример 9.5 демонстрирует загрузку текстового файла с FTP-сервера. Пример 9.5. Загрузка текстового файла с сервера, phpftpget.php 1^ид»^М1М1«и<и^><^»*^м^|»'»1^и»>»^||*ДМ^|*М|И»(»М||м^«а>м»д|||>||||УШ<ш«и»ш1И|^||1ам1>1111И11 ii«ih*ww ирчнт hpi ит wmni mt шятышчичшшхлшы пиши ц» imiii щ <HTML> <HEAD> <TITLE> Получение файла через FTP </TITLE> </HEAD> <BODY>
-Загрузка „файла на RP-сервер 291 <CENTER> <Н1>Получение файла через FTP</H1> Производится загрузка файла.... <BR> <?php $connect = ftp_connect ("ftp.ispname.com"); if (! $connect) { echo "Невозможно установить соединение."; exit ; } $result = ftp_login ($connect, "username", "password"); if (! $result) { echo "Отказ в авторизации."; exit; } $result = ftp_get ($coimect, "local.txt ", "remote . txt" , FTP_ASCII) ; if ($result) { echo "Файл успешно загружен."; } else { echo "Ошибка при загрузке файла."; } ftp_close ($connect); ?> </CENTER> <BODY> </HTML> Результатвыполненияпримераприведеннарис. 9.6. Следует обратить внимание нато, что закачанный файл будетразмещен в томже каталоге, где расположен и скрипт. Для того чтобы поместить файл в другой каталог, следует указать в качестве аргумента local^file функции ftpget полный путь к нему. Загрузка файла на FTP-сервер В предыдущем разделе файл закачивался с сервера на локальный компьютер. Ниже рассмотрен обратный процесс — передача локального файла на FTP-сервер. Для этого используется функция ft p p ut: ftp_put (resource ftp_stream, string remote_file, string local_file, int mode [, int startpos])
292 Глава 9. Cookie, сеансы, FTP, e-mail Hcrosoft Internet Explorer файл [Травка 5ед Избранное Сервис Оправка 'ф'-„- 4,о Й 7Й "<5 Ргтах -/Л/кфме 4§$"- %. S v Адри.:; ТЙпН-р :/]localhost/php/09/phpftpget.php & • JvV! Q Переход Ссылки Получение файла через FTP Производится загрузка файла.... Файл успешно загружен. Рис. 9.6. Загрузка файла с FTP-сервера Аргументы функции имеет тот же смысл, что и в предыдущем случае, только файлы указаны в другом порядке. Файл 1 ocal^fi /e (это аргумент может включать в себя полный или относительный путь к файлу) передается на FTP-сервер и сохраняется там в текущем каталоге под именем remoteJile. Остальные аргументы — mode и startpos — аналогичны функции ftpget, описанной в предыдущем разделе. Пример 9.6 демонстрирует использование функции ftpput для передачи текстового файла на FTP-сервер. Пример 9.6. Передача текстового файла на сервер, phpftpput.php <HTML> <HEAD> <TITLE> Передача файла на FTP-сервер </TITLE> </HEAD> <BODY> <CENTER> <Н1>Передача файла на FTP-cepBep</Hl> Загрузка файла. . . <BR> <?php
Загрузка файла наFTP-сервер „_„^. _^ ^93 $connect = ftp_connect ("ftp.ispname.com"); if (! $connect) { echo "Невозможно установить соединение."; exit ; } $result = ftp_login ($connect, "username", "password" ) ; if (! $result) { echo "Отказ в авторизации."; exit ; } $result = ftp_put ($connect, "remote.txt", "local.txt", FTP_ASCII) ; if ($result) { echo "Файл успешно загружен."; } else { echo "Ошибка при загрузке файла."; } ftp_close ($connect); ?> </CENTER> <BODY> </HTML> Как видно из рис. 9.7, в результате выполнения примера файл успешно передан на FTP-сервер. файл Правка Вид избранное Сервис Справка j ОН,«д - 0 ■ @ HI ф рПоиск -fpmnmb Ф\%. Ш - Адрес;.i| |jhttp://localhost/php/09/phpftpput,php S*;j "Пере ход Си-, Передача файла на FTP-сервер Загрузка файла.... Файл успешно загружен- Рис. 9.7. Загрузка файла на FTP-сервер
294 Глава 9. Cookie, сеансы, FTP, e-mail Отправка e-mail При помощи РНР можно достаточно просто отправлять электронную почту. Для того чтобы подключить эту функциональность, необходимо отредактировать в конфигурационном файле php. ini следующую секцию: [mail function] ; For Win32 only. SMTP = localhost ; For Win32 only. sendmail_from = me@localhost.com ; For Unix only. You may supply arguments as well (default: " sendmail -1 - i " ) . ;sendmail_path = Для Windows следует вместо localhost указать адрес SMTP-сервера для отправки электронной почты, а в параметре sendmail _f rom — обратный адрес отправителя писем. Для Unix и Linux скорее всего дополнительная настройка не понадобится, но в случае проблем с отправкой почты следует присвоить параметру sendmailpath полный путь к команде sendmail, предварительно убрав с него знак комментария «;». Для отправки электронной почты используется функция mail, синтаксис которой приведен ниже: mail (string to, string subject, string message [, string additional_headers [,stringaddi tional_parameters]]) Эта функция отправляет письмо message с темой subj ect no адресу to. Кроме того, могут быть указаны дополнительные заголовки почтового сообщения, а также дополнительные параметры. Пример 9.7 содержит форму, в которой вводятся все данные, необходимые для формирования письма, а в примере 9.8 приведен скрипт-обработчик формы, который осуществляет собственно отправку корреспонденции. Пример 9.7. Форма для ввода e-mail, phpemail.html <HTML> <HEAD> <TITLE> Отправка e-mail </TITLE> </HEAD> <BODY> <CENTER> <Н1>0тправка e-mail</Hl> <FORM MEIHOD=POSr ACTION="phpemail.php"> Введите сообщение и нажмите OK:<BR> Кому: <INPUT TYPE="text" NAME="to1IxBR> Тема: <E4PUT TYPE="text" NAME="subject"xBR> <TEOARE\ ШУ1Е= "message" COLS=0" R0WS="x/TEXTAREA> <BR> <INPUT TYPE="SUBMIT" VALUE="OK"> </FORM>
Отправка e-mail 295 </CENTER> <BODY> </HTML> v*&w*M^^-^M*Mor^t&&ii/M'j*-'arrjtyqia'i,M*m*mtaiti На рис. 9.8 представлена форма, после заполнения которой производится отправка письма. В примере 9.8 для отправки e-mail используется функция mail, описанная выше. файл [Травка [}ид Избранное Сервис ^правка ..'Поиск " Избранное *Jfc ': /// Q Адрес;; ; ghttp://locaJho3t/php/09/phpemail.html т j Я Переход ; CtbWK Отправка e-mail Введите сообщениеинажмитеОК: Кому: [admJn®orioner. ru Тема: Шоброе утречко! '• Проверка функциониро функции iflail Рис. 9.8. Форма для ввода e-mail ПримерЭ. 8. Отправкае-таИ,рМретаН.рМр .VJ"*!" ■Ь^*зО^'-,-.'ч.1(в»>*Хгс^**^«,Ч*'*»Ч»^**^Л«'» <HTML> <HEAD> <TITLE> Отправка e-mail </TITLE> </HEAD> <B0DY> <CENTER> <Н1>0тправка e-mail</Hl> <?php
296 Глава 9. Cookie, сеансы, FTP, e-mail mail ($_REQUEST ['to'], $_REQUEST ['subject'], $_REQUEST ['message' ] ) ; ?> Письмо отправлено. <BR> </CENTER> <B0DY> </HTML> >. >J---Xf у^УлШ/л^м 4MOWJt>Vrf>VV»Vy>*n-,biW34rJ41»**>*1ЖН***Яа*!М*ЛС*ЛЩЫФПА^О> У<Ы**&^ E-mail с дополнительными заголовками При помощи функции mail можно отправить письмо, содержащее различные дополнительные заголовки, например се : (carbon copy — твердая копия) или bee : (blind carbon copy — слепая копия). Оба этих заголовка используются для перечисления дополнительных получателей письма. Отличие в том, что заголовок bee: не виден на стороне адресата, и список тех, кому отправлено письмо при помощи него, неизвестен получателям письма (в том числе и тем, кто перечислен в этом заголовке). Для задания дополнительных заголовков при вызове функции mail используется необязательный аргумент additional headers: mail (string to, string subject, string message [, string additional_headers [, string additional_parameters}]) Следует обратить внимание на то, что для разделения строк заголовка должны использоваться символы \г\п (хотя в Unix для обозначения конца строки традиционно используется только символ \п). Пример 9.9 демонстрирует расширенную форму для отправки письма и отличается от примера 9.7 тем, что в нем присутствуют поля для дополнительных заголовков. Пример 9.9. Формадля ввода e-mail с дополнительными заголовками, phpemailheaders.html tf.-VO-WfrJ^C^ICTУХ*.■■*»;■ > »Ш *ШЬУЯПВ9*9У<4С*Я&*Ы V10»ЩС—HU W*lM»»C1«Hi <HTML> <HEAD> <TITLE> Отправка e-mail по нескольким адресам </TITLE> </HEAD> <BODY> <CENTER> <Н1>0тправка e-mail по нескольким адресам </Н1> <FORM METHOD=POST ACTION=" phpemailheaders.php"> Введите сообщение и нажмите OK:<BR> Кому: <INPUT TYPE="text" NAME="to"><BR> Cc: <INPUT TYPE="text" NAME="CG"xBR> Bee: <INPUT TYPE="text" NAME="bcc"xBR> Тема: <INPUT TYPE="text" NAME="subject"><BR> <TEXTAREANAME= "message" COLS=0" R0WS=" 5 "x/TEXTAREA> <BR> <INPUT TYPE="SUBMIT" VALUE="OK">
E-mail с дополнительными заголовками 297 </F0RM> </CENTER> <B0DY> </HTML> ■:*/да: frsi v>w v-/-^- ■ .т Внешний вид этой формы приведен на рис. 9.9. файл Правка Вид Избранное Сервис Справка ф** 0 a 1 ■& i..' Поиск -'■_: V'Избранное ^3^ . ^ ^ - Адрес:, :ГЩ http://localhost/php/09/phpernajlheaders.html V'. "Переход '.i"m.T--i Отправка e-mail по нескольким адресам Введите сообщение и нажмите ОК: Кому: :adminrbnbner ru Сс : riimkaj<|tpt-^u ВСС: jracehsfiMlsnetru j Тема; ;Доброе утречю! !Проверка передачи e-irrrtil несюльгим адое|^1тан Рис. 9.9. Расширенная форма для ввода e-mail Пример 9.10 отличается от примера 9.8 тем, что при заполнении полей формы с с и be с формируется строка заголовка, которая передается как параметр функции mail. Для проверки наличия данных в поле используется функция isset. ПримерЭ. 10. Отправкае-таИнесколькимадресатам, phpemailheaders.php <HTML> <HEAD> <TITLE> Отправка e-mail по нескольким адресам </TITLE> </HEAD> <BODY>
298 Глава 9. Cookie, сеансы, FTP, e-mail <CENTER> <Н1>0тправка e-mail по нескольким адресам </Н1> <BR> <?php $headers = ""; if(isset ($_REQUEST ["cc"])) { $headers .= "cc:".$_REQUEST ["cc"] ."\r\n"; } if (isset ($_REQUEST ["bcc"])) { $headers .= "bcc:".$_REQUEST [ "bcc" ] . "\r\n" ; } mail ($_REQUEST [ 'to'] , $_REQUEST ['subject'], $_REQUEST ['message'], $headers) ; ?> Письмо отправлено. </CENTER> <BODY> </HTML> у\&лжв1М1и&^-*х>ю</#1р*,1ЪГ<*гж*1мыл1ег!&*'гхяа Е-таМсвложеннымифайлами При помощи РНР можно отправлять и письма с вложенными файлами, но для этого придется приложить чуть больше усилий. Допустим, требуется отправить файл image, jpg. Прежде всего следует определить MIME-тип файла, в данном случае это image/ jp eg (если отправляемый файл будет иметь другой тип, следует указать корректный MIME-тип.): $attachment = "image.jpg"; $attachment_MIME_type = "image/jpeg"; Далее следует прочитать файл и сохранить его содержимое в переменной: $handle = fopen ($attachment, " rb " ) ; $data = fread ($handle, filesize ($attachment)); fclose ($handle); Так как электронные письма передаются в семибитной кодировке, требуется преобразовать содержимое файла в кодировку base64 и указать в заголовке письма, что оно состоит из нескольких частей. Преобразование осуществляется при помощи функций chunksplit Hbase64_encode: $boundary = " Multipart_Boundary " ; $headers = "\nMIME-Version: 1.0\n" "Content-Type: multipart/mixed, • \n" . " boundary=\"" . $boundary . "\""; $data = chunk_split (base64_encode ($data)); Скрипт в примере 9.11 демонстрирует отправку письма с вложенным файлом. Он может использоваться в качестве обработчика формы из примера 9.9 вместо скрипта phpmailheaders.php из примера 9.10.
E-ma^cj3£ioxe^ " ^ ™_™„5?£ Пример 9.11. Отправка e-mail с вложенным файлом, phpemailattachment.php ""П " IT^-Щ'1'|-ЩГ"ТГГТГТТ|Тц-П ["I mr II |МГцШЛЛ-|^1л»и»П>рЦ|^ШТ1»|||]<|и1-|^1М—iH^ijU^^Hii—iHi^M^^^M^MJP^WWM^^^H^^^H^^^*^ <HTML> <HEAD> <T1TLE> Отправка e-mail с вложенным файлом </TITLE> </HEAD> <BODY> <CENTER> <Н1>0тправка e-mail с вложенным файлом</Н1> <?php $to = $_REQUEST [ ' to ' ] ; $subject = $_REQUEST ['subject']; $message = $_REQUEST ['message']; // При необходимости укажите другой файл и его тип $attachment = "image.jpg"; $attachment_MIME_type = "image/jpeg"; $handle = fopen ($attachment, " rb " ) ; $data = fread ($handle, filesize ($attachment)); fclose ($handle); $boundary = " Multipart_Boundary " ; $headers = "\nMIME-Version: 1.0\n". "Content-Type: multipart/mixed;\n". " boundary=\"".$boundary."\""; $data = chunk_split (base64_encode ($data)); $text = "—".$boundary."\n". "Content-Type:text/plain\nContent-Transfer-Encoding: 7bit\n\n". $message."\n\n—".$boundary."\n". "Content-Type: ".$attachment_MTME_type.";\n name=\"". $attachment."\"\nContent-Transfer-Encoding: base64\n\n". $data."\n\n—".$boundary."—\n"; $result = mail ($to, $subject, $text, $headers); if ($result) { echo "Письмо отправлено."; } else { echo "Ошибка при отправке письма."; } ?> </CENTER> <BODY> </HTML>
300 _ Г ^^*jCJZ£**& -_А е^сеан с ^FTP, e-mail На рис. 9.10 представлен результат отправки письма. Ш Отправка e-mail с вложенным файлом.- Microsoft Internet Explorer файл ■.-"-"Иа ijWi ! ! Правка Вид Избранное Сервис ад ■ :'.: \jf\ iiz] :^тт у Справка ..hoirac '-0?Избранное ^Gft \ iiikt ^ т i gj http://kxahc3syphp/39/ptipenTailaHachment .php *Ш\ Q Парюзд Отправка e-mail с вложенным файлом Письмо отправлено. http ://all -ebooks. Г . <:»ir*M com Рис. 9.10. Письмо успешно отправлено Сеансы Когда пользователь в рамках одного web-приложения работает с различными страницами, при каждой загрузке скрипта переменные очищаются. Это означает, что для передачи данных между страницами необходимо использовать специальные приемы, например, передачу через формы (метод POST), строку URL (метод GET) или использовать cookie, как показано выше. Но самым удобным способом является использование сеансов. Сеансы предназначены для сохранения данных определенного пользователя на сервере. Для каждого пользователя формируется уникальный идентификатор сеанса, который используется для автоматического восстановления данных клиента, вне зависимости от того, сколь много страниц и скриптов использует web-приложение. Для сохранения идентификатора сеанса обычно используется cookie, при недоступности этого варианта (например, если пользователь не принимает cookie), идентификатор сеанса может быть закодирован в строке URL или передан как скрытое поле формы. Для объявления начала сеанса используется функция startsession1. Данные сеанса содержатся в суперглобальном массиве $ SESSION. Например, необходимо сохранить значение выбранного пользователем цвета. Для этого может использоваться следующий фрагмент кода: Обычно работа с сеансами обеспечивается установкой cookie. Атак как установка значения cookie происходит в HTTP-заголовке, то вызывать функцию startsession следует до формирования какого-либо HTML-кода, иначе будет выведено предупреждающее сообщение вида: "Warning: session start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at test.php:13) in test.php on line 14". Следует обратить внимание на место вызова функции startsession в нижеприведенных примерах. — Прим.ред.
Сеансы 301 session_start (); $ SESSION ['color'] = "сини Замечание Щ - Суперглобальный массив $ SESSION появился, начиная с РНР 4.I.O. До этой вер - f сии использовался глобальный массив SHTTP SESSION VARS, который внутри функций требует обязательного объявления при помощи оператора global. Этот массив перестал поддерживаться, начиная с РНР 6.0. *,-■,+.■<■■. ю^с*-*у р&ыязжчтчпкягщщяншчижыу* ftwmovouvwtc* nv/icwotMutK^v л> <*■»*-** I с*л;wv ^.лэ».V-'! Где-нибудь в другом скрипте (или даже в том же самом) требуется прочитать значение цвета. Для этого используется следующий код: session_start (); $color = $_SESSION ['color' '; Таким способом данные могут легко передаваться между различными скриптами. РНР поддерживает работу с сеансами по умолчанию. Для ее отключения необходимо скомпилировать РНР с опцией —disable-session (только для Unix, для Windows отключить ее невозможно). Настройка работы с сеансами осуществляется при помощи секции [Session] конфигурационного файла php. ini. В табл. 9.1 приведены все параметры этой секции с кратким описанием. Таблица 9.1. Параметры настройки сеансов Параметр session. save_handler session.save_path session.use_cookies Значение по умолчанию files /temp 1 Описание Обработчик, используемый цпя сохранения данныхсеанса. Каталог, используемыйдпяхранення данных сеанса (в случае использова- ниястандартногообработчика). Использование cookies для хранения идентификатора сеанса. session.use_only_ cookies Использование только сооМевдляхранения идентификатора сеанса — передача идентификатора через URL запрещается. session.name PHPSESSID Наименование cookie для хранения идентификатора сеанса. session.auto—start Автоматически начинать сеанс при запуске любого скрипта. session.cookie_ lifetime Время жизни cookie в секундах. Значение 0 задает время жизни до закрытия окна браузера.
302 Глава 9. Cookie, сеансы, FTP, e-mail Параметр session, cookiejath session.cookie_domain Значение по умолчанию / l| II Описание Путь на сервере, на который распространяетсядействиесоою~есеанса. Домен, для которого действителен cookleceaHca. session.serialize_ handler php Обработчик, используемый для сериа- лизации данных. Кроме стандартного обработчика php имеется обработчик wddx (если в РНРвключена его поддержка]. session, gc probability I session, gc divisor 100 Отношение этих двух параметров задает вероятность, с которой при запуске очередного сеанса начнется процесс сборки мусора, т.е. удаление данных сеансов, время жизни которых истекло. session.gc_ maxlifetime 1440 Максимальное время жизни сеанса (интервала времени между последовательными обращениями клиента) в секундах. session.referer check Выполнять проверку поля HTTP-заголовка Referer. Если поле не будет содер- жатьзаданнойстроки, идентификатор сеансанебудетсчитатьсякорректным. session. cache_limiter Управление кэшированием страницы на стороне браузера при помощи соответствующего HTTP-заголовка. Возмож- ныезначения:посасг\е, private, public. session, cache expire 180 Время жизни страницы в кэше браузера в минутах. session.use trans sid Разрешение передачи идентификатора сеанса через URL. Использование этой функцииможетпривести ксерьезным проблемам с безопасностью. session.hash function Выбор используемой хэш-функции. Возможные значения: 0—MD5(\286nr), 1 — SHA-1 A60бит). session.hash_bits_per_ character Количество бит, кодируемое одним символом при преобразовании хэширован- ныхданныхв строку. Возможные значения: 4 (используются символы в диапазоне 0—9, a—f), 5 @-9, a-v), 6@-9, a-z,A-Z,«-»,«,»).
Сохранение данных сеансов 303 При настройке РНР для работы с сеансами следует обратить внимание на то, что данные всех сеансов сохраняются в виде индивидуальных файлов в каталог, заданном параметром session, savepath. При настройке РНР следует при необходимости создать каталог для хранения сеансовых данных и указать его в этом параметре. При каждой инициализации сеанса файл данных создается вне зависимости от того, были ли сохранены какие-либо данные или нет. Сохранение данных сеансов Для хранения данных сеансов используется массив SSESSION. Он является суперглобальным подобно $_GET, SPOST и $_REQUEST. Перед тем, как использовать массив SSESSION, следует произвести инициализацию сеанса при помощи функции startsession. Пример 9.12 демонстрирует сохранение данных в сеансе. Элементу массива SSESSION [ 'temperature'] присваивается значение температуры. Формируемая страница (см. рис. 9.11) содержит ссылку для перехода на следующую страницу, в которой данные будут прочитаны. ПримерЭ. 12. СохранениеflaHHbixceaHca,phpsession.php <?php session_start (); ?> <HTML> <HEAD> <TITLE> Сохранение данных сеанса </TITLE> </HEAD> <B0DY> <CENTER> <H:i> Сохранение данных сеанса </Н1> <?php $_SESSION ['temperature'] = 6.6"; echo "Температура: ".$_SESSION ['temperature']; ?> <BR> Значение температуры сохранится и после перехода по <а href = "phpsession2 . р1тр">ссылке</а>. </CENTER> <B0DY> </HTML>
304 Д Сохранение данных сеанса - Microsoft Internet Explorer файл Правка Цид избранное Сервис Справка Глава 9. Cookie, сеансы, FTP, e-mail О-''' ~>; >J L~l j:' P™** Is'«мимо. &]фШ* Адресу :" | http://localhost/php/09/phpsession.php ш Переход.... С*ыт*и Сохранение данных сеанса Температура: 36.6 Значениетемпературы сохранится и после перехода по ссылке. Рис. 9.11. Сохранение данныхсеанса В примере 9.13 демонстрируется чтение данных, сохраненных в предыдущем примере, а на рис. 9.12 приведен результат выполнения этого примера. Следует обратить внимание на функцию startsession, которая должна быть вызвана первой и в этом случае. ПримерЭ. 13. Чтение данныхсеанса, phpsession2.php ■ IЯ .<«1 ч-«А.ЛС«Д^Ь»:' п »:ч»*>ог^-ч»1**р*«в« . <?php session_start(); ?> <HTML> <HEAD> <TITLE> Чтение данных сенаса </TTTLE> </HEAD> <B0DY> <CENTER> <Hl> Чтение данных сеанса </Н1> <?php if (isset ($_SESSI0N ["temperature"])) { echo "Значение температуры составляет ['temperature' ] ; } ?> </CENTER> <B0DY> </HTML> .$_SESSI0N
Создание счетчика посещений 305 файл Правка Вид Избранное Сервис Справка *Af»c.J()j!) htirp://localriost/prip/09/phpsession2,prip j " Q Переход Ссылки Чтение данных сеанса Значение температуры составляет 36.6 Рис. 9.12. Чтение данных сеанса Создание счетчика посещений В этом разделе приведен пример создания счетчика посещений страниц при помощи сеансов. Пусть требуется отслеживать, сколько раз определенный пользователь посещал заданную страницу. Если для этой цели просто использовать переменную (например, $count, как показано в примере 9.14), то требуемый результат не будет достигнут, так как переменная будет создаваться заново при каждой загрузке страницы. В результате при попытке выполнения примера 9.14 будет выведено сообщение об ошибке, как на рис. 9.13. Пример 9.14. Первая попытка создания счетчика посещений, phpcounter.php /4>04*»vVW .-ЩНиЦт* т -М&сгжяйФЛШи м »^Xu.Tg^,»j v* >-ЛрЛМХ*С*> ЛтКЛМЛС >а, 4e>vV4***0tt4*j^i V3OT '■W<■.V.*SJ'Л00, --« КУ.*9Ч*»С4VIV ?«*ОТ«1, v ■&.- (: <HTML> <HEAD> <TITLE> Счетчик показов </ТТТЬЕ> </HEAD> <B0DY> <CENTER>
306 Глава9. Cookie, сеансы, FTP, e-mail <H1> Счетчик показов </Н1> Эта страница была показана <?php $count++; echo $count; ?> раз. </CENTER> <BODY> </HTML> файл Правка Вид Избранное Сервис "правка \ •■ЛММЭ Л"> ГОчгСМ VjtfЛЖЛТЛЧ^Х. • OfjMJb&4MAMy3MX.b&&i tatttfVCr/» J tfi*) \V Избранное -§"*] : d"^. ,ij » АдресL |:fjjj' МНр7Доса1Мо51-/р^р/04/рМрсоипГегО ,php ■.**§} В Переход ■ Oc^Jwr» Счетчик показов Эта страница была показана Notice: Undefined variable, count in c:YWORK\BINOMVKHira php\Result\09 \phpcounter0.php on line 14 1 раз. Рис. 9.13. Переменная Scount не определена Решением является использование элемента массива SSESSION, как показано на примере 9.15. Результат выполнения примера приведен на рис. 9.14.
Создание счетчика посещений 307 'Ш Счетчик показов - Microcoft Internet Explorer... файл [1равка Е»ИД Избранное Сервис Справка Л^1""'"' ' ^J ' [_2.0 П "$Л? ' J> ■ -•""• ^%_7Избранное xj? V :А:Т A * '"' 34 § http://localhosh/php/09A3hpcounter.php Счетчик показов Эта страница была показана 5 раз. -..£i@ui '.'""*',', Э Переход ■^■:ь.-1лкк http://all-ebooks.com Рис. 9.14. Счетчик посещений работает Пример 9.15. Корректный счетчик посещений, phpcounter.php <?php session_start() ; ?> <HTML> <HEAD> <TITLE> Счетчик показов </TITLE> </HEAD> <B0DY> <CENTER> <H1> Счетчик показов </Н1> Эта страница была показана <?php if (! isset ($_SESSI0N ['count']) { $_SESSI0N [ ' count' ] = 0;
308 Глава 9. Cookie, сеансы, FTP, e-mail else { $_SESSION [ ' count']++ ; } echo $_SESSION ['count']; ?> раз . </CENTER> <BODY> </HTML> Сеансы без cookie Для хранения идентификатора сеанса РНР обычно использует cookie. При помощи этого идентификатора определяется тот набор данных, который связан с текущим сеансом. Но пользователь по каким-либо причинам может отключить использование cookie. В этом случае РНР будет передавать идентификатор сеанса в строке URL. Для того чтобы включить такую возможность, в конфигурационном файле php.ini следует включить параметр session, usetranssid (кроме того, следует проверить значение параметра session. use_ onlycookies, который говорит о том, что для передачи идентификатора сеанса используются только cookie): session.use_trans_sid=l После этого строка URL будет выглядеть следующим образом: script.php?PHPSESSID=322fe03120041e6c5285480a4fbf1037 Параметр по умолчанию выключен, так как передача идентификатора сеанса через URL является серьезной брешью в безопасности системы. Что же делать, если пользователь не принимает cookie, а передача идентификатора сеанса через URL также отключена? В этом случае имеется возможность ручной передачи идентификатора сеанса. Для этого его следует сохранить в скрытом поле формы. Имя поля задается параметром session.name, по умолчанию это PHPSESSID. Образец такой передачи идентификатора сеанса приведен в примере 9.16. Пример 9.16. Передача идентификатора сеанса через скрытое поле формы, phpsessionnocookies.php <?php session start(); ?> <HTML> <HEAD> <TITLE> Передача идентификатора сеанса без cookies </TTTLE> </HEAD> <BODY>
Сеансы без cookie 309 <CENTER> <Н1>Передача идентификатора сеанса без cookies</Hl> <?php $_SESSION ['t'] = 6.6"; echo "Температура: ".$_SESSION ['temperature']; ?> <BR> Для чтения температуры на следующей странице нажмите ОК: <BR> <FORM ACTlON="phpsession2.php" METH0D="POST"> ' <INPUT TYPE="HIDDEN" NAME="PHPSESSID" VALUE=" <?php echo session_id ( ) ; ?> "> <INPUT TYPE='SUBMIT1 VALUE='OK'> </FORM> </CENTER> <B0DY> </HTML> WC^i^h^jUyntpl я»»с^>ДМ^. уЛ I.I "Jul nClllll'lV til 4f|. . .n4l»:W ЛИ^ими ДМ Щ.П ЛI ll '.111 if IIHT^C П lf¥iirHi'HMntjO..I|H»LHTJ H.p4i 1.1 X ЛН.-ОЩ О г* f iw* ЛАМ"! *ПЧВ»?Л*Й«»ЛО^И^» АЛлП чЧ :-«■.-. ^. Внешний вид страницы, формируемой примером 9.16, приведен нарис . 9 .15 . файл Правка @ид избранное Сервис Справка %5ЯЯ" m Ct ' Й" Ш €fe :;Tnatx "Избрвжое 4$§ )""%. Щ "дрес". !" http;//localhost/php/09/phpsessionnocookies.php ."< ^&J Переход Ca-:.h;i ■ Передача ид ентификатора сеанса без cookies Температура: 36.6 Для чтения температуры на следующей странице нажмите ОК: (ж) Рис. 9.15. Передача идентификатора сеанса без cookies
310 Глава 9. Cookie, сеансы, FTP, e-mail Для получения доступа к идентификатору сеанса не требуется никаких дополнительных действий — в качестве обработчика используется пример 9.13 в неизменном виде. На рис. 9.16 приведен образец успешной передачи идентификатора сеанса без cookies — как видно, данные сеанса переданы корректно. £айл Дравка £ид избранное Сервис "правка .*». ' < ■ ■ .-- ■■■. : ~" ''...! На-"as. - ■•'■■'■>) \«\ ■-.%.) ■ ■ :£ "..'Поиск "/г Избранное ">)] , ti [53 4j^ '■—■ i L.„, r ЭГ' Дли* ., : ji]hitp://localhosl:/pSp/09/phpse5sion2.php \'ф\ Q Переход ■ Соыпщ- Чтение данных сеанса Значение темггературы составляет 36.6 Рис. 9.16. Доступ к данным сеанса без cookies Удаление данных сеанса Помимо передачи данных между отдельными скриптами иногда возникает и необходимость удалить данные сеанса. Для этого может с успехом использоваться уже известная функция unset. К примеру, в сеансе было сохранено определенное значение температуры: <Н1>Удаление данных сеанса</Н1> <?php session_start ( ) ; $_SESSI0N ['temperature' ] = " 3 6 . 6 " ; echo "Температура: ".$_SESSI0N ['temperature']; <BR> Значение температуры сохранится и после перехода по <а href="phpsessionunset2.рЬр">ссылке</а>.
Удаление данных сеанса 311 Внешний вид страницы, содержащей этот фрагмент кода, приведен на рис. 9.17. айл .Правка §ид Избранное Сервис £пр; AqpeQ'; jjjj hittp://localhQsVtDtTp/09A3lT3sessionunsetphp Избранное •£■) '. •■■& ''ф--' Ч;| Н Перэвд а-ылк. Удаление данных сеанса Температура: 36.6 Значение температуры сохранится и после перехода по ссылке. Рис. 9.17. Демонстрация удаления данных сеанса Переход с этой страницы по ссылке ведет на скрипт, в котором происходит удаление элемента массива SSESSION, содержащего значение температуры: Удаление элемента "temperature"...<BR> <?php sessionstart (); unset ($_SESSION ["temperature"]); ?> Для продолжения перейдите по <а href="phpsessionunset3.pbp">ccbiiiKe</a>. Внешний вид страницы, содержащей этот код, приведен на рис. 9.18. Наконец, на последней странице производится анализ наличия температуры в данных сеанса: <н1> Удаление данных сеанса </Н1> <?php session_start (); if (isset ($_SESSION ["temperature"])) { echo "Значение температуры составляет ".$_SESSION ['temperature']; } else } echo "Значение температуры не определено";
312 Глава 9. Cookie, сеансы, FTP, e-mail I Удоле ние данны> 5>айл _Г1равка Вид избранное Сервис Справка £м»Ч"' L ;-^jJ3 http://localhost/php/09/phpsessionunset2.php Г. litfllfcl ,Ш EJ.Переход' ■■ ссылки Удаление данных сеанса Удаление элемента "temperature"... Для продолжения перейдите по ссылке. Рис. 9.18. Удаление элемента массива Результат представлен на рис. 9.19 — как видно, элемент данных сеанса был успешно удален из памяти. 3 Удаление дс файл Г_1равка i^J^ Назад * ЧННЫ Вид .-■■' сеанса - Microsoft Internet Explorer .» избранное Сервис Справка :.!l CI ''"*'■ у ' """" 'Й'№^нсе "| ; " гЩ Aju-"t'"-L :-.igj http'//loc3lhost7php/09/phpsessionunset3.php #*!? |(J Переход ; i : : ■ : i Удаление данных сеанса Значение температуры не определено ;Й;!Х! ■ * Ссы^и. Рис. 9.19. Удаление эпемента массива
Итоги 313 На этом завершается описание работы с сеансами — и завершается и эта книга. В ней был показан путь от простейших приемов программирования до достаточно продвинутых способов. РНР содержит богатые возможности для создания самых разнообразных приложений. Вам, уважаемый читатель, осталось только применить все полученные знания на практике, в чем автор искренне желает всяческих успехов. Итоги В этой главе описаны некоторые весьма полезные разделы РНР: использование cookie, сеансов, FTP и электронной почты. Любая из этих технологий может значительно расширить функциональность iVeb-прилоясения. Ниже перечислены краткие итоги главы: • Для установки значения cookie используется функция setcookie. • Для доступа к значениям cookie используется суперглобальный массив $ COOKIE, проиндексированный наименованиями cookie. • Для проверки существования cookie может использоваться функция isset. • Для соединения с FTP-сервером используется функция ftp connect. • После установления соединения требуется выполнить аутентификацию при помощи функции ftplogin. • РНР содержит большое количество функций для работы с FTP — ftp nlist для получения списка файлов в каталоге, ftp chdir дляпере- хода в другой каталог, ftp get для выгрузки файла с сервера, ftp put для загрузки файла на сервер и т.д. • Для настройки подсистемы работы с электронной почтой требуется редактирование файла php.ini. • Для отправки e-mail используется функция mail. • Для начала сеанса используется функция sessionstart. • Передача данных сеанса осуществляется через суперглобальный массив $ SESSION.
Приложение А ^^- Справочник по языку Создание скриптов Скрипты заключаются в специальном теге < ?php... ? >, который обрабатывается web-сервером с поддержкой РНР соответствующим образом. В таблице приведены зарезервированные ключевые слова РНР, которые нельзя использовать для обозначения пользовательских объектов. <?php ?> Таблица А. 1. Зарезервированные ключевые слова РНР CLASS and array as break case сfunction class const continue FILE default die do echo else elseif empty enddeclare endfor FUNCTION endif endswitch endwhile eval exception exit extends for foreach LINE global if include include_onc e isset list new old_function or METHOD print require require_once return static switch unset use while declare endforeach function php_user_filter xor
316 Приложение А. Справочник по языку Скрипты состоят из операторов, которые могут простыми и заканчиваться точкой с запятой или составными, заключенными в фигурные скобки. Ниже приведен пример обоих видов операторов: <?php if ($test) { echo "Жизнь прекрасна!"; } ?> PHP может чередоваться с HTML, например: <?php if ($test) { ?> <fc»Bce в порядке.</Ь> <?php } else { ?> <Ь>У нас проблемы.</b> <?php } ?> Типыданных PHP является языком без строгой типизации переменных, и любая переменная может хранить значение произвольного типа, но при этом типы данных в языке все-таки присутствуют, и некорректное их преобразование может привести к серьезным проблемам при разработке приложений. Наиболее простым встроенным типом данных является логический. Логические переменные могут принимать два возможных значения — TRUE (истина) или FALSE (ложь). Делыечислапринимаютзначениявдиапазоне{...-3, -2, -1, 0, 1, 2, 3 ...}. Целочисленные константы могут быть заданы в десятичной, шестнадцатеричной или восьмеричной системе счисления. Для шестнадцатеричной нотации используется префикс «Ох», для восьмеричной — «О» (ноль). Ниже приведено несколько примеров: ■ 234 • -234 • 0123 (восьмеричное число, десятичный эквивалент — 83) • OxlA (шестнадцатеричное число, десятичный эквивалент — 26) Вещественные числа представляют собой значения с плавающей точкой. Диапазон значений и точность зависит от используемой платформы, но обычно максимальное вещественное число не менее 1038 с точностью не менее 14 знаков. Ниже приведены примеры вещественных констант: <?php $valuel = 1.234; $value2 = 1.23е4; $value3 = 1Е-2 3; ?>
Типы данных 317 Строки являются последовательностью символов (в РНР символ эквивалентен байту). РНР не накладывает ограничений на размер строки. Строки могут быть заданы тремя различными способами: • В одинарных кавычках. • В двойных кавычках. • При помощи вставки блока текста (т.н. синтаксис heredoc). Наиболее простой способ задать строку — написать ее в одинарный кавычках (апострофах): <?php echo ' Жизнь прекрасна! '; echo ' Текст также можно записать в несколько строчек.''; ?> Если строка будет заключенав двойные кавычки, то РНР дополнительно вы- полняетинтерпретациюспециальныхсимволов,которыезадаютсяприпомощи специальных последовательностей, начинающихся с символа «\» (обратный слеш): \п Перевод строки (LF), код символа ASCII - 10 (ОхОА). \г Возврат каретки(СК), код символа ASCII - 13 (OxOD). \t Табуляция (НТ), код символа ASCII - 9 @x09). \\ Обратный слеш. \$ Знак доллара. \"- Двойная кавычка . Кроме того, в строках, заключенных в двойные (но не одинарные) кавычки, выполняется интерпретация переменных. Это означает, что обозначение любой переменной, описанное внутри подобной строки, будет автоматически заменено на значение переменной, например: $value = 1; echo "Значение составляет $value."; В результате выполнения данного фрагмента кода будет выведена строка: Значение составляет 1. Третьим способом задания строковых констант является так называемый синтаксис heredoc (оператор «<«»). После оператора «<«» располагается уникальный идентификатор, далее следует произвольный многострочный текст, который должен завершиться тем же самым идентификатором, расположенным в начале строки, начиная с первого символа. Пример подобного синтаксиса приведен ниже: echo <«END Этот пример демонстрирует использование синтаксиса "heredoc" для описание строковой константы большого объема END;
318 _^ Приложение^.Справочник по языку Переменные Переменные в РНР обозначаются при помощи знакадоллара («$»), после которого следует имя переменной. Имена переменных являются зависимыми от регистра, то есть прописные и строчные буквы в них различаются. Имена переменных подчиняются тем же самым правилам, что и остальные идентификаторы: имя переменной начинается с буквы или символа подчеркивания и содержит произвольное число букв, цифр и символов подчеркивания. Ниже приведен пример создания двух переменных путем присваивания им значений: <?pbp $ variable = 5; $anotrier variable = $variable; ?> По умолчанию, переменные присваиваются по значению — выражение справа от оператора присваивания («=») вычисляется, и результат помещается в переменную, заданную слева от оператора присваивания. Это, в частности означает, что если значение одной переменной было присвоено другой переменной, то дальнейшее изменение значений одной из этих переменных не окажет никакого влияния на другую. Переменной может быть также присвоена ссылка на другую переменную. Это означает, что в данном случае копирование значений не производится, а изменение значений одной из этих переменных автоматически отразится и на значении другой переменной. Для обозначения ссылки на переменную используется знак амперсенд («&»), например: <?plip $variable = 5; $new_variable = &$variable; $variable = 6; // Значение $new variable также будет равно 6 ?> Предопределенные переменные В РНР имеется большое количество предопределенных переменных. Все они являются суперглобальными, то есть доступны для использования в любом скрипте, а также в теле любой функции без дополнительных описаний. Ниже приведен перечень наиболее часто употребительных предопределенных переменных: $_GLOBALS. Массив, содержащий перечень глобальных переменных. Индексом массива является имя глобальной переменной. • $_SERVER Массив параметров web-сервера. • $_GET. Массив переменных, переданных скрипту при помощи метода HTTP GET. • $ POST. Массив переменных, переданных скрипту при помощи метода HTTP POST. • $_С00К1Е. Массив переменных, переданных скрипту при помощи cookie. • $_FILES. Список сведений о файлах, которые были загружены на сервер в процессе обработки запроса HTTP POST.
Массивы 319 • $_ENV. Массив переменных среды операционной системы. • $ REQUEST. Массив переменных, переданных скрипту при помощи методов HTTP GEJT и PUT, а также при помощи cookie. • $_SESSION. Массив переменных текущего сеанса работы. Массивы $агтау [index] ~ value; $array = array (valuel, value2); $array = array (keyl => valuel, key2 => value2); Массивы являются наборами из нескольких значений, при этом каждому значению ставится в соответствие некоторый индекс. Индекс массива может быть как целочисленным, так и строковым. В случае использования целочисленных индексов нумерация элементов массива начинается с 0. Массивы именуются точно так же, как и переменные, отличительным признаком массива является использование квадратных скобок после имени массива. Для создания массива достаточно присвоить значение одному из его элементов, например: $аггау [1] = "Жизнь прекрасна."; Данный код создает массив с именем $аггау и присваивает его элементу с номером 1 строку «Жизнь прекрасна. ». После этого можно использовать элемент массива точно так же, как и обычную переменную, например: echo $array[l]; Массив со строковыми индексами создается аналогичным образом: $data ["Иван"] = 12 3; $data ["Петр"] = 567; $data ["Леонид"] = 980; При создании нового массива можно использовать сокращенный синтаксис. Если после имени массива приведены квадратные скобки без значения индекса между ними, то происходит создание нового элемента массива со следующим свободным целочисленным индексом. Если массив не существует, то он создается, а первый элемент получает номер 0, например: $data [] = 12 3; $data [] = "Привет"; $data [] = "Здравствуйте"; В вышеприведенном примере элементу $ data [0] будет присвоено значение 123, элементу $data [1] —значение «Привет» и т.д. Массив может быть также создан при помощи функции array, например: $data = array A23, "Привет", " Здравствуйте "); Созданный таким образом массив будет таким же, как и в предыдущем примере. Для того, чтобы начать нумерацию элементов массива не с 0, ас другого числа, может быть использован оператор = >: $data = array (I => 123, "Привет", " Здравствуйте "); В этом случае значение 123 будет содержаться в элементе $data [1] и т.д.
320 __ Приложение А, Справочник по языку Операторы В РНР предусмотрено большое количество различных операторов, полный перечень которых приведен в табл. А. 2 Та блица А. 2. Опера торы в порядке убывания приоритета Операторы new _[ ! - ++ — (int) (float) (strinQ) (array) (object) * / % « >> & 7 ; = += -= *= /= ■= %= Sc= \= "= <= > = print and xor
Операторы 321 Для примера ниже приведены математические операторы языка: + Сумма двух чис ел. Разность двух чисел. * Произведение двух чисел. / Частное от деления двух числе. % Остаток от деления одного числа на другое (частное по модулю). Ниже приведен пример использования математических операторов: <HTML> <BODY> <Н1 использование математических операторов< /HI > <?php echo "9 + 4 = " , 9 + 4; echo " 9 - 4 = " , 9 - 4 echo "9 * 4 = " , 9 * 4; echo "9 / 4 = " , 9 / 4; echo "9 % 4 = ", 9 % 4 ?> </B0DY> </HTML> Операторы имеют определенный приоритет. Например, рассмотрим выражение: <?php echo 4+2*9; ?> Его результат будет зависеть от того, какой из двух операторов выполнится первым - сложение или умножение. В данном случае результат будет равен 22, так как первым выполнится оператор умножения, так как умножение имеет более высокий приоритет по сравнению со сложением. В табл. А.2 приведены операторы по убыванию приоритета. Операторы с одним приоритетом выполняются по пр'рядку слева направо. Для изменения порядка выполнения операторов используются скобки. Пример использования скобок приведен ниже. <?php echo ' echo echo ?>  + 2*9 = " " D + 2) * 9"  + B * 9)", , 4 + 2*9; D + 2) * 9 ; 4 + B * 9); Результатом выполнения этих трех выражений будет 22, 54 и 22 соответственно. 11 РНР в примерах
322 „_____„ _^ Приложение А, Справочник по языку Оператор if if (expression) statement Оператор i f предназначен для условного выполнения фрагментов кода. Вначале вычисляется значение условие expression, и если оно истинно, то выполняется оператор statement. Если же условие expression ложно, то оператор statement игнорируется. Если в зависимости от определенного условия требуется выполнить больше чем один оператор, то требуется использовать составной оператор, который представляет собой последовательность операторов, заключенную в фигурные скобки. В следующем примере сравниваются две переменные, и если $ value 1 больше, чем $ value 2, то их значения меняются местами, и выводится соответствующее сообщение: <?php if ($valuel > $value2) { echo "$valuel > $value2\n"; echo " Значения меняются местами . " ; $temp = $valuel; $valuel = $value2 , - $value2 = $valuel; } ?> Оператор else if (expression) statementl else statement2 Если в зависимости от некоторого условия требуется выполнить один из двух операторов, на помощь приходит оператор else. Если условие expression истинно, то выполняется оператор statementl, если же оно ложно — то оператор statement2. Пример использования оператора else для сравнения значений двух переменных приведен ниже: <?php if ($valuel > $value2) { echo "$valuel больше $value2 " ; } else { echo "$valuel меньше или равно $value2"; } ?>
OriepaTogelseif ^ ^ . 323 Оператор elseif if (expressionl) statementl elseif(expression2) statement2 elseif(expressionN) statementN else statementZ Оператор elseif расширяет функциональность операторов i f и е 1 s e, позволяя проверить несколько условий последовательно. Условия expressionl, express ion2 и т.д. проверяются последовательно, и в случае истинности одного из них выполняется соответствующий оператор statementK. Если же ни одно из условий не выполнено, вьшолняется оператор statementZ. Ниже приведен пример, в котором выводится результат сравнения двух переменных: <?php if ($valuel > $value2) { echo «$valuel больше $value2"; } elseif ($$valuel == $value2) { echo "$valuel равно $value2 " ; } else { echo "$valuel меньше $value2"; } ?> Вместо ключевого слова elseif можно также использовать два слова else if. Оператор switch switch (expression) { case test!: statementl; break; case test2: statements,- break; case testN: statementN; break; default: statements,- } Оператор switch похож на серию операторов if, в которых одно и то же выражение сравнивается с различными значениями. При совпадении значения выражения с каким-либо значением выполняется соответствующий оператор.
324 Приложение А. Справочник по языку Например, пусть требуется сравнить значение переменной $ехрг с несколькими целыми числами. Для этого может быть использован оператор if: <?php if ($expr == 1) echo "Expr = } elseif ($expr echo "Expr = } elseif ($expr echo "Expr = = 2' 1) 3) } ?> Та же самая задача может быть решена при помощи оператора switch: <?php switch ($expr) { case 1: echo "Expr = Inbreak; case 2: echo "Expr = 2"; break; case 3: echo "Expr = 3 " ; break; } Когда в теле оператора switch обнаруживается оператор case со значением, равным значению выражению expression, выполнение начинается с оператора case и продолжается до конца тела оператора switch или до первого встреченного оператора break. Если в конце очередного блока после оператора case не будет указан оператор break, выполнение будет продолжено до конца оператора switch. Например, имеется следующий оператор switch: switch { case 1: echo case 2: echo case 3: echo ) ($expr) "Expr = "Expr = "Expr = 1 2 3 В том случае, если значение переменной $ехрг равно 1, будут выполнены все три оператора echo. В теле оператора switch можно также употреблять ключевое слово defan 11, под которым имеется в виду значение, которое не соответствует никакому из вышеперечисленных значений case. Оператор default должен располагаться после всех операторов case, так как после него ни один оператор case не будет обрабатываться. Ниже приведен пример использования оператора default:
QnepaTopwhile „ , » 325 <?php switch ($expr) { case 1: echo "Expr = Inbreak; case 2 : echo "Expr = 2 " ; break; case 3 : echo "Expr = 3 " ; break; default : echo "Expr не равно ни 1, ни 2, ни 3"; } ?> Этот оператор switch эквивалентен следующему оператору if: <?php if ($expr ==1) { echo "Expr is 1"; } elseif ($expr = = 1) { echo "Expr is 2"; } elseif ($expr = = 3) { echo "Expr is 3"; } else { echo " Expr не равно ни 1, ни 2 , ни 3 " ; } Оператор while while (expr) statement Цикл while является простейшим циклом в РНР. Он позволяет повторять выполнение заданного оператора statement (который может быть составным) дотехпор, пока значение выражения ехрг является истинным (TRUE). Оператор statement называется телом цикла. Значение выражения проверяется каждый раз перед выполнением тела цикла, так что если даже если значение изменится в середине тела цикла, всё тело цикла будет выполнено до конца. Если значение выражения ехрг является ложным (FALSE) перед началом выполнения цикла, то тело цикла не будет выполнено ни разу. Также как и в случае с оператором if, для того, чтобы поместить в тело цикла несколько простых операторов, их следует объединить в составной при помощи фигурных скобок: <?php $loop_index = 1; while ($loop_index <= 10) { echo $loop_index+ +; } ?>
326 Приложение А, Справочник по языку В этом примере использовался счетчик цикла — переменная $loop_index. Но при использовании цикла whi le наличие счетчика цикла не является обязательным. Например, некоторые функции, например feof (которая возвращает TRUE при достижении конца файла), могут быть использованы для формирования условия цикла while. Ниже приведен пример, иллюстрирующий это: <?php $handle = fopen ("file.txt", "г") ; while (!feof ($handle)) { $text = fgets ($handle); echo $text, "<BR>"; } ?> Оператор do. . .while do{ statement } while [expr); Цикл do. . .while очень похож на цикл while, за тем лишь отличием, что значение выражения ехрг проверяется в конце после выполнения тела цикла, а не в начале. Это означает, что тело цикла do. . . whi I e всегда выполняется хотя бы один раз, в отличие от тела цикла while, которое может не выполниться ни разу. Ниже приведен пример цикла while, тело которого не будет выполнено ни разу: <?php $ value =10; while ($value < 5) { $value += 2; echo $ value, "<BR>"; ) ?> Но при использовании цикла do. . .while его тело будет выполнено минимум один раз, поэтому при выполнении следующего примера будет отображена строка «12»: <?php $value = 10; do { echo Svalue, "<BR>"; $value += 2; } while (Svalue < 5); ?>
Оператор for 327 Оператор for for (exprl; expr2; ехргЗ) statement Цикл for является наиболее универсальным и часто используемым циклом в РНР. При его выполнении сначала однократно вычисляется выражение exprl. Далее вычисляется значение условия цикла — выражение ехрг2. До тех пор пока оно истинно (TRUE), выполняется тело цикла — оператор statement. После тела цикла вычисляется выражение ехргЗ, которое обычно используется для увеличения счетчика цикла. Как только условие цикла станет ложным (FALSE), выполнение цикла прекратится. Ниже приведен пример цикла for, который отображает текст 20 раз: <?php for ($Toop_counter = 0; $loop_counter < 2 0 ; $loop_counter++) { echo "Этот текст будет отображен 2 0 pa3.<BR>"; } ?> Этот цикл может быть также записан в сокращенной форме, в которой тело цикла будет отсутствовать: <?php for (Sloop counter = 0; Sloop counter < 20; echo "Этот текст будет отображен 20 раз.<ВК>", Sloop counter+ + ); ?> Оператор foreach foreach (array expression as SvalueJ statement foreach (array expression as $key => SvalueJ statement Цикл foreach предназначен для перебора всех элементов заданного массива. Он предназначен только для обработки массивов, так что если его попытаться применить к другим объектам, будет выведено сообщение об ошибке. Первая форма этого цикла осуществляет перебор всех элементов заданного массива array expression. При каждой итерации значение текущего элемента массива заносится в переменную $va 1 ие, и выполняется тело цикла — оператор statement. Вторая форма отличается от первой тем, что помимо сохранения значения элемента массива, перед каждым выполнением тела цикла в переменную $кеу заносится значение индекса элемента массива. Ниже приведен пример использования цикла foreach: <?php $array = array ("grapes", "grapefruit", "bananas"); foreach ($array as $value) { echo "Текущее значение: $value\n" ; } V>
328 Приложение А. Справочник по языку Можно также отобразить значение индекса элемента массива: <?php $array = array ("grapes", "grapefruit", "bananas"); foreach ($array as $key => $value) { echo "Текущий индекс равен $key, а значение — $value\n"; } ?> Функции function function name(l$argl [, $arg2, ■ ■ ■ , [$argN]]]) { [statement] [return Sreturn value;] } Функция представляет собой группу операторов, используемых совместно. Функция может быть вызвана по имени, ей могут быть переданы некоторые данные, и, наконец, функция может вернуть результат. В теле функции может располагаться любой код РНР, включая объявление других функций и даже классов. Пример описания функции приведен ниже: function echoer () { echo "Доброе утречко!" ; } Вызов функции осуществляется по имени: echoer (); Функция может принимать один или несколько аргументов, которые перечисляются через запятую внутри круглых скобок. Ниже приведен пример функции, которая отображает содержимое переданного ей массива: <?php $vegetables [0] = "пшеница"; $vegetables [l] = "рожь"; $vegetables [2] = "ячмень"; $vegetables [3] = "овес"; echoer ($vegetables); • function echoer ($array) for ($index = 0; $index < count ($ array) ; $index + +) } echo "Элемент $index: ", $array[$index], "\n"; } ?>
Классы и объекты 329 При выполнении данного кода будут отображены следующие строки: Элемент 0: пшеница Элемент 1: рожь Элемент 2: ячмень Элемент 3: овес Для возврата значения из функции используется оператор return: return {value); Круглые скобки являются необязательными. Например, следующая функция увеличивает переданное ей значение на единицу и возвращает его в качестве результата: <?php function incrementer ($value) { return + + $value; ) ?> Ниже приведен пример использования значения, возвращенного функцией: <?php echoincrementer(9); function incrementer ($value) { return + + $value; } ?> Классы и объекты class class name [extends ancestor name] I [accessrnodifier] var variable; [accessrnodifier] function function name (argl, arg2,... argN) { statement } } Класс представляет собой совокупность переменных и функций, или, в терминах объектно-ориентированного программирования (ООП), свойств и методов. Класс является типом данных, поэтому возможно создавать переменные типа класса. Например, класс Person содержит имя человека и два метода — setname для присвоения значения имени и getname для получения сохраненного значения имени.
330 Приложение А. Справочник по языку !■■»—- *4*~*n*V?W class Person { var $name; function set_name ($text) { $this->name = $text; } function get_name () { return $this->name; } Для создания объекта определенного класса используется оператор new. Оператор new используется только для создания переменных типа класса, он не требуется для создания простых переменных целого, вещественного и остальных скалярных типов. Например, для создания нового объекта класса Person и сохранения его в переменной с именем Sivan, может быть использован следующий код: <?рпр class Person { var $name; function set_name ($text) { $this->name = $text; } function getjame () { ■i return $this->name; } $ivan = new Person; ?> Для доступа к методам объекта класса Person используется оператор «->» (стрелка). Например, для сохранения имени человека может быть использован следующий код: $ivan = new Person; $ivan->set_name ("Иван"); Для получения текущего значения имени используется метод getname: $ivan = new Person; $ivan->set_name ("Иван") ; echo "Имя человека : ", $ivan->get_name () , "."; После выполнения данного фрагмента кода будет отображена следующая строка: Имя человека: Иван. Помимо методов, при помощи оператора «->» доступны также и свойства класса, например:
331 <?php class Person { var $name; function set_name ($textj { $this->name = $text; } function getjame () { return $ this->name; } Sivan = new Person; echo "Имя человека: ", Sivan->name, "."; ?> По умолчанию все свойства и методы класса доступны для использования, но это не всегда является корректным. Метод, который сохраняет значение в свойстве класса, может выполнять дополнительную обработку, которая не будет выполнена, если значение свойству будет присвоено напрямую. Например, метод setname сохраняет значение имени только в том случае, если его длина не превышает заданного предела: function set_name ($text) { if (strlen ($text) <= 12 8) { $this->name = $text; } } Для управления внешнего доступа к свойствам и методам класса используются модификаторы доступа (access modifier). Существует три модификатора доступа: • public. Свойство или метод доступно всем. Этот модификатор используется по умолчанию. • private. Свойство или метод доступно только внутри данного класса • protected. Свойство или метод доступно только внутри данного класса и всех его потомков. Если свойство или метод объявлены как private, к ним нельзя обратиться извне класса. Например, пусть класс описан следующим образом: <?php class Person { private $name; function set_name ($text) { $this->name = $text; } function get_name () { Классы и объекты
332 Приложение А, Справочник по языку return $this->name; } } Sivan = new Person; echo "Имя человека: ", $ivan->name, "."; ?> При вьшолнении данного кода будет выведено следующее сообщение об ошибке: И\« человека: PHP Fatal error: Cannot access private property Person::$name in test.php Метод класса также может быть объявлен как private: class Person { var $name; private function set_name ($text) { $this->name = $text; } function get_name () { return $this->name; В данном случае метод setname недоступен для использования за пределами данного класса.
ПриложениеБ *~Ч^ яя&шт&лмыш'тюкяФ Справочник функций В данном приложении приведены наиболее употребительные функции РНР, предназначенные для обработки массивов, файлов и строк. Таблица Б. 1. Функции обработки массивов Функция Назначение array array change key case (array input [, int case]) Изменение регистра строковых индексов массива. array array chunk (array input, int size [, bool preserve keys]) Разделение массива на части. array array_combine (array keys, array values) Создание массива. array array count values (array input) Формирован \лемассива,индексамикоторо- го являются значения заданного массива, а значениями — число повторений соответствующего значения в заданном массиве. array array diff (array arrayl, array array2 [, array ... ] ) Формирование массива из тех элементов первого заданного массива, которые отсутствуют востальныхзаданныхвгачествеарлуменгов функции массивов. Индексы в новом массиве перенумеровываются. array array difFassoc arrayl,array array2 [, array ... ] ) Формирование массива из тех элементов (array первого заданного массива, которые отсутствуют в остальных заданных в качестве аргументов функции массивов, сучетом строковых индексов.
334 Функция array array diff uassoc (array array 1, array array2 [, array . . . , callback key compare func]) array array fill (int start index, int num, mixed value) array array filter (array input callback callback]) array array flip (array trans) array array intersect (array arrayl, array array2 [, array . . . ]) array array intersect assoc (array arrayl, array array2 [, array ...]) bool array_key_exists (mixed key, array search) array array keys (array input [, mixed search value]) array array map (mixed callback, array arrl [, array ...]) ____ array array merge (array arrayl, array array2 [, array ...]) array array^merge recursive (array arrayl, array array2 [, array ... 1) bool array multisort (array arl [, mixed arg [, mixed . . . [, array ...]]]) array array pad (array input, int pad size, mixed pad value) mixed arraypop (array array) int array_push (array array, mixed var [, mixed . ..] ) Приложение Б. Справочник функций Назначение ^== Формирование массива из тех элементов первого заданного массива, которые отсутствуют в остальных заданных в качестве аргу- метхэвфункциимассивов, сучетом строковых индексов.Для сравнения индексов используется заданная функция. Заполнение массива заданным значением. Фильтрация элементов массива с использованием заданной функции. Обмен местами индексов и значений. Формирование массива из элементов, кото- рыеприсутствуютвовсехза^щпиых массивах. Формирование массив из элементов, которые присутствуют во всехзаданныхмасси- вах, с учетом строковых индексов. Проверка наличия заданного индекса в массиве. Формирование индексов заданного массива в виде отдельного массива. Формирование массива из всехэлементов заданных массивов после обработки ихука- занной функцией. Простоеслияниемассивов. Рекурсивное ел мяниемассивов. Сортировка многомерных массивов. Заполнение массива заданным значением до определенной длины. Возврат последнего элемента массива с его одновременным удалением из массива. Добавление заданного элемента в конец массива. Аналогично конструкции $аггау [] = $value;
PHP в примерах 335 Функция mixed array rand (array input [, int num req]) Назначение выбор одного или нескольких случайно взятых элементов из массива. mixed arrayreduce (array input, callback function [, int initial]) Обращение массива — первый элемент ста- array array reverse (array , новится последним, второй — предпослед- array [, bool preserve keys]) НИМИТ.Д. mixed arraysearch (mixed ,_, Поиск заданного элемента в массиве и опре- needle, array haystack [, bool деление соответствующего ему индекса. strict]) Возвращает первый элемент массива, одно- mixed array_shift (array array) временно удаляя его из массива с перенумерацией числовых индексов. array array slice (array array, Формирование подмассива заданной дли- int offset [, int length]) ны, начиная с указанного элемента. array array splice (array Удалениеизмассивафрагментазаданной input, int offset [, int length длины, начиная с определенной позиции, и [, array replacement]]) вставка вместо него заданный массив. mixed array sum (array array) Вычислениесуммувсехэлементовмассива. Формированиемассивиз гехэлементов перво- array array udiff assoc (array го задан но го массива, которые отсутствуют в ос - arrayl, array агтау2 тальныхзаданныхвкачествеаргументов [, array . . . ,callback функциимассивов, сучетомстроковыхиндек- data compare func]) сов. Для сравнения элементов массивов исполь- зуетсязаданнаяфункция. Формирование массив из тех элементов первого заданного массива, которые отсутствуют в остальных заданных в качестве аргументов функциимассивов, с учетом строковых индексов. Для сравнения элементов массивов и для сравнения ключей используются заданные функции Формирование массив из тех элементов первого заданного массива, которые отсутствуют в остальных заданных в качестве аргументов функции массивов. Индексы в новом массиве перенумеровываются. Последовательное применение заданной функции к элементам массива, в результате чегоформируетсяитоговоезначение. Например, если функция выполняет сложение своих аргументов, то в результате образуется сумма всех элементов массива. array array udiffuassoc (array arrayl, array array2 [ , array . . . , callback datacomparefunc, callback keycomparefunc]) array array udiff (array arrayl, array array2 [, array . . . , callback data compare func]) array array umque (array array) Удаление дублирующихся значений из массива.
336 Приложение Б. Справочникфункций Функция Назначение int array unshift (array array, mixed var [, mixed . .. ] ) Добавление одного или нескольких элементов в начало массива с перенумерацией числовых индексов. array array values (array input) Формирование/массива из всехзначенийзадан- ногомассива.Новыймассивиндексируетсяпо- следовательными целыми числами, начинаясО. bool array walk (array array, callback function [, mixed userdata]) Выполнение заданной функции последова- тельнонадвсемиэлементамимассива. array array ([mixed ... ] ) Создание массива. bool arsort (array array [, int sort flags]) Сортировкамассивалоубь/ваниюегозначе- ний с сохранением индексов. bool asort (array array [, int sort flags] ) Сортировка массива по возрастанию его значений с сохранением индексов. array compact (mixed varname [ , mixed . . . ] ) Создание массива, содержащего названия переменных и их значения. int count (mixed var [, int mode ] ) Количествоэлементовмэссивэ. mixed current (array array) Текущий элемент массива. array each (array array) Текущий элемент и индекс массива. mixed end (array array) Перемещениеуказателякпоследнемуэле- ментумассива. int extract (array var array [, int extract type [, string prefix] ]) Создание переменных с заданными значениями на основе массива. bool in array (mixed needle, array haystack [, bool strict]) Проверка, содержится ли заданное значение в массиве. mixed key (array array) Текущий индекс массива. bool krsort (array array [, int sort flags]) Сортировкамассивалоубываниюегоиндек- COB. bool ksort (array array [, rrt sortflags]) Сортировка массива по возрастанию его индексов. void list (mixed . . . ) Присвоение переменным из списка значения подобно массиву. void natcasesort (array array) Сортировкамассиваестественнымобра- зом'безучетарегистрасимволов. Естественным здесь и далее называется такой порядок сортировки, при котором цифровые последовательности, входящие в состав сравниваемьи строк, рассматриваются как числа. Например, при естественном сравнении строк они будут упорядочены следующим образом: «А» < «АО < «А1» < «А1А» < «А1Б» < «А2» < «А10» < «А20». -Прим.ред.
PHP в примерах Функция void natsort (array array) mixed next (array array) mixed pos (array array) mixed prev (array array) array range (int low, int high [, int step]) mixed reset (array array) bool rsort (array array [, int sort flags]) void shuffle (array array) int sizeof (mixed var [, int mode]) bool sort (array array [, int sort flags]) bool uasort (array array, callback cmp function) bool uksort (array array, callback cmp function) bool usort (array array, callback cmp function) Таблица Функция string basename (string path [, string suffix]) bool chgrp (string filename, mixed group) 337 Назначение Сортировка массива естественным образом с учетом регистра символов. Перемещение указателя на следующий элемент массива. Текущийэлементмасалва. Перемещение указателя на предыдущий элемент массива. Создание массива, содержащего диапазон элементов. Перемещениеуказателянапервыйэлемент массива. Сортировка массива по убыванию значений его элементов с перенумерацией его индексов. Перестановка элементы массива случайным образом. Количество элементовлшссива. Сортировка массива по возрастанию значений его элементов с перенумерацией его индексов. Сортировка массива по возрастанию его значений, с сохранением индексов и использованием заданной функции сравнения элементовмассива. Сортировка массива по индексам с использованием заданной функции сравнения эле- ментов массива. Сортировка массива с использованием заданной функции сравнения элементов мясжиня. .2. Функции обработки файлов Назначение Выделение имени файла из заданного пуши. Изменение группы доступа для файла.
338 Приложение Б. Справочник функций Функция bool chown (string filename, mixed user) void clearstatcache (void) bool copy (string source, string dest) void delete (string file) string dirname (string path) float diskfreespace (string directory) float disk total space (string directory) float diskfreespace (string directory) bool fclose (resource handle) bool feof (resource handle) bool fflush (resource handle) string fgetc (resource handle) array fgetcsv (resource handle, int length [, string delimiter [, string enclosure]]) string fgets (resource handle [, int length]) string fgetss (resource handle, int length [, string allowable_tags]) bool fileexists (string filename) string file get contents (string filename [, bool use include path [, resource context]]) int file put contents (string filename, string data [, int flags [, resource context]]) Назначение Изменение владельца файла. Очисткакэшасостоянийфайлов.Кэши- руютсярезультатывыполненияследую- щих функций: stat(), lstat(), file_exists(), is_writob/e {), isreadable [), isexecutable (), isjile (), i$_dir(), isjinkf), filectime(), fileatime(), filemtime(), fileinode (), filegroup (), fileownerf), filesize (), filetype () и fileperms (). Копиров аниефайла. Удалениефайла. Выделение катал о га из полного имени файла. Определениесвободногоместаназа- данномустройстве( каталоге). Определение суммарного объема задан- ногоустройства( каталога). Определение свободного места на задан номустройстве^аталоге^. Закрытиеоткрытогофайла. Проверка на конец файла. Сброс кэша записи файла на диск. Чтение символа из файла. Чтение строки в формате CSV и выделение отдельных полей. Чтениестрокиизфайла. Чтение строки из файла и удаление HTML-тегов. Проверка на существование файла(каталога). Чтение файла целиком в одну строку. Запись строки в файл.
PHP в примерах 339 Функция Назначение array file (string filename [, int use include path [, resource context]]) Чтение файла в виде массива по строкам. int fileatime (string filename) int filectime (string filename) Время последнего обращения к файлу. Время последнего изменения /-узла' файла. int fllegroup (string filename) Идентификатор группы файлов. int fileinode (string filename) Идентификатор /-узла файла. int filemtime (string filename) int fileowner (string filename) Времяпоследнегоизмененияфайла. Определение владельца файла. int flleperms (string filename) int filesize (string filename) Определение прав на файл. Определение размера файла. string filetype (string filename) Огфедепаме ми файла. bool flock (resource handle, int operation [, int &wouldblock]) Блокировка файла. array fhrnatch (string pattern, string string [, int flags]) Проверка на совпадения имени файла с шаблоном. resource fbpen (string filename, string mode [, int use include path [, resource zcontext]]) Открытиефайла или URL. int fpassthru (resource handle) Вывод всех оставшихся данных из файла. int fputs (resource handle, string string [, int length]) Запись в файл двоичных данных. string fread (resource handle, int length) Чтение из файла дв оичныхданных. mixed fscant (resource handle, string format [, string varl]) Чтениеданныхизфайлапозаданному формату. int fseek (resource handle, int offset [, int whence]) Перемещениеуказателяпофайлу. array 'fstat (resource handle) Информация о файле. int ftell (resource handle) Определение положения указателя по файлу. bool ftruncate (resource handle, int size) Обрезание файла по заданной длине. 1 В Unix-системах i-узел содержит информацию о правах доступа, владельца файла, а также о списке блоков, составляющих файл. Изменение содержимого файла как такового не всегда влияет на i-узел. — Прим. ред.
340 ПриложениеБ. Справочникфункций Функция int fwrite (resource handle, string string [, int length] ) array glob (string pattern [, int flags]) bool is_dir (string filename) bool is_executable (string filename) bool is_file (string filename) bool is_link (string filename) bool is_readable (string filename) bool is_uploaded_file (string filename) bool is_writable (string filename) bool is_writeable (string filename) bool link (string target, string link) int linkinfo (string path) array lstat (string filename) bool mkdir (string pathname [, int mode [, bool recursive [, resource context]]]) bool move_uploaded_file (string filename, string destination) array parse_ini_file (string filename [, bool process_sections]) array pathinfo (string path) int pclose (resource handle) resource popen (string command, string mode) int readfile (string filename [, bool use_include_path [, resource context]]) Назначение Запись в файл двоичных данных. Поискфайловыхлутей, совпадающих с шаблоном. Определение, задает ли f i l ename каталог. Определение, задаетли filename ис- полняемыйфайл. Определение, задаетли fi 1 ename обычныйфайл. Определение, задаетли filename символическую ссылку. Определение, задаетли fi 1 ename файл, доступный для чтения. Определение, задаетли filename файл, загруженный при помощи POST. Определение, задает ли.filename файл,доступныйцлязаписи. Определение, за дает п\лл\Л ename файл, доступный для записи. Создание жесткой ссылки на файл (только для Un ix). Чтениеинформацииожесткойссылке. Чтение информации о символической ссылке. Создание каталога. Перемещение загруженного файла в заданный каталог. Синтаксический разбор конфигурацион- ногофайпа. Определение информации о пути к файлу. Закрыть файловый указатель процесса. Открьпьфайловыйуказательпроцесса. Вывести заданный файл в стандартный поток вывода.
PHP в примерах 341 Функция Назначение string readlink (string path) Определить файл, на который ссылается символическая ссылка. string realpath (string path) Определить абсолютное имя файла (каталога). bool rename (string oldname, string newname [, resource context]) Переименование фа йлаили каталога. bool rewind (resource handle) Перемещение указателя ^началу файла. bool rmdir (string dirname [, resource context]) Удалениекаталога. int set file buffer (resource stream, int buffer) Установить объем буфера для заданного файла. int stream_set_write_buffer ( resource stream, int buffer ) Установить объем буфера для заданного файла. array stat (string filename) Информация офайле. bool symlink (string target, string link) Создание символической ссылки string tempnam (string dir, string prefix) Создание файла суникальным именем. resource tmpfile (void) Созданиевременного^кяйла. bool touch (string filename [, int time [, int atime]]) Установить время доступа и время последнее модификации файла. int umask ([int mask]) Изменение текущей масккрежима созда - ния файлов. bool unlink (string filename [, resource context]) Удаление файла. Таблица Б. 3. Функции обработки строк Функция Назначение string addcslashes (string str, string charlist) Экранирование специальных символов, а также символов из заданного списка, при помощи символа « \» (как в языке С). string addslashes (string str) Экранирование специальных символов при помощи символа о \» (как в языке С]. string bin2hex (string str) Преобразование бинарныхданных в шестнадцатеричное представление
342 Приложение Б. Справочникфункций Функция string chop (string str [, string charlist]) string chr (int ascii) string chunk split (string body [, int chunklen [, string end]]) string convert cyr string (string str, string from,string to) mixed count chars (string string [ , int mode]) int crc32 (string str) string crypt (string str [, string salt]) void echo (string argl [, string argn...]) array explode (string separator, string string [, int limit]) int fprintf (resource handle, string format [, mixed args]) array get html translation table (int table [, int quote style]) string hebrev (string hebrew text [, int max chars per line]) string hebrevc (string hebrew text [, int max chars per line]) string html entity decode (string string [, int quote style [, string charset]]) string htmlentities (string string [, int quote style [, string charset] ]) string htmlspecialchars (string string [, int quote_style [, string charset]]) string implode (string glue, array pieces) Назначение Удаление завершающих пробелов, а также любых дополнительных символов (синоним rtrimj. Символ по коду ASCII. Разбиение строки на фрагменты заданной длины. Преобразование из одной кириллической кодировки в другую. Информация о символах, встречающихся в строке Вычисление CRC32 (контрольной суммы) заданной строки. Одностороннее шифрование строки. Отображение одной или нескольких строк. Разбиение строку на подстроки, ограниченные заданным разделителем, и формирование из них массива. Вывод отформатированной строки в файл. Таблица преобразования, используемая и htmlentities(). Преобразование текста на иврите из логической кодировки в визуальную. Преобразование текста на иврите из логической кодировки в визуальную с преобразованием перевода строки. Декодирование всеНТМЬ-представле- ния в соответствующие символы. Функция выполняет обратное действие по anDieeeoIChtrnlentites. Кодирование всех специальных символов в их HTAdL-представление (например, символ < кодируется как &gt;). (Содирование всех символов в их HTML-представление, если оно у них есть. Формирование строку из элементов массива.
PHP в примерах 343 Функция Назначение string join (string glue, array pieces) Формирование строку из элементов массива. int levenshtein (string strl, string str2) Вычисление расстояния Левенпгтейна между двумя строками. array localeconv (void) Информация о числовых форматах. string ltrim (string str [, string charlist]) Удаление лидирующих пробелов (а также любыхдругихзаданных символов]. string md5_file (string filename [, bool raw_output] ) Вычислениехеша/И05заданногофайла. string md5 (string str [, bool raw_output]) ВьнислениехешаМ05заданнойсгр<жи. string metaphone (string str) Вычисление ключа metaphone для строки. Для схожих по произношению слов функция вернет одинаковое значение. string money format (string format, float number) Форматирование числа какденежной величины. string nl langinfo (int item) Определение информации оязыке и региональных настройках. string nl2br (string string) Добавлениетега <BR> перед каждым переводом строки. string number_format (float number [, int decimals]) Форматированиечисласразделигеля- ми между группами разрядов. int ord (string string) ASCII-код заданного символа. void parse str (string str [, array arr]) Синтаксический разбор строки URL и присвоение значения переменным. int print (string arg) Отображение строки. void printf (string format [, mixed args]) Отображение строки с форматированием. string quoted_printable_decode (string str) Преобразованиесгрсжив кодировке quoted-printableB8-6nTHyiocTpoKy. string quotemeta (string str) Экранирование специальных символов. string rtrirn (string str [, string charlist]) Удаление завершающих пробелов (а также любьгсдополнительных символов/ string setlocale (mixed category, string locale [, string ...]) Установка информации о языке и ре- гиональныхнасгройках string shal file (string filename [, bool raw output]) Вычисление хеша SHA7 заданного файла. string shal (string str [, bool raw output]) ВычислениехешабШ 1 заданнойстроки.
344 Приложение Б. Справочникфункций Функция На значение int similar_text (string first, string second [, float percent]) Вычисления лодобиядвухстрок. string soundex (string str) Вычисление ключа soundex для строки. Для схожих по произношению слов функция вернет одинаковое значение. string sprintf (string format [, mixed args]) Формирование строки с форматирова- mixed sscanf (string str, string format [, string varl]) Чтение переменныхиз строки по за- данномуформату. mixed str ireplace (mixed search, mixed replace, mixed subject [, int &count]) Поиск и замена подстроки в строке безучетарегистра символов. string str pad (string input, int pad length [, string pad string [, int pad type]]) Заполнение строки до определенного размера заданной подстрокой (обычно символом]. string str repeat (string input, int multiplier) Повторение строки. mixed strreplace (mixed search, mixed replace, mixed subject [ , int &count]) Поиск и замена подстроки в строке сучетомрегистрас\лмволов. string str_rotl3 (string str) Трансформация строки поалгоритму ROT13. Преобразование ROT13заключается впростом сдвиге каждой латинской буквы на 13позиций валфавите, остальныесимволы не изменяются. Обратное преобразование выполняетсятойжефункцией. string str shuffle (string str) Случайное перемешивание символов встроке. array str split (string string [, int split length] ) Формирование массива из символов строки. mixed str_word_count (string string [ , int format]) Подсчет количества слов в строке. int strcasecmp (string strl, string str2) Сравнение двоичных данных без учета регистраснмволов. string strchr (string haystack, string needle) Выд епеи\лечасти строки от первого вхождения подстроки до конца (сино- /-/MMstrstrj. int strcmp (string strl, string str2) Сравнение двоичных данных с учетом регистраснмволов. int strcoll (string strl, Сравнениестроксучетомрегиональ- string str2J ныхнастроек.
PHP в примерах 345 Функция Назначение int strcspn (string strl, string str2) Определение длины участка в начале строки, не соответствующего маске. string strip_tags (string str [, string allowable_tags]) Удаление из строки тегов HTML и PHP. string stripcslashes (string str) Обратное преобразование строки, закодированной при помощи addcslashes. int stripos (string haystack, string needle [, int offset]) Поиск первого вхождения подстроки в строке без учета регистра символов. string stripslashes (string str) Обратное преобразование строки, закодированной при помощи addslashes. string stristr (string haystack, string needle) Выделение части строки от первого вхождения подстроки до конца без учета регистра символов. int strlen (string str) Определениедлиныстроки. int strnatcasecmp (string strl, string str2) Сравнение строк с учетом естественного порядка безуч етарегисграсимволов. int strnatcmp (string strl, string str2) Сравнение строк с учетом естественного порядка. int strncasecmp (string strl, string str2 , int len) Побайтовое сравнение первых п симво- ловстрокбезучетарегисгра символов. int strncmp (string strl, string str2, int len) Побайтовое сравнение первых п симво- ловстроксучетомрегисгра символов. int strpos (string haystack, string needle [, int offset]) Поиск первого вхождения подстроки в строке с учетом регистра символов. string strrchr (string haystack, char needle) Поиск последнего вхождения символа в строке. string strrev (string string) Инвертированиестроки. int strripos (string haystack, string needle [, int offset]) Поиск последнего вхождения подстроки встрокебезучетарегистра символов. int strrpos (string haystack, string needle [, int offset]) Поиск последнего вхождения подстроки в строке сучетом регистра символов. int strspn (string strl, string str2) Определен1яедлиныучасткастроки, состоящего из заданных символов. string strstr (string haystack, string needle) Выделение части строки от первого вхождения подстроки до конца. string strtok (string argl, string arg2) Разбиение строки на отдельные лексемы, используя заданный набор разделителей. string strtolower (string str) Преобразование прописных букв встрочные.
346 Приложение Б. Справочникфункций Функция string strtoupper (string string) string strtr (string str, string foam, string to) int substr compare (string main str, string str, int offset [, int length [, bool case sensitivity] ]) int substr_count (string haystack string needle) string substr_replace (string string, string replacement, int start [, int length] ) string substr (string string, int start [, int length]) string trim (string str [, string chartist]) string ucfirst (string str) string ucwords (string str) void vprintf (string format, array args) string vsprintf (string format, array args) string wordwrap (string str [, int width [, string break [, boolean cut]]]) Назначение Преобразование строчных букв в прописные. Преобразование заданных символов в строке. Сравнение двух строк, начиная с заданного смещения (с учетом или без учетарегистрасимволов). Подсчет того, сколько раз заданная подстрока встречается в строке. Поиск и замена всех вхождений подстроки в заданном участке строки. Выделение заданной подстроки из исходной строки. Удаление лидирующих и завершающих пробелов fa также любых других заданных символов]. Преобразованмепервойбуквыстроки в прописную. Преобразование первой буквы кажцо- го слова строки в прописную. Отображение строки с форматированием. Формированиестрокисформатирова- нием. Выравниваетстроки по заданной правой границе.
Научно-техническое издание Стивен Хольцнер РНР в примерах Подписано в печать 28.11.2006. Формат 70х100/,б. Усл. печ. л. 28,6. Гарнитура Школьная. Бумага газетная. Печать офсетная. Тираж 4000 экз. Заказ 6510 Издательство «Бином-Пресс», 2007 г. 141077, Королев Московской обл., ул. 50 лет ВЛКСМ, 4-Г При участии ООО «ПФ «Сашко» Отпечатано в ОАО «ИПК «Ульяновский Дом печати» 432980, г. Ульяновск, ул. Гончарова, 14