PHP
для чайников
PHP 5 для "Чайников"
PHP 5 ДЛЯ "ЧАЙНИКОВ" -
Джанет Валейд
Файл опубликован на сайте для ознакомления!
[Введение]
Раз вы держите в руках эту книгу, значит, вас интересуют сценарии РНР. Вероятно, Вы
хотите научиться программировать и слышали, что РНР — очень простой язык. Это действительно
так. С языка РНР можно начинать изучение программирования.
Возможно, вы разрабатываете интерактивный Web-узел и в качестве языка хотите использовать
РНР. И здесь вы правы. С помощью этого языка вы сможете обеспечить очень эффективное
взаимодействие с посетителями своего Web-узла.
Возможно, вам нужно в короткий срок разработать обычное приложение. Вы слышали,
что РНР освоить очень легко. Да, это так. При создании языка РНР ставилась отдельная
цель — обеспечить простоту его изучения.
А может, вы администрируете некоторую систему и надеетесь, что язык РНР поможет
обеспечить эффективную работу с файлами или обработку данных. Он действительно может
почти все. С его помощью можно даже написать электронное сообщение своему шефу
с предложением перейти к использованию РНР.
[Об этой книге]
Эту книгу можно рассматривать как доступное введение в область программирования на
языке РНР: в ней рассматриваются основные вопросы программирования вообще и особенности
языка РНР в частности. Книга начинается с основ РНР. Сначала вы сможете определить,
нужно ли вам устанавливать РНР. (Детальные инструкции по установке РНР содержатся
в приложении А.) В книге описаны основные возможности языка РНР с примерами их использования.
Если у вас есть опыт программирования, вы можете пропустить этот раздел.
В книге описаны основные варианты использования РНР. Вы узнаете, как написать сценарий
для Web, взаимодействовать с файлами и базами данных, а также научитесь решать другие типичные
задачи. Кроме того, в книге содержатся рекомендации по эффективному использованию
РНР и рассказывается, как избежать ошибок. Информация, содержащаяся в приложениях, поможет
новичкам и опытным программистам быстро написать много интересных приложений.
[Как использовать эту книгу]
Книга написана как справочник, а не как учебное пособие, поэтому вам не придется читать
ее от корки до корки. Вы можете начать изучение книги с любого вопроса.
Книга хорошо структурирована, поэтому по оглавлению можно легко найти нужную главу.
В каждой главе содержатся ссылки на другие главы, в которых можно найти информацию, связанную
с данным вопросом.
В книге содержится множество примеров кода на РНР, включающих как несколько строк,
так и целые программы. Операторы РНР в книге выделены следующим образом:
Это оператор сценария РНР
В тексте книги операторы РНР тоже выделяются специальным шрифтом, например, ~вот так~ (нет!)
В примерах кода некоторые слова выделены курсивом (нет!). Они обычно описывают параметры,
которые необходимо заменять реальными значениями. Например, в команде
echo ЧИСЛО!, число2
выделенные курсивом параметры нужно заменить реальными числами. При использовании
этого оператора в сценарии он может иметь вид
echo 3, 127
Кроме того, примеры кода могут содержать многоточия, которые не нужно вводить
в сценарии. Они лишь означают, что в списке можно использовать любое количество параметров.
Например, если вам встретится строка
echo число!, число2, ...
в своем сценарии многоточие вводить не нужно, вместо него можно использовать реальные
параметры.
[Очевидные nftec/положения]
Надеюсь, вы достаточно много знаете о компьютерах, и вас не пугают такие термины, как
файл, каталог, путь, или другие основные понятия, связанные с операционной системой.
Предполагается, что вы умеете скопировать файл в нужный каталог.
Предполагается также, что вы умеете создавать файлы, редактировать их в редакторе,
удалять, копировать и перемещать.
Если вы хотите работать с РНР, то должны использовать операционную систему, которая
поддерживает этот язык. Операционная система должна быть сравнительно новой версии. Например,
Windows 95 является очень старой, как и Mac OS 9. Даже Windows 98 нельзя назвать новой
операционной системой, хотя некоторые специалисты запускают РНР под ее управлением.
Если вы планируете использовать язык РНР для создания Web-приложений, вам понадобится
применять и язык HTML (HyperText Markup Language). Надеюсь, вы знакомы с этим языком.
Поэтому в книге не поясняются многочисленные примеры использования этого языка. Если вы
не знакомы с языком HTML, прочтите специализированную книгу, а затем попробуйте создать
простую Web-страницу. Если у вас совсем нет терпения, можно приступать к изучению РНР даже
без базовых знаний HTML, Из этой книги вы сможете почерпнуть все сведения, необходимые для
создания своего Web-приложения. Однако на всякий случай положите радом книгу по HTML.
Надеюсь, вам уже приходилось создавать хотя бы одну Web-страницу, а может быть, даже
статический Web-узел. Тогда вы должны знать, где нужно разместить Web-страницу, чтобы
она была доступна пользователям Web.
Книга не предполагает знания каких-либо языков программирования. Эта книга рассчитана
на новичков, которые хотят научиться писать сценарии на языке РНР. Поэтому, если у вас
нет опыта программирования, не печальтесь. В книге вы найдете всю необходимую информацию.
Если же вы умеете программировать на другом языке, особенно на С, эта книга поможет
вам быстро освоить новый язык программирования.
[Gnfiifiantjfia книги]
Материал этой книги делится на шесть частей, в которых изложена вся необходимая информация
о РНР, от основ этого языка до его приложений.
Часть I. "Познакомьтесь с языком сценариев РНР"
В этой части приводится обзор возможностей РНР и принципов его работы. Вы узнаете,
как настроить среду для использования языка РНР и как на нем написать первый сценарий.
Часть II. "Переменные и данные"
Переменные — основа языка РНР. В этой части речь идет о создании и использовании
переменных. Здесь рассказывается о типах данных и способах их обработки. Вы узнаете, как
создавать и использовать сложные переменные, получившие название массивов.
Введение 17
Часть III. "Основы программирования на РНР"
В этой части показано, как писать сценарии на языке РНР, а также изложены основы
объектно-ориентированного программирования на РНР.
Часть IV. "Стандартные РНР-приложения"
В этой части изложены приемы программирования на языке РНР, необходимые при создании
типичных приложений. Вы узнаете, как писать сценарии для Web-узла, отображать
формы и обрабатывать их данные. Вы также научитесь использовать язык РНР для взаи содействия
с базами данных и для выполнения системных задач, в том числе записи файлов на
жесткий диск и выполнения команд операционной системы.
Часть V. "Великолепные десятки"
В этой части содержатся полезные рекомендации о том, что следует делать при написании
сценариев РНР, а чего делать не нужно. Здесь же приводится список полезных Web-ресурсов,
связанных с использованием РНР.
Часть VI. "Приложения"
В этой части приводятся детальные рекомендации по установке РНР. В приложении Б содержится
список функций РНР, которые могут оказаться полезными при создании сценариев РНР.
Лшапог/гамжи, используемые в книге
Для удобства работы с книгой в ней содержатся специальные пиктограммы, определяющие
различные типы информации.
Эта пиктограмма связана с дополнительной информацией по конкретному ио-
просу. Советы позволят сэкономить время и силы, поэтому на них стоит обращать
особое внимание.
Эта пиктограмма сопровождает информацию, которую желательно запомнить.
Обращайте особое внимание на предупреждения! В них описаны действия, которые
нужно выполнить (или, наоборот, которые выполнять не следует)
во-избежание неприятностей.
Эта пиктограмма связана с технической информацией. Она может быть интересной
и полезной, однако не является обязательной для понимания основного
содержания книги.
18 Введете
[Часть I]
Познакомьтесь с языком
сценариев РНР
v4w полный ЬолЪМ, (Члр»лин. Но ыы ^obtpwiHHO Hi
МОИ 00Л6ЛН .
3 э/пой чаани.
рассматриваются основные возможности РНР. Дается описание
этого языка, основных принципов его работы и назначения. После
этого описываются настройки РНР в вашем рабочем окружении и рассматриваются
различные способы доступа к интерпретатору РНР.
Далее предлагается описание процесса разработки на языке РНР. Рассматривается
создание первых сценариев и обсуждается несколько про-
ых примеров.
Глава 1
Знакомство с РНР
в этой главе:
> Обзор особенностей РНР
> Описание работы РНР
> РНР как открытое программное обеспечение
так, вы желаете познакомиться с языком РНР. Возможно, это ваш первый опыт
в программировании. И вы выбрали РНР по совету своего товарища, который сказал
вам, что язык РНР очень простой. Может быть, он и прав, поскольку РНР является одним из
самых легких для понимания языков программирования. И разработчики РНР постоянно
прилагают все усилия, чтобы этот язык оставался несложным в использовании.
Возможно, вы уже имеете опыт программирования на других языках. И вы решили изучить
РНР, поскольку он является наилучшим средством для создания новых Web-
приложений. Это решение заслуживает похвалы, так как РНР — это как раз то, что нужно для
создания динамических Web-приложений. Начать программировать на РНР очень легко. Более
того, РНР предоставляет ряд современных средств, которые будут полезны для опытных
программистов. Если вы знакомы с языком программирования С, то вы уже имеете неплохой
задел, поскольку РНР имеет аналогичный синтаксис.
В этой главе описывается РНР и рассказывается о том, что этот язык позволяет делать
и каким образом.
РНР является широко используемым открытым универсальным языком разработки сценариев.
Первоначально он был создан для разработки Web-узлов. Созданный Расмусом Лердофом
(Rasmus Lerdof), PHP фактически использовался как средство доя создания пользователями своих
Web-страниц (Personal Home Page — персональные домашние страницы). Однако РНР оказался
настолько полезным и популярным, что быстро стал полноценным языком программирования.
При этом он приобрел новое название — Hypertext Preprocessing, — которое отображает его
расширенные возможности по предварительной обработке Web-страниц перед их отображением.
РНР приобрел большую популярность благодаря следующим преимуществам.
/ Быстродействие Web-узлов. Поскольку код РНР встраивается в HTML-страницу,
время, необходимое для обработки и загрузки Web-страницы, невелико.
•S Открытость. РНР является доказательством того, что бесплатные обеды все
же существуют, и вы можете получить больше того, за что платите.
S Простота использования. Синтаксис РНР достаточно прост для понимания
и использования даже для непрограммистов. При этом РНР разработан таким
образом, чтобы быть легко встраиваемым в HTML-страницы.
Универсальность. PHP можно использовать под управлением разных операционных
систем, включая Windows, Linux, Mac OS и большинство систем семейства
Unix.
Многосторонняя техническая поддержка. Вы можете посетить официальный
Web-узел РНР (www.php.net), где предлагается обширный список тем
для обсуждения, покрывающий различные вопросы, такие как основы FHP,
РНР под Windows или базы данных и РНР. К тому же перечень тем для обсуждений
можно найти также по адресу news.php.net.
Безопасность. Если ваш сценарий РНР разработан правильно, то его программный
код пользователи увидеть не смогут.
Настраиваемость. Открытость РНР позволяет программистам модифицировать
программное обеспечение, добавлять или изменять его функциошль-
ность, необходимую для решения конкретных задач. РНР обеспечивает достаточный
контроль над окружением, позволяя уменьшить вероятность ошибок.
[Различные применения PHP]
РНР является универсальным средством разработки сценариев общего назначения. Сценарии
представляют собой компьютерные файлы, которые содержат написанные на языке
РНР инструкции, выполняющие определенные действия, такие как вывод на экран строки
"Привет" или сохранение некоторой информации в базе данных. Большинство сценариев
содержат последовательности инструкций, позволяющих решать задачи, начиная от
разботки Web-страниц до навигации по файловой системе. Поскольку РНР создавался для Web,
он обладает многими возможностями, которые как раз и предназначены для использования
в сценариях создания динамических Web-страниц. Возможно, в данный момент у вас возникнут
трудности при использовании РНР для создания Web-страниц, однако его применение
для других целей трудно переоценить.
РНР является очень популярным средством для разработки Web-узлов. Согласно информации,
размещенной на Web-узле РНР (www.php.net/usage.php), около 11 миллионов
доменов используют РНР. Даже Web-узел Yahoo!, который, вероятно, является самым посещаемым
в мире, решил заменить свой собственный язык создания сценариев на РНР.
Использование РНР для Web-приложений
С самого начала Web-страницы были статическими, т.е. они представляли собой простые
документы. Пользователи посещали Web-узлы, чтобы прочитать нужную информацию.
При этом документы были связаны между собой, так что пользователь мог спокойно найти информацию,
которую он искал. Однако Web-страницы оставались неизменными. Каждый
пользователь, посещающий определенную Web-страницу, всегда видел одно и то же.
Впоследствии разработчики Web-страниц пожелали большего. Они захотели взаимодействовать
с посетителями, получать от них информацию и настраивать Web-страницы под
конкретного пользователя. При этом было разработано несколько языков, позволяющих
создавать динамические Web-узлы. РНР является одним из самых успешных таких языков,
который быстро нашел свое применение и приобрел большую популярность.
РНР является серверным языком (server-side language) для написания сценариев. Это означает,
что сценарий выполняется на сервере (компьютер, на котором установлен Web-узел).
В этом состоит отличие от другого популярного языка для создания динамических Web-
страниц — JavaScript. Сценарий, написанный на JavaScript, выполняется клиентским браузером
Таким образом, JavaScript - клиентский язык (client-side language). Web-серверы
и взаимодействие серверов и клиентов описываются в разделе "РНР для Web" далее в этой главе.
Часть I. Познакомьтесь с языком сценариев РНР
Поскольку сценарий РНР выполняется на сервере, он позволяет динамически генерировать
HTML-код Web-страницы. Таким образом, каждый пользователь может видеть "свою" Web-
страницу. При этом посетитель видит результат выполнения сценария, а не его программный код.
РНР предоставляет ряд возможностей, специально предназначенных для разработки
Web-узлов.
Взаимодействие с HTML-формами. РНР позволяет отображать данные
HTML-форм и обрабатывать информацию, введенную пользователем в браузере.
Взаимодействие с базами данных. РНР позволяет взаимодействовать с базами
данных для хранения информации, введенной пользователем, или извлечения
информации для ее отображения.
•J Создание безопасных Web-страниц. РНР позволяет разработчикам создавать
безопасные Web-страницы, требующие ввода достоверных имени пользователя
и пароля перед выводом содержимого Web-страницы.
Эти и другие возможности РНР позволяют очень легко создавать динамические Web-узлы.
Как уже отмечалось, РНР — серверный язык, который не может взаимодействовать
с пользователем напрямую. Это означает, что невозможно инициировать какие-либо действия,
основываясь на состоянии пользовательского компьютера, например, среагировать на
щелчок кнопкой мыши или уменьшение размера окна. Другими словами, с помощью РНР невозможно
создать такие популярные эффекты, как выпадающее или изменяющее цвет меню.
С другой стороны, JavaScript является клиентским языком написания сценариев, который не
имеет доступа к серверу. Например, с помощью JavaScript невозможно сохранять информацию
на сервере или извлекать ее из серверной базы данных. Но, к счастью, вам ничего не
нужно выбирать. Вы спокойно можете использовать РНР и JavaScript вместе для создания таких
Web-страниц, которые невозможно разработать, используя только один из этих языков.
Вопросам совместного использования РНР и JavaScript посвящена глава 11.
Использование РНР для взаимодействия с базами данных
Существенным преимуществом языка РНР являются его возможности по взаимодействию
с базами данных. РНР поддерживает практически все возможные форматы баз данных, о которых
вам когда-либо приходилось слышать. РНР устанавливает соединение с базой данных
и взаимодействует с ней. При этом вам нет необходимости знать о каких-либо технических
деталях такого взаимодействия. Вы указываете имя базы данных и ее местоположение, а сценарий
РНР сам выполняет все необходимые действия: устанавливает соединение, выполняет
запрос и возвращает результат.
В настоящее время РНР поддерживает большинство известных форматов баз данных:
•
•
•
•
•
•
•
• /
•
dBASE
Informix
Ingres
Microsoft SQL Server
mSQL
MySQL
Oracle
PostgreSQL
Sybase
Глава 1. Знакомство с PHP 23
РНР поддерживает также и другие форматы баз данных, такие как filePro, FrontEase
и InterBase. К тому же РНР поддерживает открытый интерфейс доступа к базам данных
ODBC (Open Database Connectivity), который позволяет взаимодействовать с такими баздми
данных, как Access и ШМ DB2.
РНР идеально подходит для разработки Web-узлов, предназначенных для взаимодействия
с базами данных. PHP-сценарий позволяет сохранять и извлекать информацию из любой поддерживаемой
базы данных. Кроме того, РНР может взаимодействовать с базами данных вне
Web-окружения. Таким образом, работа с базами данных — одно из наилучших свойств РНР.
Использование РНР для взаимодействия с файловой системой
РНР предоставляет все необходимые средства для взаимодействия с файловой систем эй:
с папками и файлами, находящимися на локальном жестком диске или на компьютере, дос :уп
к которому возможен через сеть. РНР позволяет осуществлять запись в файл, считывать их
содержимое и создавать новые файлы. РНР также предоставляет возможности по созданию
папок, копированию, переименованию, удалению или изменению атрибутов файлов, а также
множество других разных операций. Таким образом, язык РНР позволяет выполнять практически
все возможные задачи, относящиеся к файловой системе.
Большинство Web-узлов требует взаимодействия с файловой системой. Например, вэе-
менную информацию Web-приложению целесообразно сохранять в файле, а не в базе данных,
и, следовательно, существует необходимость считывать ее из файла.
Поддержка и администрирование любой программной системы также часто требу от
взаимодействия с файловой системой. Например, РНР-сценарии можно использовать для
создания копий файлов, очистки папок или обработки текстовых файлов для изменения фермата
их содержимого. РНР позволяет справиться с этими задачами очень легко.
Использование РНР для запуска системных команд
Язык РНР предоставляет необходимые средства для взаимодействия с операционной ы :с-
темой, позволяя выполнять системные команды и получать результаты их выполнения. Например,
в сценарии РНР можно использовать команду d i r или I s для получения перечня
файлов в папке.
Возможность взаимодействия РНР с операционными системами является особенно полезной
при решении задач системной поддержки и администрирования. Например, используя
системные команды в сценарии РНР, можно получить список файлов в папке, выбрать, а затем
удалить ненужные файлы с определенным расширением.
Возможность выполнения системных команд позволяет также запускать и другие прэ-
граммы в системе, т.е. с помощью сценариев РНР можно выполнять программы, написа *-
ные на других языках, и использовать результаты их выполнения. Не стало ли вам легче от
того, что не нужно переписывать программы, которые вы используете в настоящее время?
Используя PHP-сценарий, вы можете просто выполнять программы, написанные на Peri,
С или любом другом языке, или запускать сценарии оболочек (shell scripts). Таким образом,
РНР позволяет добавить новую функциональность к системным средствам, не тратя дополнительного
времени на переписывание уже существующих программ.
Л/атциим функционирования PHJ*
РНР является языком программирования высокого уровня. Это означает, что он является
дружественным для пользователей и подобен английскому языку. Однако поскольку компьютер
не понимает английский язык, то для взаимодействия с ним можно использовать РНР.
24 Часть I. Познакомьтесь с языком сценариев РНР
При этом интерпретатор РНР преобразует код сценария в язык, понимаемый компьютером,
который, в свою очередь, и обеспечивает выполнение всех необходимых действий.
Интерпретатор РНР поставляется в двух различных версиях. Первая из них предназначена
для работы с Web-узлами, а вторая — для запуска сценариев из командной строки независимо
от Web. При этом вы можете установить как обе версии, так и одну из них.
РНР как универсальный язык
Если РНР используется в качестве универсального языка написания сценариев, необходимо
установить РНР CLI. Эта версия РНР как раз и была разработана для этих целей. При этом
доступ к интерпретатору РНР осуществляется через командную строку, из которой и происходит
запуск сценариев РНР. Такой подход аналогичен принципам использования многих
других языков программирования, таких как Perl или С. Вопросы, связанные с запуском сценариев
с помощью РНР CLI, более подробно рассматриваются в главе 3.
Как работает World Wide Web
Будет полезным немного рассказать о том, как работает "всемирная паутина", или World Wide Web j
(WWW). Web представляет собой сеть компьютеров, на которых находятся Web-страницы. Количество j
таких Web-узлов достигает миллионов. Для того чтобы было легче найти Web-узел во "всемирной j
паутине", ему присваивается определенный адрес, называемый URL (Uniform Resource Locator —
универсальный локатор ресурсов). URL Web-узла состоит из имен домена и файла, например)
www.mycompany.com/'
w e l c o m e . h t m l . Если пользователь хочет посетить определенную Web-страницу, ему необходимо набрать 1
нужный URL-адрес в браузере. При этом происходит следующий процесс.
|
1. Web-браузер посылает сообщение в Web с запросом на получение необходимой страницы.
2. Сообщение передается компьютеру, который находится по URL-адресу, указанному в запросе.
3. Web-сервер, установленный на удаленном компьютере, получает отправленное сообщение.
4. Web-сервер отыскивает необходимый HTML-файл, имя которого указано в URL-адресе запроса.
5. Отыскав запрашиваемый файл, Web-сервер передает его обратно браузеру, (Если запрашиваемого файла ]
не существует, Web-сервер посылает сообщение об ошибке.)
6. Web-браузер отображает на экране HTML-код полученной Web-страницы.
РНР для Web
Если РНР используется для создания Web-узлов, он должен использоваться совместно
с Web-сервером. Дело в том, что никакой Web-узел не может существовать без Web-сервера.
Web-сервер представляет собой специальное программное обеспечение, предназначенное для
отображения Web-страниц во "всемирной паутине". Поэтому РНР не может не взаимодействовать
с Web-сервером.
При разработке Web-узлов РНР используется в качестве встроенного языка написания сценариев
(embedded scripting language). Это означает, что для размещения кода РНР в HTML-
файле используются специальные дескрипторы HTML, т.е. HTML-страницы, содержащие код
РНР, можно создавать и редактировать таким же образом, как и обычные страницы.
Если модуль РНР установлен на компьютере, то Web-сервер настроен таким образом,
чтобы обрабатывать встроенный PHP-код страниц с определенными расширениями. Зачастую
таковыми являются страницы с расширением .php или .phtml, однако Web-сервер
можно настроить для обработки файлов с любыми расширениями. Получив запрос на получение
файла с определенным расширением, Web-сервер передает обратно HTML-код без каких
бы то ни было изменений. В свою очередь, PHP-код сначала обрабатывается модулем
РНР, а затем результаты его интерпретации также отправляются обратно клиенту.
Глава 1. Знакомство с РНР 25
При этом результат обработки кода РНР возвращается в формате HTML, а сам код FHP
в файл, передаваемый обратно браузеру, не включается. Это существенно повышает безог ясность.
Кроме того, вся обработка выполняется незаметно для пользователя. Рассмотрим следующий
пример кода на РНР:
<?php echo "<р>3дравствуй, мир"; ?>
В этом выражении дескриптор <?php является открывающим, а ?>— закрывают IM.
Оператор echo позволяет выводить текст, в том числе и как HTML-код. Модуль РНР выполнит
обработку этого выражения и выдаст следующий результат:
<р>3дравствуй, мир
Полученная строка содержит обычный HTML-код, который и отсылается клиентскому
браузеру.
Таким образом, очевидно, что РНР и Web-сервер функционируют совместно. Модуль PrIP
можно интегрировать далеко не с каждым Web-сервером, а только с наиболее популярными
из них. Поскольку РНР был разработан в рамках одного из проектов Apache Software Foun iation,
лучше всего его использовать вместе с Web-сервером Apache. Однако модуль РНР можно
использовать и совместно с Microsoft IIS/PWS, iPlanet (в прошлом Netscape Enterpiise
Server) и другими Web-серверами.
Немного о Web-серверах
Программное обеспечение, которое обеспечивает отправку Web-страниц во "всемирную паутину", называется
I Web-сервером (Web server). В настоящее время существует большое количество Web-серверов, но среди них
| наиболее популярным является Apache. Согласно результатам исследований, приведенным на узлих
| www.netcraft.com И www.securityspace.com/s_survey/data/, ОКОЛО 60% Web-узлСБ
| используют Apache. Web-сервер Apache относится программному обеспечению с открытым кодом, т.о.
j бесплатному, и позволяет взаимодействовать со многими операционными системами. Он автоматически
! устанавливается вместе с операционной системой Linux и Mac OS X. Более подробную информацию о Wet-
| сервере Apache можно найти по адресу h t t p d . a p a c h e . o r g . Поскольку язык РНР был разработан Е
j рамках одного из проектов Apache Software Foundation, наилучшим образом он работает именно вместе :
i Web-сервером Apache.
; Однако существуют также и другие Web-серверы. Вторым по популярности является Internet Information Serve r
! (IIS), который используется на около 30% Web-узлов. Разработанный компанией Microsoft, IIS-сервер работает
j только под управлением операционной системы Windows. При этом он устанавливается по умолчанию вместэ
с серверными версиями этой системы. Среди других Web-серверов следует выделить Zeus, NCSA и Sun ONE!.
| Остальные Web-серверы используются не более чем на 2,5% Web-узлов.
О Услеживайfne изменения
Язык РНР относится к программному обеспечению с открытым кодом. Если до сих п эр
вы использовали только коммерческое программное обеспечение, разработанное такими
компаниями, как Microsoft, Macromedia или Adobe, то увидите, что программное обеспечение
с открытым кодом представляет собой нечто совсем иное. Оно обычно разработано различными
программистами, которые занимаются разработкой в свое свободное время для удовольствия
и абсолютно бесплатно. Не существует никакого корпоративного офиса, с которым
можно было бы связаться по каким-либо вопросам, ни менеджера по продажам, который оы
убеждал вас во многих преимуществах разработанного программного обеспечения, ни телефона
технической поддержки, по которому можно было бы позвонить.
Все это звучит так, как будто не существует никакой поддержки РНР, не правда ли? Однако
все обстоит иначе. РНР поддерживается невероятным количеством разработчиков
26 Часть I. Познакомьтесь с языком сценариев РНР
и пользователей. И необходимо постоянно следить за изменениями, так как это является частью
работы как пользователей, так и разработчиков РНР.
Открытое программное обеспечение часто подвергается изменениям, чаще чем один или два
раза в год, как в случае с коммерческим. Оно изменяется в тот момент, когда разработчики считают,
что для этого пришло время, или вследствие возникающих проблем. Когда обнаруживается
серьезная проблема, например изъян в обеспечении безопасности, новая версия, устраняющая
ее, может быть выпущена в течение нескольких дней. При этом вы не получите цветных буклетов
и не увидите красочную рекламу в цветных журналах перед выходом новой версии. Если не
сделать все возможное для получения новой информации, можно пропустить выпуск новой версии
или оставаться в неведении о серьезных проблемах, связанных с текущей версией.
Чаще посещайте официальный Web-узел РНР и постоянно знакомьтесь с приведенной
там информацией. Подпишитесь на рассылку сообщений, которые содержат
достаточно оперативную информацию. Когда вы приступите к использованию РНР,
то большое количество ценной информации по различным вопросам можно будет
найти в своем почтовом ящике. Впоследствии вы сможете помочь многим другим
разработчикам, основываясь на своем собственном опыте. По крайнем мере подпишитесь
на рассылку уведомлений (announcement mailing lists), которые рассылаются
не так часто. Из них можно узнать о серьезных проблемах, найденных в программном
обеспечении, или о выходе новых версий. Это именно то, что вам нужно.
Итак, пока вы не забыли, посетите официальный Web-узел РНР и подпишитесь на различные
новости по адресу www.php.net/mailing-lists.php.
РНР 5
Большинство существенных изменений, внесенных в РНР 5, не касаются общих правил
написания кода. В основном они относятся к вопросам, связанным с производительностью
РНР. Был существенно улучшен механизм Zend (волшебный и скрытый управляющий механизм),
и, как результат, сценарии выполняются теперь намного быстрее и эффективнее.
Большой акцент в РНР 5 сделан на объектно-ориентированном программировании, возможности
которого существенно улучшены по сравнению с версией РНР 4. Создание и использование
объектов осуществляется намного быстрее. Добавлены многие объектно-
ориентированные свойства, включая обработку исключений (exceptions). Программисты,
предпочитающие объектно-ориентированный подход, должны быть довольны изменениями,
внесенными в РНР 5. (Объектно-ориентированное программирование описано в главе 9.)
С выходом РНР 5 изменилось и название интерпретатора РНР. Теперь интерпретатор для
Web называется php-cgi. PHP CLI называется просто php, как php. exe под Windows. Оба
файла можно найти в папке, в которой установлен модуль РНР. До появления РНР 5 обе программы
имели одинаковое имя php. exe, но содержались в разных подкаталогах.
В РНР 5 добавлена поддержка формата баз данных MySQL 4.1 и выше. Однако она не включена
по умолчанию, поэтому поддержку MySQL 4.0 или MySQL 4.1 нужно активизировать после установки
РНР. До версии РНР 5 базы данных MySQL 4.0 и ниже поддерживались автоматически.
В РНР 5 по умолчанию поддерживается расширение SQLite, которое предоставляет быстрые
и простые средства для хранения и получения информации из текстовых файлов (flat files).
Предыдущие версии РНР
Следует знать о существенных изменениях, которые касаются предыдущих версий РНР.
Это связано с тем, что сценарии, написанные для более ранних версий интерпретатора РНР,
могут вызывать проблемы при использовании его более поздних версий. Ниже приведены
самые существенные изменения.
Глава 1. Знакомство с РНР 27
S Версия 4.3.1. Решены проблемы обеспечения безопасности, которые били
обнаружены в версии 4.3.0. Поэтому для поддержки Web-узла не стоит использовать
версии РНР 4.3.0 и ниже.
•S Версия 4.3.0. Внесены существенные изменения в версию РНР CLI, которые
позволяют устанавливать ее по умолчанию при компиляции исходного
кода РНР (этот процесс описан в приложении А). Если версия РНР для командной
строки вам не требуется, то при установке необходимо отключить
соответствующий параметр.
•S Версия 4.2.0. Значением переменной r e g i s t e r _ g l o b a l s по умолчаьию
является Off. Сценарии, написанные с помощью предыдущих версий языка
РНР, могут использовать значение On и, следовательно, будут работать некорректно.
Поэтому целесообразно переписать код сценария так, чтобы оь не
зависел от значения этой переменной.
•S Версия 4.1.0. Введены суперглобальные массивы. Сценарии, использующие
суперглобальные переменные (они рассматриваются в главе 6), не будут п од-
держиваться ранними версиями. До версии РНР 4.1.0 необходимо использовать
массивы старого формата, такие как, например, $HTTP_POST_VARS.
Возможно, к моменту выхода в свет этой книги уже появятся обновления в РНР версии 5.
Однако вряд ли крупные отделы информационных технологий и Web-хостинговые компа! [ии
сразу же этим воспользуются. Всегда помните о нюансах различных версий используемого
программного обеспечения.
28 Часть I. Познакомьтесь с языком сценариев PhP
Глава 2
Настройка программного окружения
В э/ной главе...
> Получение доступа к РНР через Web-серверы хостинговых компаний
> Создание личного Web-узла с нуля
> Тестирование РНР-сценариев
Й ш Ш еперь, когда вы решили использовать язык РНР, первая задача состоит в настрой-
+S й ц* ке рабочего окружения для разработки Web-приложений. Как уже упоминалось,
РНР чаще всего используется для разработки динамических Web-узлов, поэтому данная глава
в основном посвящена настройке РНР для дальнейшего использования на Web-узле. Если вы
планировали использовать РНР только как язык сценариев общего назначения, независимо от
Web, то процесс настройки рабочей среды намного упрощается. Вы можете пропустить разделы,
посвященные настройке окружения для работы в Web, и сразу перейти к разделу
"Настройка РНР для написания сценариев общего назначения".
Haanfiouica Web-остужения
Как говорилось в главе 1, язык РНР для Web-разработки используется в паре с Web-
сервером. Таким образом, для работы Web-узла требуется Web-сервер. При использовании
РНР на вашем узле Web-сервер должен поддерживать обмен информацией со сценариями
РНР. Значит, РНР должен быть установлен на сервере, который удовлетворяет данному требованию.
Окружение узла включает в себя не только Web-сервер и модуль РНР. Приведем
несколько других требований.
•S Компьютер должен быть подключен к Internet.
•S Компьютер должен иметь достаточно ресурсов, таких как дисковое пространство
и память, для управления ожидаемым Web-трафиком.
•S Для работы сценария РНР может понадобиться другое программное обеспечение,
например для управления базами данных.
Вы можете интересоваться или не интересоваться установкой вашего личного окружения,
вы можете считать, что его настройка — это развлечение, или можете думать, что все программы
уже установлены и функционируют. Если вы хотите установить личное Web-
окружение с нуля, то это можно осуществить. Возможно, даже на вашем компьютере уже работает
Web-узел, а вам нужно только обеспечить расширение его функциональности с использованием
языка РНР. Если вы не хотите устанавливать личное Web-окружение, то можете
использовать окружение, установленное и поддерживаемое кем-то другим, например
информационным отделом вашей компании или коммерческими компаниями, которые предоставляют
услуги Web-хостинга. Возможно, вы уже имеете Web-узел, который хотели бы
сделать более динамическим. Язык РНР можно использовать во всех случаях, независимо от
того, сами вы создаете Web-окружение или оно предоставлено кем-то другим.
Другой вариант типичной среды разработки включает как вашу личную Web-среду, так
и поддерживаемую кем-то другим (зачастую разработчики организуют тестирование Webсреды
на своих личных компьютерах, на которых они создают и отлаживают Web-страницы).
Потом, когда все будет работать корректно, Web-страницы пересылаются на корпоративный
Web-узел, который поддерживается информационным отделом или компанией, предоставляющей
услуги Web-хостинга.
Приведем некоторые преимущества использования готового Web-окружения.
•S Это легче, чем настроить свое собственное окружение. Вы только копируете
Web-страницы на другой компьютер. Вам не нужно устанавливать ;ру-
гое программное обеспечение, компьютерное оборудование или решать кэм-
пьютерные проблемы. Кто-то другой сделает все это за вас.
•S Требуется меньше технических навыков работы. Вам необходимо знать
лишь языки программирования в Web, такие как HTML и РНР. При этом не
нужно ничего знать о соединениях Internet, Web-серверах, администрирс ваши
компьютеров и других технических вопросах. Это интересно некоторым
людям, однако далеко не всем.
Преимущества использования собственной Web-среды состоят в следующем.
•S Управляемость. Вы принимаете все решения самостоятельно и можете настроить
Web-среду по своему усмотрению.
•S Доступ. Вы имеете доступ к компьютеру всегда, когда захотите работать
с вашим узлом.
S Стабильность. Вы знаете, что узел будет работать столько, сколько вам нужно.
Вы полностью защищены от ситуации, когда однажды проснувшись, узкае-
те, что компания, которая предоставляла вам услуги хостинга, отошла от ;;ел,
и вам необходимо за два дня переместить ваш узел куда-нибудь в другое местэ.
•S Безопасность. Поскольку вы контролируете Web-среду, то только вы должны
иметь доступ к компьютеру. По мере необходимости его можно заблокиэо-
вать. Если вы пользуетесь услугами хостинговых компаний, то к компьютеру
имеют доступ и другие люди. Один из них может быть тем плохим парнгм,
который завладеет вашими секретами.
Использование существующей Web-среды
Если вы используете Web-среду, настроенную кем-то другим, вам не обязательно нужно
понимать все нюансы процесса установки и администрирования программного обеспечения
Web-узла. Кто-то другой— информационный отдел вашей компании, коммерческие хостпн-
говые компании или ближайший сосед— отвечает за функционирование узла. Их обязш-
ность — предоставить вам возможность работать с Web-узлом, включая РНР. Ваше задача —
лишь написать и установить файлы Web-узла.
Для использования существующей Web-среды вам понадобится следующая информация
от администратора Web-узла.
•S Местоположение Web-страниц. Для того чтобы узел был доступен для всего
мира, Web-страницы должны располагаться в особом месте на компьютере.
Web-сервер, который доставляет Web-страницы во внешний мир, рассчиты за-
ет найти файлы в специальном каталоге. Вам необходимо знать, где находится
этот каталог, и иметь к нему доступ.
S Процесс доставки Web-страниц. Необходимо знать, как установить фашы.
В большинстве случаев вы отправляете файлы с использованием протокола FTP
в надлежащее место. Протокол передачи файлов FTP (File Transfer Protocol) —: то
метод копирования файлов с одного компьютера на другой по сети. В некотор их
30 Часть I. Познакомьтесь с языком сценариев РНР
случаях файлы можно копировать непосредственно или использовать другие
методы доставки Web-страниц. Для установки файлов нужно иметь идентификатор
пользователя (user Ш) и пароль.
S Имя файла, используемое по умолчанию. Когда пользователи вводят в окне
браузера адрес URL, им передается некоторый файл. В настройках Web-
сервера указывается имя файла, отсылаемого по умолчанию, если URL-адрес
указывает на каталог. Зачастую этот файл называется index.htm или
index.html, но иногда он имеет имя d e f a u l t . h t m . Необходимо знать,
как назвать свой файл, передаваемый по умолчанию.
S Расширение файлов РНР. После установки модуля РНР Web-сервер ожидает
встретить операторы РНР в файлах со специальным расширением.
Часто таким расширением является .php или .phtml, но могут использоваться
и другие расширения. Операторы РНР в файлах с некорректным
расширением не будут выполняться. Необходимо знать, какое расширение
нужно использовать для сценариев РНР.
Одним из неудобств хостинга узла в существующей Web-среде является отсутствие контроля
над средой разработки. Администраторы предоставляют Web-среду, которая, по их мнению, работает
лучше всего. Например, модуль РНР имеет бесчисленное количество настроек, которые
можно установить, отменить или инициализировать разными значениями. Администраторы, задавая
значения параметров, руководствуются своими нуждами, которые могут быть оказаться не
столь подходящими для ваших целей. Возможно, такая настройка окружения обоснована легкостью
ее обслуживания, низкой стоимостью и минимальными неудобствами клиента. Вы не
сможете изменить некоторые параметры среды, а можете только просить, чтобы администраторы
изменили их. Они будут неохотно изменять рабочие параметры, поскольку подобная модификация
может привести к проблемам с системой или с другими клиентами.
Выбор хостинговой компании
Хостинговые компании предоставляют все, что нужно для работы Web-узла, включая
дисковое пространство и все программное обеспечение узла. Вы только создаете файлы своих
Web-страниц и перемещаете их в местоположение, указанное хостинговой компанией.
Услуги хостинга предоставляет огромное количество компа
ний. При этом обычно взимается
ежемесячная плата, которая часто является очень маленькой или совсем отсутствует.
Компании, предоставляющие услуги бесплатно, требуют размещения их рекламы на страницах
своих клиентов. Конечно, месячная плата изменяется в зависимости от ресурсов, выделенных
для вашего Web-узла. Например, плата за узел, который занимает 2 Мбайт дискового
пространства, как правило, меньше, чем за узел размером 10 Мбайт.
Убедитесь в том, что хостинговая компания позволяет использовать сценарии РНР
(некоторые этого не делают). Также убедитесь, что компания предлагает последнюю версию
РНР. Хостинговая компания может не поддерживать последнюю версию, которая только выпущена,
но обязана обновить ее незадолго после выхода новой версии.
Не пользуйтесь услугами компаний, которые предлагают поддержку лишь РНР 3.
РНР 4.3.1 был выпущен в феврале 2003 года, поэтому ни одна хостинговая компания
не должна предоставлять РНР более ранних версий, поскольку в РНР 4.3.1
были устранены проблемы с безопасностью, обнаруженные в более ранних версиях.
Остается надеяться, что к моменту выхода в свет этой книги большинство
компаний будет предлагать хостинг РНР 5.
Глава 2. Настройка программного окружения 31
\
Среди других мотивов выбора хостинговой компании следует отметить следующие.
•S Надежность. Вам необходима компания, которой можно доверять и котэрая
завтра не обанкротится и не исчезнет. Выберите компанию, которая имеет необходимые
вычислительные мощности и другие ресурсы для поддержки Bai jero
узла. Узел, который больше простаивает, чем работает, абсолютно бесполезш.
S Скорость. Страницы, которые медленно загружаются, раздражают польз эва-
телей и вынуждают их посетить другие Web-страницы. Медленная загрузка
страниц может быть результатом того, что хостинговая компания мало? юд-
жетна и не имеет хорошего оборудования. В любом случае компании, пгре-
сылающие Web-страницы слишком медленно, не могут представлять ocof ioro
интереса. Поэтому при выборе хостинговой компании следует пойнтер гсо-
ваться скоростью загрузки страниц, которую она обеспечивает. Иногда такая
информация содержится на узле хостинговой компании, в противном ел; чае
ее можно получить у менеджера.
•S Техническая поддержка. Некоторые хостинговые компании не имеют специалистов,
готовых отвечать на вопросы или решать проблемы клиентов.
Техническая поддержка часто обеспечивается только через рассылку по э. гек-
тронной почте. Такой способ может быть приемлем только в том случае, если
ответ предоставляется в кратчайший срок. Иногда качество услуг компании
можно проверить, позвонив по телефону технической поддержки или зас< кая
время ответа по электронной почте.
S Доменное имя. Каждый узел имеет свое доменное имя, с помощью которого
Web-браузеры находят его в сети. Каждое имя домена регистрируется за небольшую
ежегодную плату, так что пользоваться им может только один у (ел.
Одни хостинговые компании разрешают независимо использовать зарегистрированное
вами доменное имя; другие помогают с регистрацией и использованием
нового имени домена, а третьи требуют использовать их домен яое
имя. Например, допустим, что ваша компания называется Good Stuff и вы хотите,
чтобы узел назывался JanetsGoodStuff. Одни компании разрешат назвать
ваш узел JanetsGoodStuff . com, а другие потребуют, чтобы узел имел имя
JanetsGoodStuff.Web-hostingcompanyname.com, или JanetsGoodStuff
.Web-hostingcompanyname . com/~GoodStuf f, или что-то в этом
роде. Вообще-то, узел будет выглядеть более профессионально, если вы будете
использовать собственное доменное имя.
•/ Свойства. Свойства следует выбирать в зависимости от назначения у:ла.
Обычно хостинговая компания предлагает определенные возможности в пакетах
или планах. Но чем больше возможностей, тем выше цена. Некоторые
свойства, которые следует рассмотреть, приведены ниже.
• Дисковое пространство. Как много (Мбайт/Гбайт) места на диске займет
ваш узел? Медиа-файлы (графика и музыка) могут занимать действительно
много дискового пространства.
• Передача данных. Некоторые хостинговые компании взимают плату за
отправку Web-страниц пользователям. Если вы рассчитываете на интенсивный
трафик, то эти затраты следует принять во внимание.
• Адреса электронной почты. Многие компании обеспечивают своих клиентов
некоторым количеством адресов электронной почты. Например, гели
ваш узел называется JanetGoodStuff.com, вы можете позволить
своим посетителям писать по адресу me@JanetGoodStuf f . com.
32 Часть I. Познакомьтесь с языком сценариев РНР
• Программное обеспечение. Хостиговые компании предлагают доступ к
множеству программных продуктов для разработки Web-приложений.
Помимо РНР, который является предметом рассмотрения этой книги, некоторые
компании предлагают базы данных, такие как MySQL или
PostgreSQL, другие средства Web-разработки, такие как FrontPage, программы
разработки электронных магазинов, проверки правильности данных
кредитных карточек и т.д.
• Статистика. Часто компании помогают своим клиентам собрать статистику
о Web-трафике на вашем узле, сведения о количестве пользователей,
времени доступа к Web-странице и т.д.
•S Резервное копирование. Резервные копии (backup) — это копии файлов ваших
Web-страниц и баз данных, которые хранятся на случай потери или повреждения
файлов или базы данных. Нужно удостовериться в том, что компания
регулярно и часто делает резервные копии приложений своих клиентов.
При этом следует также поинтересоваться, как быстро ваш узел перейдет из
резервных копий в рабочий режим при возникновении какой-либо проблемы.
Хостинговые компании сложно исследовать с нуля— поиск в Google на запрос "webhosting"
выдает около 4 миллионов результатов. Наилучший путь для выбора хостинговои
компании — попросить рекомендации у людей, имеющих опыт работы с этими компаниями.
Люди, которые пользовались услугами хостинговых компаний, могут предостеречь вас от услуг
компаний с медленным сервисом или неустойчивой работой компьютеров. Собрав сведения
о нескольких хостинговых компаниях, услугами которых довольны их клиенты, вы можете
сузить этот список до одной, которая вам больше подходит.
ЧЙ—*j? Игра "доменное имя"
Каждому узлу необходим уникальный адрес в сети. Он используется компьютерами для нахождения узла и
называется IP-адресом. Это последовательность из четырех чисел от 0 до 255, разделенных точками,
например 1 7 2 . 1 2 . 2 0 4 . 2 .
Так как IP-адрес — это комбинация цифр и точек, их тяжело запомнить. К счастью, большинство IP-адресов
имеет соответствующие имена, которые намного легче запомнить, например amazon. com, www. i r e . g v
или mycompany. com. Имя, которое соответствует адресу узла, называется доменным именем (domain
name). Доменом может быть как один компьютер, так и группа компьютеров, связанных между собой. Если
домен состоит из нескольких компьютеров, то каждый из них может иметь свое имя. Имя, которое включает в
себя собственное имя компьютера, такое как thor.mycompany.com, называется лоддоменом
(subdomain) домена mycompany. com.
Имя домена или поддомена является неотъемлемой частью URL-адреса, который пользователь вводит в окне
браузера для определения Web-узла, который он хочет посетить. URL-адрес может содержать больше
составляющих, нежели просто имя домена, но зачастую имя домена (например, amazon.com) —это все,
что нужно. Иногда достаточно имени поддомена ( j a n e t . v a l a d e . com). Если используется только имя
домена, то Web-сервер передает файл с именем по умолчанию ( i n d e x . h tm или i n d e x , h t m l ) . Иногда в
адрес кроме имени домена включают также имя файла, например j a n e t . v a l e d . c o m / l i n k s . h t m l .
Для того чтобы имя домена могло служить адресом, оно должно быть уникальным в Internet. Тогда система
регистрации доменных имен сможет удостовериться в том, что нет двух узлов с одинаковыми именами. Каждый
клиент может зарегистрировать любое имя домена, если это имя еще никем не используется. При
регистрации имени домена вы проверяете его на наличие в сети. Если все в порядке (имя уникально), вы
регистрируете его на свое имя или на имя компании и платите взнос. Обычная плата за регистрацию доменного
имени составляет 35 долларов в год. Обычно больше платить не приходится, а вот поторговаться можно.
Глава 2. Настройка программного окружения 33
Доменное имя можно зарегистрировать на многих Web-узлах, включая множество хостинговых компании.
Поиск в Google по запросу "регистрация доменного имени" дает около 2 миллионов результата, i
Удостоверьтесь, что вы нашли самую низкую цену. Многие узлы позволяют по доменному имени узнать, за
кем оно закреплено. Эти Web-узлы используют поиск в базе данных доменных имен с помощью команды ,
whois. Такой поиск можно организовать на узлах Allwhois (Allwhois.com) и Better-Whjis j
i (betterwhois.com).
Об именах можно спросить у коллег или друзей. На PHP-форумах посетители
часто задают вопросы о хостинговых компаниях. Многие посетители форумов
имеют богатый опыт использования РНР с хостинговыми компаниями и будут
рады вам помочь. Поскольку подобные вопросы возникают очень часто, то соответствующую
информацию можно поискать и в архивах, расположенных по адресу
marc . theaimsgroup. com/.
Настройка собственного Web-окружения
Если вы начинаете разработку Web-узла с нуля, нужно хорошо понимать структуру гро-
граммного обеспечения. Необходимо принять несколько решений относительно аппаратного
и программного обеспечения. Потребуется установить Web-сервер и модуль РНР, а затем самостоятельно
поддерживать, администрировать и обновлять систему. Такой путь требует
больше усилий и знаний.
Приведем основные действия по настройке Web-окружения, необходимой для работы
программ, описанных в этой книге.
1. Настройте компьютер.
2. Установите Web-сервер.
3. Установите модуль РНР.
Первый шаг здесь мы рассматривать не будем. Наверняка у вас есть компьютер, но вгол-
не возможно, что для развертывания своего Web-узла вы планируете использовать (или приобрести)
другой компьютер. Более подробную информацию относительно компьютеров
можно найти в книге ПК для "чайников", 9-е издание, которая вышла в издательстве
"Диалектика". Web-серверы и модули РНР существуют почти для всех типов аппаратных
средств и операционных систем, включая множество версий Unix и Linux, Windows и MacOS.
Установка Web-сервера
Если компьютер уже куплен и настроен, следует решить, какой Web-сервер устанав пивать.
Наилучший выбор — это, конечно же, сервер Apache, поскольку он имеет ряд следующих
преимуществ.
•S Бесплатный. Что еще можно добавить к этому?
•S Работает с разными операционными системами. Сервер Apache работает
под управлением систем Windows, Linux, MacOS, FreeBSD и большинства
версий Unix.
S Популярность. Согласно исследованиям, результаты которых приведены по адг есу
www.netcraft.com/survey и www.securityspace.com/s_survey/data/,
на 60% узлов используется Web-сервер Apache. И это действительно так. !Это
также означает, что при возникновении проблем вам сможет помочь болытое
количество пользователей.
34 Часть I. Познакомьтесь с языком сценариев РНР
•f Надежность. После установки и настройки сервер Apache будет работать
столько, сколько проработает ваш компьютер. Проблемы с этим сервером
возникают очень редко.
•/ Возможность настройки. Открытый исходный код дает возможность программистам
модифицировать сервер Apache, добавляя или модифицируя модули
по своему усмотрению.
•/ Безопасность. Существует бесплатное программное обеспечение, которое
позволяет настроить Apache для работы с сервером безопасности SSL. Протокол
SSL применяется для обеспечения повышенной безопасности Web-узлов,
использующих очень важную информацию. Это значит, что информация, передаваемая
между Web-сервером и браузером, шифруется, поэтому никто не
сможет перехватить и прочитать ее. Безопасность — необходимый компонент
для узлов электронной коммерции.
Сервер Apache автоматически устанавливается при установке полной версии системы Linux.
Кроме того, Apache обычно входит в состав операционной системы Мае. Для большинства версий
Unix можно самостоятельно скачать ядро Apache и скомпилировать его, а можно использовать
двоичные файлы (binary) (скомпилированные программы для определенных операционных
систем). Если вы работаете с операционной системой Windows, вам необходимо установить бинарный
файл (в основном Apache предназначен для работы с операционными системами
Windows NT/2000/XP, хотя иногда его используют и в системах Windows 98/Ме).
Как уже говорилось, наиболее стабильной текущей версией является Apache 1.3.27.
Apache 2 — это также стабильная версия, но до сих пор модуль РНР работает с ней в экспериментальном
режиме. Однако в любом случае обратитесь на узел www. php. n e t и проверьте
текущее состояние дел по этому вопросу. Информацию о сервере Apache, загрузочные модули,
документацию, рекомендации по установке в различных операционных системах
можно найти по адресу h t t p d . apache. org.
Для работы с языком РНР вполне подойдут и другие Web-серверы. Компания Microsoft
предлагает сервер IIS (Internet Information Server), который занимает второе место по популярности
в сети Internet: на нем работает около 27% Web-узлов. Компания Sun предлагает
сервер iPlanet (раньше он назывался Netscape Enterprise Server), который обслуживает менее
5% узлов глобальной сети.
Установка модуля РНР
Многие компьютерные системы поставляются вместе с модулем РНР. Он включен в состав
большинства дистрибутивов Linux. Некоторые более новые версии операционной системы
Mac OS X тоже поставляются вместе с модулем РНР. Перед тем как установить этот модуль,
проверьте, не был ли он установлен на вашем компьютере ранее. Для этого поищите на диске
PHP-файлы. В различных операционных системах это можно сделать следующим образом. I S Linux/Unix/Mac. В командной строке введите команду
find / -name "php*"
S Windows. Воспользуйтесь средством поиска (выберите команду Пуск^Поиск)
для нахождения файлов по шаблону php*.
Если вы не нашли PHP-файлов, значит, модуль РНР отсутствует. Для его установки потребуется
доступ к Web-серверу вашего узла. Например, если вы устанавливаете РНР для
работы с сервером Apache, нужно отредактировать его конфигурационный файл. Всю
необходимую информацию и требуемые программные модули можно найти на узле
www. php. n e t . Подробные указания по установке приведены в приложении А.
Глава 2. Настройка программного окружения 35
Если же РНР-файлы нашлись, значит, модуль РНР уже установлен и переустанавли *ать
его не нужно. Чтобы определить, нужно ли переустанавливать модуль РНР, воспользуйтесь
следующими рекомендациями.
| S Параметры установки. Модуль РНР может быть установлен не с теми п ара-
метрами, которые нужны именно вам. Например, он может быть устаноглен
без поддержки базы данных, которую вы планировали использовать. Обь: чно
при установке модуля РНР по умолчанию включен режим поддержки ODBC,
но параметры поддержки MySQL, Oracle, MS SQL и других баз данных ел ;ду-
ет задавать в явной форме. Аналогично, при установке РНР всегда обеспечивается
поддержка SQLite, XML, COM, FTP и т.д., но поддержка других форматов
по умолчанию отключена. Если вы планируете использовать другую
базу данных или программное обеспечение, то, видимо, следует переустановить
модуль РНР с поддержкой дополнительных возможностей.
Можно проверить, какие настройки использовались при установке модуля
РНР. Для этого следуйте рекомендациям по тестированию, приведенным
в следующем разделе. Если тестовый сценарий работает корректно, то в таблице,
которую выведет функция phpinf о (), будут приведены все режимы,
которые поддерживаются вашей версией РНР. Проверьте, включена ли поддержка
нужных вам расширений. Если нет, следует переустановить модуль
РНР. Подробные указания по установке приведены в приложении А.
S Версия. Установленная версия может оказаться не самой новой. Следует проверить
номер установленной версии модуля РНР. Сделать это можно с пс мощью
команды
php-cgi -v
Для версий, более ранних, чем РНР5, эта команда имеет следующий вид:
php -v
Чтобы использовать одну из этих команд, следует перейти в каталог, содержащий
файл php-cgi.exe (или php.exe). В результате вы увидите следующую
информацию:
РНР 5.0.0 (cgi-fcgi), Copyright (с) 1997-2003 The PHP Grotp
Zend Engine v2.0.0. Copyright (c) 1998-2003 Zend Technologies
Если установленная ранее версия оказалась не самой новой, модуль РНР следует
переустановить. Более подробную информацию о его последней вер;ии
можно найти по адресу www. php. n e t /downloads . php.
Тестирование РНР
После того как получена вся необходимая информация, следует протестировать модуль
РНР и убедиться в корректности его работы.
1. Найдите папку, в которой будут размещаться сценарии РНР.
Именно в этой папке и ее подпапках будут храниться файлы вашего узла. Обычно три
использовании сервера Apache эта папка по умолчанию называется htdocs. Она содержится
в папке, в которой установлен Web-сервер. Для сервера IIS — это папка
lnetpub\wwwroot. В системе Linux это может быть каталог /var/www/html. При
установке Web-сервера можно указать любое имя папки, поэтому если Web-серзер
устанавливал кто-то другой, необходимо узнать имя папки, используемой для хранения
файлов РНР. Если вы пользуетесь услугами хостинговой компании, она долхна
предоставить вам имя этой папки.
36 Часть I. Познакомьтесь с языком сценариев РНР
2. Создайте файл с именем t e s t .php и добавьте в него следующий код:
<html>
<head>
<title>Tec™poBaHne PHP</title>
</head>
<body>
<р>Это строка HTML
<?php
echo "<р>Это строка РНР</р>";
phpinfо();
?>
</body>
</html>
3. Укажите в браузере URL-адрес файла t e s t . p h p , который был создан при выполнении
п. 2.
URL будет иметь вид h t t p : / / w w w . m y c o m p a n y . c o m / t e s t . p h p . Если же Web-
север, модуль РНР и сам файл находятся на локальном компьютере, можно ввести
URL-адрес l o c a l h o s t / t e s t .php.
A^'g^N Чтобы файл обрабатывался интерпретатором РНР, нужно получить доступ к нему
через Web-сервер, а не с помощью команды меню браузера Ж ФайлООткрыть.
В результате в окне браузера вы увидите следующее:
Это строка HTML
Это строка РНР
Под этими строками должна появиться большая таблица, отображающая всю информацию
о РНР в вашей системе. В ней будут содержаться пути и имена файлов, значения переменных,
поддерживаемое программное обеспечение и значения различных параметров.
Эта таблица создается функцией сценария p h p i n f о ( ) . Если у вас возникнут вопросы по
поводу настройки модуля РНР, всегда можно воспользоваться этой функцией, чтобы отобразить
таблицу и проверить установки. Функция p h p i n f о () будет часто использоваться в этой книге.
Если с установкой модуля РНР возникли какие-либо проблемы, то в результате выполнения
тестового сценария можно получить следующую информацию.
•S Выводится только текст Это строка HTML. Строки РНР и таблица не отображаются.
•S Отображается пустая страница.
•/ Браузер не отображает Web-страницу.
Если при запуске тестового файла возникли проблемы, а вы не являетесь системным администратором,
то нужно поговорить с тем, кто устанавливал и поддерживает программное
обеспечение. Это их работа — диагностировать и решать подобные проблемы.
Если же вы системный администратор и у вас возникла проблема с тестовым файлом, то
сначала проверьте, установлен ли модуль РНР. В командной строке перейдите в каталог,
в котором установлен модуль РНР, и введите команду
php-cgi -v
или
php -v
Глава 2. Настройка программного окружения 37
Если интерпретатор РНР возвращает информацию о своей версии, значит, он установ, [ен.
Убедитесь в том, что вы обращаетесь к тестовому файлу именно так, как описано в п. 3.
Удостоверьтесь, что тестовый файл находится в вашем дисковом пространстве, как списано
в п. 1. При использовании сервера Apache можно просмотреть файл httpd.conf
и проверить правильность строки
DocumentRoot "С:/Program Files/Apache Group/Apache/htdocs"
Эта строка указывает серверу Apache, где искать файлы Web-страниц.
Еще раз убедитесь в правильности кода. Тестовый сценарий можно загрузить с Web-) зла
автора этой книги — j a n e t . v a l a d e . com.
Если же сценарий написан правильно и пути заданы корректно, то проблема, скорее псе-
го, в конфигурационных параметрах модуля РНР. Просмотрите инструкции по настройке модуля
РНР в конце приложения А и удостоверьтесь в том, что вы следовали всем указаниям.
Особенно проверьте следующее.
•S Web-сервер настроен так, что по расширению определяет файлы с кодом Р IP.
Проверьте, что файл h t t p d . conf содержит строку
AddType a p p l i c a t i o n / x - h t t p d - p h p .php
•S Эта строка указывает серверу Apache, что код РНР следует искать в файаах
с расширением . php. Для сервера ES нужно получить доступ к консоли, как
описано в приложении А, и проверить список расширений.
S Проверьте корректность других строк в файле httpd.conf, как описшо
в рекомендациях в приложении А. Удостоверьтесь также, что необходимые
строки содержатся в нужных местах.
•S Если вы используете сервер IIS, найдите в файле php. i n i следующую строку:
cgi.force_redirect = О
S Если в файле php. i n i нет такой строки — добавьте ее. Если она есть, но перед
ней стоит точка с запятой, удалите этот символ. Если в этой строке укгза-
но значение 1 — замените его на 0.
Если вы все тщательно проверили, но проблема не исчезла, возможно, у вас что-то необычное
с настройками компьютера или Web-сервера. Прочтите всю информацию о комт потере,
которая имеет отношение к установке модуля РНР, а также о проблемах, которые мо :ут
возникать при его установке.
Если проблема по-прежнему существует, отправьте свой вопрос в одну из групп новостей.
Сначала просмотрите архивы по адресу marc . theaimsgroup. com/. Возможно, кто-то )же
задавал этот вопрос, и вы сможете быстро найти ответ в архивах. Если нет — отправьте вопрос
на форум. Включите в свой вопрос следующую информацию.
•S Укажите название и версию операционной системы, которую вы используете.
•S Укажите версию РНР, которую вы пытаетесь установить.
S Скопируйте содержимое тестового файла в письмо.
S Опишите точный результат, который вы видите на Web-странице.
Как правило, участники форума являются очень эрудированными специалистами. Они 18-
верняка помогут решить все проблемы.
38 Часть I. Познакомьтесь с языком сценариев РНР
Hactflftoutca THJ* qj& написания
cu^Haftuetf общего назначения
PHP можно использовать как самостоятельный язык программирования общего назначения.
В этом случае устанавливать Web-сервер не нужно. Версия РНР для командной строки
— РНР CLI — является отдельной программой, которая не используется для поддержки
Web-узлов. Ее необходимо установить отдельно.
Даже если на вашей машине уже установлен модуль РНР, версия РНР CLI на ней может
отсутствовать. Проверьте, установлен ли на вашем компьютере модуль РНР и какой версии.
Поищите соответствующий файл в каталоге РНР. Исполняемый файл РНР CLI называется
php.exe, a PHP CGI— php-cgi.exe. (В версиях до РНР 5 оба файла назывались
php. ехе, которые хранились в различных подкаталогах. РНР CLI размещался в подкаталоге
/ c l i . ) Возможно, версия РНР CLI была установлена в каком-нибудь другом месте. Все файлы
РНР на жестком диске можно найти с помощью следующей команды.
•S Linux/Unix/Mac. Введите в командной строке следующую команду:
f i n d / -name "php*"
•S Windows. Используйте средство поиска (выберите команду ПускО Поиск)
и в качестве шаблона поиска введите строку php*.
Если вы нашли файлы РНР, которые, по-вашему мнению, могут относиться к РНР CLI,
перейдите в каталог, где находятся эти файлы, и введите следующую команду:
php -v
На экране появится следующая строка, содержащая фрагмент cgi или c l i :
РНР 5 . 0 . 0 ( c l i ) ( b u i l t : Jun 15, 2003 23:07:34)
Обратите внимание на то, что в данном случае в строке содержится фрагмент ( c l i ) . При
проверке версии интерпретатора для Web, в результирующей строке будет содержаться
фрагмент (cgi). Указанная команда может также использоваться для проверки корректности
работы программы РНР CLI. Если в результате выводится номер версии, а не сообщение
об ошибке, значит, программа работает правильно.
Если вы не нашли версию РНР CLI, ее нужно установить. Только после этого вы сможете
использовать РНР для решения задач, не связанных с Web. В приложении А детально описана
процедура установки РНР, включая инструкции и для установки РНР CLI.
Если вы собираетесь использовать РНР как для разработки Web-узлов, так и для создания
сценариев общего назначения, необходимо установить две различные PHP-программы —
версию для Web и версию РНР CLI. Обе программы должны быть одинаковой версии, т.е. если
вы устанавливаете РНР 5.0.0 для Web, убедитесь, что вы также используете РНР CLI 5.0.0.
В системе Windows для работы РНР требуется файл p h p 5 t s . d l l , который находится
в главном каталоге РНР. Необходимо использовать одинаковые версии РНР, чтобы обе РНР-
программы могли работать с одним файлом php5ts . d l l . (Более детальная информация по
этому вопросу содержится в приложении А.)
Hacfnftoutca THJ*
Модуль РНР характеризуется чрезвычайной гибкостью. Поведение интерпретатора РНР
определяется конфигурационными параметрами. Например, именно эти параметры определяют
режим отображения сообщений об ошибках. Конфигурационные параметры хра-
Глава 2. Настройка программного окружения 39
нятся в файле php. i n i . Редактируя этот файл, можно вносить изменения в конфигурационные
параметры.
Как описывается в приложении А, при установке модуля РНР создается файл php. i ai.
Если вы устанавливаете РНР самостоятельно, запомните местоположение этого файла. Еоз-
можно, позже вам понадобится его изменить. Если вы только используете модуль РНР, а кто-
то другой является его администратором (например, если вы пользуетесь услугами хостин го-
вой компании), вы вряд ли будете иметь доступ к файлу php. i n i . Если вам нужно измен 1ть
параметры модуля РНР, необходимо попросить об этом администратора. В некоторых случаях
можно добавить соответствующие команды в свой сценарий, чтобы временно измен тгь
настройки только для этого сценария. Определенные операторы, которые временно измеш ют
настройки РНР, обсуждаются в различных главах этой книги.
использование специальных cfteqctn?
создания, PHT-cu^Hafiuee
PHP-сценарии— это простые текстовые файлы. Значит, при их создании можно пользоваться
любыми известными средствами работы с текстовыми файлами. Множество сценариев
написано с использованием редакторов vi, Notepad или WordPad. Кроме того, существуют
средства, которые существенно облегчают весь процесс разработки.
Заслуживают внимания редакторы для создания программ и интегрированные среды
разработки ШЕ (Integrated Development Environment). Эти средства предоставляют возможности,
которые могут уберечь вас от огромных затрат времени в процессе разработ <и.
Загрузите некоторые демонстрационные версии программ, испытайте их и выберите наиболее
подходящую. Время, потраченное на поиск и выбор редактора, вы с лихвой наверстаете
впоследствии.
Редакторы для написания программ
Такие редакторы предоставляют богатые возможности для написания программ. Большинство
подобных программных средств предоставляют следующие возможности.
•S Выделение цветом. Цветовое выделение частей сценария, таких как дескрипторы
HTML, строки текста, ключевые слова и комментарии, позволяет лег ко
ориентироваться в коде программы.
•S Структурированное расположение текста. Автоматический отступ внутри
скобок облегчают чтение сценариев.
S Нумерация строк. Добавление временной нумерации строк упрощает рабе ту
над ошибками, поскольку в сообщениях об ошибках указывается номер строки
сценария РНР. Самостоятельно сложно отсчитать 872 строки от начгла
файла и найти ту, в которой была обнаружена ошибка.
•S Работа с несколькими файлами. Можно работать с несколькими файлами
одновременно.
S Простота вставки кода. Многие редакторы содержат кнопки для вставки
фрагментов кода, таких как дескрипторы HTML или операторы и функции РНР.
S Библиотека фрагментов кода. Фрагменты своего кода можно сохрани-ь,
а затем вставить в сценарий одним щелчком мышью.
40 Часть I. Познакомьтесь с языком сценариев Pt'P
В Internet содержится много бесплатных или недорогих редакторов. Среди наиболее популярных
можно выделить следующие.
•S Arachnophilia (www.arachnoid.com/arachnophilia/). Этот мультип-
латформенный редактор написан на языке Java и относится к бесплатному
программному обеспечению.
S BBEdit (www.barebones . com/products/bbedit/index, shtml). Этот
редактор предназначен для использования на компьютерах Мае. Редактор
BBEdit стоит 179 долларов. Существует бесплатная версия этого редактора
BBEdit Lite. Его развитие и поддержка были прекращены, однако редактор
все еще можно найти и легально использовать. В качестве замены BBEdit Lite
предлагается редактор TextWrangler, который стоит всего 49 долларов.
•S EditPlus (www.editplus.com). Этот редактор разработан для использования
на машинах под управлением операционной системы Windows.
EditPlus — условно-бесплатная программа, лицензия на использование которой
стоит 30 долларов.
•S Emacs (www.gnu.org/software/emacs/emacs.html). Редактор Emacs
работает под управлением систем Windows, Linux и Unix и относится к бесплатному
программному обеспечению.
•f HomeSite (www.macromdia.com/software/homesite/). Редактор HomeSite
предназначен для использования под управлением системы Windows и стоит
99 долларов.
V HTML-Kit (www.chami.om/html-kit/). Это еще один редактор для
Windows, который можно использовать бесплатно.
•S vim и gvim: (www.vim.org/). Эти бесплатные улучшенные версии редактора
v i можно использовать в операционных системах Windows, Linux, Unix
и MacOS. Редактор gvim имеет графический пользовательский интерфейс,
который позволяет пользователям Windows чувствовать себя как дома.
Интегрированная среда разработки
Интегрированная среда разработки (Integrated Development Environment — ШЕ) — это
целостное рабочее пространство для разработки приложений. Наряду с другими средствами
она включает редактор для написания программ. Необходимо отметить следующие возможности,
которыми обладает большинство ШЕ.
•S Средства отладки. Содержит встроенные возможности по отладке программного
кода.
•S Предварительный просмотр. Обеспечивает отображение Web-страницы, генерируемой
сценарием.
S Средства тестирования. Имеет встроенные средства тестирования сценариев.
•S FTP. Имеет встроенную поддержку протокола FTP и его использования для
загрузки файлов. Позволяет отслеживать файлы, относящиеся к Web-узлу,
и обновлять его содержимое.
•S Управление проектом. Организует сценарии в проекты; управляет файлами
проекта, включая отладку файлов и их регистрацию.
•S Резервное копирование. Периодически (автоматически) создает резервные
копии Web-узла.
Глава 2. Настройка программного окружения 41
Интегрированные средства разработки более сложны в изучении, чем обычные редакторы.
Некоторые из них довольно дороги, но множество их преимуществ стоят этих денег.
Интегрированная среда разработки особенно полезна, когда сценарии для одного проекта
разрабатываются несколькими программистами. Интегрированная среда разработки существенно
упрощает координацию проектов и обеспечивает совместимость кода.
Отметим некоторые популярные интегрированные среды разработки.
| S Dreamweaver MX (www.macromedia.com/dreamweaver). Эта интегрированная
среда разработки доступна для платформ Мае и Windows. Она обеспечивает
визуальные средства макетирования, позволяя создать Web-
страницу, перетягивая элементы с панели инструментов и щелкая на COOTI ет-
ствующих кнопках. Dreamweaver может самостоятельно написать HTML- сод
вместо вас. Она включает редактор HomeSite, поэтому вы можете написать
свой собственный код, а также поддерживает язык РНР. Стоимость
Dreamweaver — 399 долларов.
S Komodo (www.activestate.com/Products/Komodo/). Komodo существует
для платформ Windows и Linux. Это интегрированная среда разрабо' жи
с использованием языков с открытым кодом, включая Perl, Python, а таьже
РНР. Стоимость этой системы— 29,95 доллара для использования в личных или
образовательных целях и 295 долларов — для коммерческого использования.
•S Maguma (www.maguma.com). Maguma доступна только для Windows. Это
интегрированная среда разработки с использованием Apache, PHP и MySQL
под управлением операционной системы Windows. Она поставляется в дгух
версиях, Maguma Studio Desktop и Maguma Studio Enterprise, имеющих разн/ю
стоимость, и предоставляет средства разработки очень больших узлов с несколькими
серверами. Maguma Studio для РНР— это свободно распространяемая
версия с поддержкой только языка РНР.
S PHPEdit (www.phpedit.net/products/PHPEdit/). Эта бесплатная кн-
тегрированная среда разработки доступна только для системы Windows.
•/ Zend Studio (www. zend.com/store/products/zend-studio.ph? ).
Zend Studio предназначена для использования в системах Windows и Linux.
Эта интегрированная среда разработки была написана людьми, которые создали
механизм Zend — ядро РНР. Цена Zend Studio — 195 долларов.
Web-страницу с описанием редакторов и интегрированных сред разработки, которые
можно использовать для создания сценариев РНР, можно найти по адресу
p h p e d i t o r s . l i n u x b a c k u p . c o . u k . В настоящее время в списке содержится описание
111 редакторов.
42 Часть I. Познакомьтесь с языком сценариев РНР
Глава 3
Создание первого сценария РНР
Вэ/ной гла&е...
> Операторы языка РНР
> Включение фрагментов РНР в файлы HTML
> Операторы РНР для вывода данных
> Документирование сценариев
ператор языка РНР — это инструкция, которая указывает интерпретатору РНР, какие
действия нужно выполнить. PHP-сценарий— это последовательность операторов
РНР. Теоретически сценарий может содержать один или несколько операторов, но вряд ли
какой-либо сценарий будет состоять из единственного выражения. В большинстве случаев
сценарии включают по несколько операторов в строке. Интерпретатор РНР выполняет операторы
по-одному до тех пор, пока не достигнет конца сценария.
Как уже упоминалось в главе 1, РНР обеспечивает множество возможностей, а сценарии позволяют
объяснить интерпретатору РНР, что вы хотите. Вы можете вывести текст на Web-страницу
или сохранить данные, которые вводятся пользователем в форму на Web-странице. РНР также может
выполнять действия, которые не свойственны Web-узлам, например записывать файлы в каталог
на жестком диске. Можно написать простой сценарий, который вьводит приветствие в окне
Web-браузера. Можно создать сложный сценарий, который выводит в окне браузера разный текст
для разных людей, запрашивает пароль у посетителей Web-узла или отказывает в доступе тем
посетителям, которые не ввели нужный пароль. Приложение часто состоит из двух или нескольких
сценариев, которые совместно выполняют требуемые действия. Большие, сложные
приложения, такие как приложения электронной коммерции, могут состоять из многих сценариев.
В этой главе речь пойдет о том, как написать собственный сценарий. Мы обсудим операторы
вывода, которые чаще всего встречаются в сценариях РНР. И, наконец, будет продемонстрирована
важность документирования сценариев.
Написание onefiatfiofioe !PH!P
Оператор РНР определяет, какие действия необходимо выполнить. Одним из наиболее
популярных операторов РНР является echo. Он предназначен для вывода информации. Рассмотрим
следующий пример использования оператора echo:
echo "Привет";
Оператор echo выводит все, что находится между двойными кавычками (""). Поэтому
в данном случае отобразится строка Привет.
Оператор echo является простым (simple statement). Все простые операторы в языке РНР
заканчиваются точкой с запятой (;). Интерпретатор РНР считывает простые операторы до
тех пор, пока не встретит символ ; (или закрывающий дескриптор, который рассматривается
далее в этой главе). При этом все пробелы игнорируются. Не имеет значения, сколько считано
строк, каков смысл или синтаксис оператора. Все содержимое сценария просто считывает-
ся до точки с запятой и интерпретируется как один оператор.
О
Отсутствие точки с запятой является распространенной ошибкой, в результате которой
выводится сообщение об ошибке. Оно может выглядеть следующим образом:
Parse error: expecting ' , ' " or ' ; ' ' in file.php on line 6
Обратите внимание, что в сообщении указывается номер строки, где содержится ошибка.
При этом строка, в которой пропущена точка с запятой, является предыдущей по отношеь ию
к указанной в сообщении, т.е. в данном случае точка с запятой отсутствует в пятой строке.
Для написания сценариев РНР можно воспользоваться специальным редакторам,
в котором будут отображаться номера строк. В этом случае будет проще aHanj зи-
ровать код сценария. Иначе придется отсчитывать номера строк, чтобы найти ту,
в которой содержится ошибка. Действительно, если сценарий состоит из б строк то
пересчитать их не так уж и сложно. Но если в сценарии содержится 553 стрски,
то жизнь перестает быть веселой. Необходимо отметить, что многие редакторы
позволяют указать номер строки, к которой необходимо перейти.
В РНР весь сценарий можно разместить в одной длинной строке, разделяя при этом п х>-
стые операторы точкой с запятой. Но в этом случае анализ и чтение сценария существенно
затруднятся. Таким образом, простые операторы лучшее размещать в разных строках.
Иногда несколько операторов помещают в один блок, заключенный в фигурные скобки
({ }). Операторы в блоке выполняются вместе, как один оператор. Очень часто блоки кода
используются совместно с условным оператором, где набор инструкций выполняется при i ;ы-
полнении некоторого условия. Рассмотрим следующий пример:
if (время_суток == полночь)
{
одеть пижаму;
почистить зубы;
лечь в кровать;
}
Фигурные скобки указывают, что набор операторов в блоке будет выполняться как одно
целое. В полночь, т.е. когда время_суток = полночь, будут выполнены все три действия,
указанные в блоке. В противном случае ничего делать не надо (не надо одевать пижаму, чистить
зубы, идти ложиться спать).
Операторы, использующие блоки кода (как, например, оператор if), называются сложными
(complex statement). В этом случае интерпретатор РНР считывает весь сложный оператор,
не останавливаясь перед первым символом точки с запятой. Он допускает существование
нескольких блоков кода и ищет последнюю фигурную скобку последнего блока. Следует такке
отметить, что перед закрывающей фигурной скобкой стоит точка с запятой, а после — нет.
Операторы внутри блока вводятся с отступом. Такое размещение влияет только на удоС о-
читаемость кода, но никак не на результат, выполнения. Человеку, анализирующему код ci ;е-
нария, будет намного легче определять, где начинается и заканчивается тот или иной блок.
Отсутствие закрывающей фигурной скобки является распространенной ошибкой, особен ю
если используется несколько вложенных блоков. Использование отступов позволит быстэо
найти недостающую скобку.
Написание сцена/гиев
Для написания полноценного сценария необходимо добавить несколько оператор эв
в файл, который имеет расширение .php. Однако, если сценарий не так уж прост или если
у вас нет опыта, будет разумным сначала написать код сценария на бумаге. Помните, что тщательное
планирование позволит избежать многих ошибок при написании программного кода.
44 Часть I. Познакомьтесь с языком сценариев РНР
При создании сценария РНР для Web-узла его программный код необходимо каким-то
образом вставить в HTML-код Web-страницы. Если же сценарий создается независимо от
Web, то операторы РНР помещаются в отдельный файл, который вызывается напрямую.
В следующих разделах будет показано, как следует поступать в обоих случаях.
Как сервер обрабатывает файлы РНР
| Если пользователь обращается к обычному файлу HTML (с расширением . h t m l или . htm), Web-сервер
: передает его код напрямую браузеру. Браузер, в свою очередь, обрабатывает полученный файл
с дескрипторами HTML и выводит Web-страницу. Если же пользователь сгенерировал запрос к файлу РНР |
(с расширением . php), Web-сервер осуществляет обработку кода РНР (а не отправляет его сразу браузеру).
При этом выполняются следующие шаги.
1. Web-сервер просматривает исходный файл в режиме HTML, т.е. он никак не обрабатывает дескрипторы i
HTML, а отправляет их напрямую браузеру.
| 2. Просмотр в режиме HTML выполняется до тех пор, пока не будет найден открывающий дескриптор РНР
| (<?php). |
3. Найдя открывающий дескриптор <?php, Web-сервер переключается в режим РНР. Все, что находится после I
дескриптора <?php, интерпретируется Web-сервером как PHP-код и соответствующим образом
обрабатывается. Например, если в коде РНР содержится оператор вывода, то соответствующая информация
передается браузеру.
| 4. Web-сервер продолжает работу в режиме РНР до тех пор, пока не встретит закрывающий дескриптор
РНР (?>).
| 5. Найдя закрывающий дескриптор ?>, Web-сервер снова переключается в режим HTML и продолжает
выполнять действия, начиная с п. 1.
Вставка операторов РНР в HTML-код
При использовании языка РНР для создания Web-узлов операторы РНР необходимо
вставлять в HTML-код Web-страницы. При этом соответствующие файлы должны иметь
расширение . php, чтобы Web-сервер мог знать о наличии кода РНР. (Администратор Web-
сервера может использовать и другие расширения файлов, которые могут содержать операторы
РНР, например .php4 или .phtml. Однако расширение .php является наиболее популярным,
поэтому оно и будет использоваться в данной книге.)
Для вставки кода РНР в файл HTML используются дескрипторы, наподобие тех, что применяются
в файлах HTML. Общий синтаксис имеет следующий вид:
<?php
операторы РНР
?>
Можно также использовать сокращенную форму дескрипторов РНР <? и ?>, что
позволяет немного сократить код. Для того чтобы активизировать или отключить
использование сокращенных дескрипторов, следует внести соответствующие изменения
в конфигурационный файл php . i n i .
Иногда использование сокращенных дескрипторов является не очень хорошей
идеей. Действительно, если разместить Web-узел на сервере, который не поддерживает
сокращенные дескрипторы, PHP-код будет обрабатываться некорректно,
т.е. для переносимости кода лучше применять полные дескрипторы РНР.
Глава 3. Создание первого сценария РНР 45
Все операторы, находящиеся между открывающим и закрывающим дескрипторами РНР,
передаются Web-сервером на обработку интерпретатору РНР. После выполнения всех де) ICT-
вий код РНР опускается, а результат передается обратно Web-серверу. Тот, в свою очередь,
отправляет на сторону пользователя (т.е. браузеру) код HTML и результаты обработки сценария
РНР. При этом код РНР в браузере не отображается.
Например, добавим в файл HTML следующие строки кода РНР. При этом не забудьте сохранить
этот файл с расширением . php:
<?php
echo "Это привет от РНР";
?>
При получении Web-сервером запроса на файл с расширением . php он проверяет егс на
наличие дескрипторов РНР. Найдя открывающий дескриптор <?php, Web-сервер выполнит
оператор echo, а не просто отправит его браузеру. Браузеру будет передан результат выпэл-
нения, а именно строка Это привет от РНР, которая и отобразится в его окне. Даже если
просмотреть исходный код в браузере, в нем вы не увидите код РНР.
Не пытайтесь просматривать файл РНР, используя браузер напрямую, т.е. для те-
ремещения к файлу не надо выбирать в меню браузера команду File^Opeii^
Browse (Файл^Открыть^Обзор). К файлу нужно обращаться через полный
URL-адрес сценария РНР, как описано в главе 2.
На Web-страницу можно добавить несколько фрагментов PHP-кода. В качестве примера
приведем следующий фрагмент.
дескрипторы HTML
<?
echo "Это привет от РНР";
?>
дескрипторы HTML
<?
echo " Это тоже привет от РНР";
?>
В результате в окне браузера отобразятся две строки.
Использование РНР независимо от Web
РНР можно использовать в качестве самостоятельного языка написания сценариев, не.а-
висимо от Web. Для этого в РНР предназначен специальный интерфейс CLI (Command Li ie
Interface— интерфейс командной строки). Версия РНР CLI отлична от той, которая используется
для работы с Web-серверами (обычно называемой РНР CGI), и устанавливается независимо.
В приложении А приводятся более подробные инструкции по установке интерфейса CLI
Если вы намерены использовать интерфейс командной строки CLI для РНР, вы, скор ;е
всего, работаете на компьютере под управлением операционной системы Unix или Linux.
Программисты, работающие в Windows, вряд ли будут использовать РНР в качестве самостоятельного
языка написания сценариев (хотя в случае необходимости это можно сделан).
В данном разделе речь пойдет об использовании версии РНР CLI в операционных системах
Linux/Unix, но большая часть информации останется верной и для Windows. (В некоторых
случаях будут указаны соответствующие расхождения.)
Рассмотрим следующий сценарий РНР:
<?php
echo "Это привет от РНР";
?>
46 Часть I. Познакомьтесь с языком сценариев РНР
i Я§4
> Щ4^ф- Выполнение сценариев РНР в операционных системах Linux/Unix
: Если у вас уже имеется опыт запуска сценариев оболочки (shell script) или сценариев Perl в операционных
1 системах Linux/Unix, то выполнение PHP-сценариев не составит особого труда. Нужно просто добавить строку,
указывающую расположение интерфейса командной строки РНР CLI, и тогда вызов сценария можно
осуществлять напрямую:
#! /usr/bin/php 1
\ <?php
echo "Это привет от РНР" ;
! ?>
| Первая строка указывает, что сценарий будет выполнен с использованием программы, расположенной по адресу
• / u s r / b i n / p h p . В операционной системе Windows эта строка не работает, хотя и не приводит к генерации
ошибки. Строку # ! / u s r / b i n / p h p можно спокойно включать при создании сценариев РНР для Linux/Unix, не |
особенно заботясь о том, что при переходе к Windows она не будет работать.
I Для запуска сценария РНР необходимо ввести его имя. Это можно сделать в каталоге, в котором содержится |
j исходный файл, или указать полный путь к нему. Например, если файл, содержащий приведенный выше '
| фрагмент кода, называется t e s t . php, то для его запуска следует ввести имя
j test.php
; или указать полный путь к нему:
• /mystuff/test.php
j He забывайте также о том, что для выполнения этого файла, как и для запуска любого другого сценария,
нужно иметь соответствующие разрешения.
Если назвать этот файл t e s t c l i .php, то для его запуска необходимо ввести следующую
строку (при условии, что он находится в том же каталоге, где установлен РНР CLI):
php t e s t c l i . p hp
Можно также указать полный путь к интерпретатору РНР:
/usr/local/php/cli/php testcli.php
Если же сценарий РНР требуется запустить в операционной системе Windows, следует
воспользоваться консольным режимом ввода команд. Для этого необходимо выбрать команду
меню StartoPrograms^Accessories^Command Prompt (Пуск^Программы^Стан-
дартные1^Командная строка).
Основные отличия версии CLI от CGI состоят в следующем.
S Вывод заголовков HTTP. Поскольку в версии CGI результат выполнения
сценария передается сначала Web-серверу, а потом браузеру, к нему добавляются
заголовки HTTP (информация, с помощью которой Web-сервер и браузер
взаимодействуют друг с другом). Таким образом, в предыдущем примере
версия РНР CGI выдаст следующий результат:
Content-type: text/html
X-Powered-By: PHP/5.0
Это привет от РНР
Первые две строки в окне браузера не отображаются, но они необходимы для
корректной работы Web-сервера. В свою очередь, версия РНР CLI автоматически
не передает заголовки HTTP, а просто выведет одну строку:
Это привет от РНР
Глава 3. Создание первого сценария РНР 47
S Формат сообщений об ошибках. При использовании версии PHP CGI со общения
об ошибках будут отформатированы с помощью дескрипторов HTML,
поскольку, вероятнее всего, они будут отображаться в браузере. Сообщения
об ошибках в версии PHP CLI никак не форматируются.
•/ Использование значений по умолчанию для параметров argc и arirv.
Переменные argc и argv используются для передачи данных в сценарий из
командной строки (как в С и других языках). Вряд ли вы будете использовать
эти параметры в версии CGI, в то время как в CLI — скорее всего, будете. Поэтому
по умолчанию эти параметры доступны в CLI и недоступны в О31.
(Более подробно переменные argc и a r gv описаны в главе 5.)
При использовании РНР для командной строки можно воспользоваться некоторыми дополнительными
параметрами (ключами). Например, ключ -v позволяет вывести версию РНР.
Для этого нужно ввести следующую строку:
php -v
В табл. 3.1 приведены наиболее полезные параметры командной строки.
Таблица 3.1. Параметры командной строки РНР
Параметр Назначение
- с Определяет путь к используемому файлу php. i n i . Версией CLI может использоваться свой
собственный файл php. i n i , например - с / u s r / l o c a l / p h p / c l i / p h p . i n i (Более
подробную информацию о файле php. i n i можно найти в приложении А.)
-? Идентифицирует запускаемый сценарий. Например, php -? / m y f i l e s / t e s t c g i . p hp
- h Выводит справочную информацию
- i Выводит информацию о РНР, которая аналогична результатам функции p h p i n f о ()
(см. главу 2)
- 1 Проверяет сценарий на наличие ошибок, но не выполняет его
- т Выводит список скомпилированных модулей РНР. (Более подробно модули описаны в главе 14.)
- г Выполняет код РНР, введенный в командной строке.
Например, php - r ' p r i n t ( ' П р и в е т ' ) ; '
- v Выводит номер версии РНР
Созс/ание nefi0oio сцена/гил THJ*
За многие годы сложилась такая традиция, что первая созданная программа должна выв >
дить строку Здравствуй, мир. Если вы изучали HTML, то вам, наверное, доводилось осуществлять
эту процедуру и вы использовали примерно следующий код:
<html>
<headxtitle>HTML-nporpaMMa</titlex/head>
<body>
<р>3дравствуй, мир!</р>
</body>
</html>
Если отобразить содержимое этого файла в браузере, получим очевидный результат:
Здравствуй, мир!
48 Часть I. Познакомьтесь с языком сценариев РНР
Ваш первый сценарий на РНР будет выполнять абсолютно те же действия. Ниже приведен
фрагмент кода, который содержит дескрипторы HTML и PHP-код и выводит в окне браузера
строку Здравствуй, мир!
<html>
<headxtitle>CueHaprai PHP</titlex/head>
<body>
<?php
echo "<р>3дравствуй, мир!</р>";
?>
</body>
</html>
Результат выполнения этого сценария будет таким же, как и результат вывода файла HTML.
Нет смысла просматривать файл РНР, используя напрямую браузер, т.е. для перехода
к файлу нет смысла выбирать в меню браузера команду File^OpenO
Browse (ФайлООткрыть^Обзор). Для обращения к файлу необходимо указать
полный URL-адрес сценария РНР в адресной строке браузера (см. главу 2). Если
код РНР не выполняется, а просто отображается в окне браузера, значит, вы обратились
к нему не через URL-адрес.
В приведенном выше примере фрагмент РНР состоит из следующих строк:
<?php
echo "<р>3дравствуй, мир!</р>"
?>
Между открывающим и закрывающим дескрипторами РНР содержится только один оператор
echo, который выводит строку, заключенную в двойные кавычки (" ").
Таким образом, в результате выполнения сценария браузеру будет передана следующая
строка:
<р>3дравствуй, мир!</р>
Если фрагмент PHP-кода заменить этой строкой, то получим обычный HTML-файл. При
этом в обоих случаях результат будет один и тот же, точно так же, как и исходный код, обрабатываемый
браузером (чтобы его увидеть в меню браузера, следует выбрать команду
View=>Source (ВидОПросмотр HTML-кода)).
2)ей1альнее о<$ onefiatfiofiax вывода
В сценарии, созданном в предыдущем разделе, для отображения информации использовался
оператор вывода echo. Операторы вывода (output statement) встречаются практически
во всех сценариях. Очень редко приходится создавать приложения, в которых ничего не выводится.
Действительно, PHP-сценарий может выполнять любые действия незаметно для
пользователя, например проверять наличие файла на жестком диске. Но если клиенту ничего
не будет выведено, то в чем тогда смысл? Как пользователь узнает, найден файл или нет?
А если найден, то где он в таком случае расположен? Соответственно, практически во всех
сценариях используются операторы вывода.
Общий синтаксис оператора echo выглядит следующим образом:
echo элемент_вывода1,элемент_вывода2,элемент_выводаЗ, ...
При работе с этим оператором следует руководствоваться такими правилами.
Глава 3. Создание первого сценария РНР 49
•S Параметр элемент_вывода может быть числом (например, таким кан 1
или 250) либо текстовой строкой. Более подробно типы данных рассматриваются
в главе 5.
•S Текстовая строка должна быть заключена в одинарные или двойные кавпч-
ки. (В главе 5 обсуждается, какие кавычки следует использовать в тех ыш
иных случаях.)
•S Количество аргументов оператора echo может быть произвольным.
S Аргументы оператора echo разделяются запятой (,) без использования
пробелов.
S Если необходимо добавить пробел при выводе различных значений, его следует
добавить в строку вывода в качестве отдельного символа.
В табл. 3.2 приведены некоторые примеры использования оператора echo.
Таблица 3.2. Примеры использования оператора echo
Пример Результат выполнения
echo 123;
echo "Здравствуй, мир!";
echo "Здравствуй,","мир!";
echo "Здравствуй,", " ","мир!";
echo Здравствуй, мир!;
echo ''Здравствуй, мир!';
123
3дра в с т вуй, мир!
Здравствуй,мир!
Здравствуй, мир!
Выдаст сообщение об ошибке, поскольку строка
не заключена в кавычки
Здравствуй, мир!
Обработка операторов вывода РНР
В сценарии, выводящем строку Здравствуй, мир !, как и в большинстве других сценариев,
операторы вывода используются для генерирования кода HTML, который отображается
в браузере. В этом случае необходимо помнить о двух этапах, которые при этом выполняются
1. Интерпретатор РНР выполняет операторы РНР, перенаправляет результат работы
Web-серверу, который, в свою очередь, отправляет их клиентскому браузеру.
РНР никак не обрабатывает HTML-код, а только передает информацию, полученною
в результате выполнения РНР-кода.
2. Web-браузер интерпретирует полученную от интерпретатора РНР информацию как
HTML-код и выводит ее на Web-странице.
В отличие от РНР он обрабатывает только HTML-код и не "понимает" кода РНР. Таким
образом, нужно позаботиться о том, чтобы Web-браузер корректно интерпретировал
информацию, полученную в результате выполнения фрагмента кода на РНР.
В качестве примера рассмотрим оператор вывода echo, отображающий стро<у
Здравствуй, мир!:
echo "<р>3дравствуй, мир!</р>",-
Он выводит все, что находится в двойных кавычках (""). Обработка этого РНР-кода буд гт
выполнена в два этапа.
1. Результатом выполнения оператора echo будет следующая строка:
<р>3дравствуй, мир!</р>
50 Часть I. Познакомьтесь с языком сценариев РНР
Поскольку интерпретатор РНР не понимает HTML-код, то дескрипторы <р> и </р>
никак обработаны не будут, а будут восприниматься как символы текстовой строки.
2. Получив строку, Web-браузер, в свою очередь, интерпретирует символы <р> и < /р>
как открывающий и закрывающий дескрипторы HTML для форматирования текста
и выводит его в окне браузера соответствующим образом:
Здравствуй, мир!
При этом сами дескрипторы не отображаются. Для того чтобы увидеть, что именно
было передано браузеру Web-сервером, можно отобразить исходный код HTML-
страницы. Для приведенной страницы он будет иметь следующий вид:
<р>3дравствуй, мир!</р>
Использование специальных символов в операторах вывода
Оператор echo специальным образом обрабатывает некоторые символы, которые существенно
влияют на получаемый результат. Одним из них является символ перехода на новую
строку \п. Рассмотрим следующий пример:
echo "<р>3дравствуй,\п мир!</р>"
Символ \п в операторе echo означает переход на новую строку, однако это не отображается
в браузере. Для перехода к новой строке на Web-странице необходимо использовать
внутри строки специальный дескриптор <br>. Рассмотрим следующий пример:
echo "<р>3дравствуй,<br> мир!</р>"
В этом случае в браузере будет выведено две строки.
В табл. 3.3 приводятся отличия результатов выполнения оператора echo на разных этапах:
после его обработки интерпретатором РНР и в Web-браузере. Первый столбец содержит
пример фрагмента кода с оператором echo. Во втором приводится результат его обработки
интерпретатором РНР (т.е. то, что передается браузеру), а в третьем — результат, отображаемый
в самом браузере.
Таблица 3.3. Этапы обработки страницы с РНР-кодом
Пример оператора echo Результат обработки
интерпретатором РНР
Результат отображения
в браузере
echo "Здравствуй, мир!";
echo "Здравствуй,";
echo "мир!";
echo "Здравствуй,\пмир!";
Здравствуй, мир!
Здравствуй, мир!
Здравствуй, мир!
Здравствуй,мир!
Здравствуй, Здравствуй, мир!
мир!
Здравствуй,<Ьг>мир! Здравствуй,
мир!
echo "Здравствуй,<Ьг>\пмир!"; Здравствуй,<Ьг> Здравствуй,
мир! мир!
echo "Здравствуй,<Ьг>мир!
Обратите внимание на наличие пробела в результирующих выражениях. Так, в первом
примере пробел содержится в текстовой строке, выводимой оператором echo. Следовательно,
этот символ будет содержаться и после обработки интерпретатором РНР, и в браузере. Во
втором случае выполняются два разных вызова оператора echo. Причем, поскольку ни одна
из выводимых строк не содержит пробела, в результирующих выражениях он также отсутствует.
В третьем примере при отображении текста в окне браузера будет выведен пробел, хотя
Глава 3. Создание первого сценария РНР 51
в строке Здравствуй\пмир! его нет. Это связно с тем, что специальный символ \п никак
не интерпретируется браузером (т.е. не осуществляется перевод на новую строку), а просто
заменяется на пробел.
Свободно используйте символ перевода строки \п. В противном случае исходный
HTML-код будет содержать очень длинные строки. Представим, например,
что имеется форма, содержащая большое количество полей. Несмотря на то чго
она может иметь нормальный вид в окне браузера, ее HTML-код может быть р; з-
мещен всего в нескольких строках. В общем-то, это не создает никаких проблем
до тех пор, пока не понадобится поработать с кодом HTML самой Web-страницы.
В этом случае придется серьезно попотеть, отыскивая ошибку в многокилометровых
строках кода. Поэтому использование символа \п позволит привести HTML-
код к более удобному для анализа виду. Кроме того, некоторые браузеры мог ут
некорректно обрабатывать длинные строки.
РНР выводит в точности то, что ему указывают. Интерпретатору РНР не важно, пе
впоследствии будет отображаться информация— в окне браузера или просто на экраге.
Прежде всего, это ваша забота. Если разрабатывается приложение для Web, то выводимые
строки должны содержать дескрипторы HTML. Если же язык РНР используется для написания
сценария, независимого от Web, в этом случае информацию лучше выводить в ви :е
обычного текста.
2)ош/мен/пи{1ован,ие сценариев
Документирование сценариев является очень важным этапом при разработке приложений.
Комментарии позволяют описать, что именно и как выполняет сценарий. Чем больше, сложнее
и замысловатее код сценария, тем большее значение приобретает документирование. Проработав
двадцать часов над сценарием, вы будете уверены, что он навеки останется в вашей памяти.
Однако по прошествии двух лет, когда необходимо будет пересмотреть код сценария, i ы
его совсем не узнаете. Также вполне возможна ситуация, когда действительно кто-то другой захочет
переделать код сценария, а в это время вы будете недоступны, отдыхая на Багамах.
Комментарии (comments) представляют собой заметки, вставляемые в код сценария. При
этом они игнорируются интерпретатором РНР и предназначены для пользователей. Комментарии
в сценарии могут быть произвольной длины. Их общий синтаксис имеет следующий вид:
/* текст комментариев
еще комментарии */
Когда интерпретатор РНР встречает в сценарии символы начала комментария (/*), весь
последующий код игнорируется вплоть до символов * /.
Очень часто разработчики добавляют комментарии в начало сценариев, чтобы дать о нем
краткую информацию и указать, какие функции он выполняет. Рассмотрим следующий пример:
/* имя сценария: hello.php
описание: отображает строку "Здравствуй, мир!"
на Web-странице
автор: Программист Джон
дата создания: 02/01/03
дата изменения: 03/15/03
*/
В языке РНР комментарии можно использовать и в сокращенной форме. Для этого можю
использовать символ решетки (#) либо два символа косой черты (//). Они позволяют закомментировать
целую строку. Например:
52 Часть I. Познакомьтесь с языком сценариев РН°
# Строка комментариев 1
/ / Строка комментариев 2
Символы # и / / можно также использовать в строке кода, указывая тем самым на начало
комментария. Это особенно полезно для описания работы отдельного оператора. Рассмотрим
следующий пример:
echo "Привет"; // это мой первый оператор вывода
Следует отметить, что интерпретатор РНР не включает комментарии в HTML-код, передаваемый
впоследствии браузеру, так что пользователь их увидеть не сможет.
Иногда очень полезно использовать комментарии в качестве заголовка разделов кода, например:
/* Проверяет, исполнилось ли покупателю 18 лет */
/* Сохраняет информацию в базе данных */
/* Осуществляет поиск указанного файла */
Иногда следует выделить комментарии, чтобы заострить на них внимание. Это можно
сделать следующим образом:
################################
# Дважды проверьте этот раздел #
################################
Используйте комментарии так часто, как того требует ситуация. Однако, с другой стороны,
не стоит ими злоупотреблять: большое количество комментариев может резко снизить их
ценность. Их лучше всего использовать для описания различных разделов кода сценария или
в случае нестандартного (или неочевидного) подхода к написанию программы. Например,
комментарий, поясняющий работу оператора echo, является лишним, поскольку и так понятно,
для чего он предназначен. Если смысл кода очевиден, не следует загромождать его
лишними комментариями.
Внимательно следите за тем, чтобы не использовать в сценарии вложенные комментарии.
В этом случае код РНР будет работать некорректно. Рассмотрим следующий пример:
/* Первый комментарий
/* Вложенный комментарий */
*/
Найдя символы начала комментария, /*, интерпретатор РНР будет игнорировать код до
тех пор, пока не встретит символы */. Поэтому будет проигнорирован и второй набор символов
/*. Таким образом, будет закомментировано все, что находится между первыми символами
/* и */. Дойдя до второго набора символов */, интерпретатор РНР выдаст сообщение
об ошибке, поскольку он не интерпретирует их как символы окончания комментария.
Глава 3. Создание первого сценария РНР 53
Часть II
Переменные и данные
*\Лъъитм, но доменные имен* *W", Ч№>" u W
иже злрегишриро&дны & tttwu. Можем ^релложиуль
W, W или W.
/3 эркои час/ни
В этой части речь пойдет о создании и использовании переменных
в языке РНР. Будут описаны типы данных, которые могут храниться
в переменных, а также особенности хранения различных типов. Вы узнаете
также, как хранить взаимосвязанные данные в сложных переменных,
получивших название массивов.
Глава 4
Использование переменных
в сценариях РНР
вSfflou главе...
> Имена переменных
> Присваивание значений переменным
> Удаление переменных
> Использование констант
> Обработка ошибок
временные (variable) — это контейнеры, в которых содержится информация. Сначала
задается имя переменной, а затем в этой переменной можно хранить информацию.
Например, можно назвать переменную $аде и записать в нее число 21. После присваивания
переменной некоторого значения эту переменную можно использовать в сценарии.
При использовании языка РНР для Web переменные зачастую применяются для хранения
информации, которую пользователи вводят в формах HTML, например имени пользователя.
Тогда эту переменную можно использовать в сценарии или даже создать персональную Web-
страницу с отображением имени пользователя, например "Приветствую Вас, Сергей Петренко!"
В этой главе речь пойдет о том, как описывать переменные и работать с содержащейся
в них информацией. Вы также узнаете, как обрабатывать ошибки.
iLueHa nefieutettHbtx
Имена переменных, или идентификаторы, должны быть осмысленными. Автору приходилось
встречать сценарии, где все переменные назывались $varl, $var2, $var3 и т.д. Переменные,
конечно, можно называть подобным образом, но если спустя какое-то время вы
вернетесь к этому сценарию, у вас могуг возникнуть проблемы с выяснением смысла каждой
переменной. Интерпретатор РНР не будет затрудняться или путаться, но люди, которые попытаются
разобраться в сценарии, вынуждены будут тратить лишнее время. Делайте ваши
сценарии как можно проще для понимания, используя осмысленные имена переменных, например
$f irstName, $directory_name или $DateOfBirth.
Приведем основные правила именования переменных.
| S Все имена переменных начинаются с символа доллара ($). Этот символ
в языке РНР означает начало имени переменной.
S Имена переменных могут быть любой длины.
S Имена переменных могут включать только буквы, цифры и символы
подчеркивания.
•/ Имена переменных должны начинаться с буквы или символа подчеркивания.
Они не могут начинаться с цифры.
Л
•f Символы верхнего и нижнего регистров различаются. Имена
$ f a v o r i t e c i t y и $ F a v o r i t e c i t y означают разные переменные. Е:ли
информация хранится в переменной $FavoriteCity, вы не сможете гоз-
же в сценарии получить доступ к этой информации, используя имя переменной
$ f a v o r i t e C i t y.
•
Приведем примеры допустимых имен переменных:
$_name
$first_name
$name3
$name_3
Следующие имена переменных приведут к генерации сообщений об ошибках:
$3name
$name?
$first+name
$first.name
Первое имя недопустимо, потому что оно начинается не с буквы или символа подчер ш-
вания, как требуют правила именования. Три остальных имени недопустимы, поскольку кю-
ме цифр, букв и символа подчеркивания в них содержатся другие символы.
Выбор имени переменной зависит от личных предпочтений. Чаще всего для создания осмысленных
имен переменных используется символ подчеркивания или прописные букны.
Эти наиболее популярные стили формирования имен переменных проиллюстрированы на
следующем примере:
$first_name
$firstName
Описание переменных на основе одного из двух приведенных стилей облегчает чтение сценариев.
Обычно имя начинается с символа нижнего регистра. Однако главное правило выбс ра
имен переменных — их согласованность. Выберите стиль и используйте его во всем сценарии
ТЦшсванЯание и otiiorffiajtcetiue значений
nefieueHHbtx
Переменные могут содержать числа или строки символов. Переменная может существовать
или не существовать, содержать или не содержать информацию. Причем это не одю
и то же. Даже если переменная в настоящее время не содержит никакой информации, о \г.
может существовать так же, как существует полка шкафа, даже если она пуста. Конечно, если
переменная содержит информацию, она должна существовать.
В следующих разделах рассказывается о том, как создавать переменные и работать с их
значениями.
Создание переменных
Переменная автоматически создается при сохранении в ней некоторой информации.
Чтобы задать значение переменной, нужно использовать знак равенства (=) . Например,
следующие четыре оператора РНР присваивают значения переменным:
$аде = 21;
$price = 20.52;
$temperature =-5;
$name = "Кларк Кент";
58 Часть //. Переменные и данные
Обратите внимание, что в этих примерах числа не заключены в кавычки, а имя, которое
является строкой символов, — заключено. Кавычки в РНР свидетельствуют о том, что символы
входят в состав строки, обрабатываемой интерпретатором РНР как отдельная единица.
Без кавычек интерпретатор РНР не будет знать, что символы образуют строку, и будет неправильно
их обрабатывать. Различные типы данных и особенности их использования будут
подробно обсуждаться в главе 5.
Всякий раз, когда значение присваивается несуществующей переменной, эта переменная создается.
Например, предположим, что в начале сценария используются следующие операторы РНР:
$color в "синий";
$color = "красный";
Первый оператор создает переменную и присваивает ее значение " синий". Следующая
инструкция изменяет значение переменной $color на " красный".
Значение одной переменной можно присваивать другой переменной, как показано в следующих
примерах:
$namel = "Салли";
$name2 = "Сюзан";
$favorite_name = $name2;
После выполнения этих операторов в переменной $ favor i t e_name будет содержаться
значение "Сюзан".
Можно создать переменную, не присваивая ей никакого значения. Например, следующая
инструкция создает переменную:
$city = "";
Теперь переменная существует, но не содержит никакого значения. Более подробная информация
о типах данных и особенностях их использования содержится в главе 5.
Отображение значений переменных
Самый быстрый способ отображения значения переменной заключается в использовании
функции p r i n t _ r . Приведем пример отображения значения переменной:
$today = "Воскресенье";
print_r($today);
Результатом выполнения кода будет вывод слова Воскресенье.
Значение можно также отобразить и с помощью оператора echo. Результатом выполнения
кода РНР
$аде = 21;
echo $age;
будет вывод числа 21.
Использование оператора echo указанного вида приводит к тому же результату, что
и применение функции p r i n t _ r . Однако оператор echo позволяет сделать гораздо больше.
С его помощью можно вывести несколько элементов, включая числа и строки. Например,
предположим, что в переменной $name содержится значение Кларк Кент. Вы можете
включить в HTML-файл следующую строку:
<р> Добро пожаловать, <?php echo $name?>/p>
Результат ее обработки на Web-странице будет выглядеть так:
Добро пожаловать, Кларк Кент
Если вы попытаетесь использовать несуществующую переменную, то будет сгенерировано
предупреждение. Например, предположим, что вы хотите вывести значение переменной
$аде, но допустили ошибку:
echo $aeg;
Глава 4. Использование переменных в сценариях РНР 59
В результате появится следующее предупреждение:
Notice: Undefined variable: aeg in c:\testvar.php on line 5
В этом сообщении (Notice) говорится о том, что вы используете неопределенную переменную.
Такое сообщение в данном случае полезно, поскольку позволяет точно определить
строку с опечаткой. Однако в некоторых случаях при написании кода может использоват .ся
несуществующая переменная, и это не будет опечаткой (такая переменная может быть задана
преднамеренно). Например, такой подход можно использовать в условном операторе
(условные операторы будут описаны в главе 7). Сценарий при этом будет работать как положено,
и предупреждение в этом случае будет совсем ни к чему. Эту проблему можно решигь,
добавив перед именем переменной символ @. Если вы хотите, чтобы предупреждение не отображалось,
используйте следующий синтаксис:
echo @$aeg,-
Таким образом, можно отключить вывод сообщения об ошибках. Поэтому, несмотря на
то, что переменная не существует, команда echo не отобразит никакой информации.
Не отключайте сообщения об ошибках, которые вы не понимаете. Убедитесь, i то
вы понимаете сущность ошибки и уверены, что это не приведет к неправильной
работе приложения. Сообщение об ошибке указывает на то, что в сценарии содержится
некорректность, которую нужно исправить. Это может быть опечатка
в имени переменной, как в предыдущем примере.
Многие языки программирования требуют, чтобы перед использованием переменные
были описаны. В этих языках использование переменной без ее описания
— неустранимая ошибка, при наличии которой сценарий прекращает выполняться.
Однако РНР не требует этого, что может несколько смутить
специалистов, имеющих опыт программирования на языке Java или С.
Создание пе/гвого сценария с пе[1еменн,ыми
Сценарий, приведенный в главе 3, отображает на Web-странице приветствие, используя
простую инструкцию echo. В этом разделе мы тоже создадим сценарий, отображающий
приветствие, но с использованием переменной. В сценарии из главы 3 для вывода приветствия
используется следующий фрагмент кода на РНР:
<?php
echo "<р>3дравствуй, мир! </р>";
?>
Приведем полный текст сценария, содержащий раздел РНР с переменной и отображающий
приветствие "Здравствуй, мир!":
<html>
<head> <title>CueHapmi с использованием nepeMeHH0H</titlex/head>
<body>
<?php
$salutation = "Здравствуй, мир!";
echo "<p> $salutation </p>";
?>
</body>
</HTML>
Если этот сценарий загрузить в браузер, на Web-странице отобразится приветствие
Здравствуй, мир!
4S2&
'"й-ОБНО^
60 Часть II. Переменные и данные
Переменная сохраняет свое значение в процессе выполнения всего сценария, а не только в
отдельном РНР-разделе. Если переменной присвоить значение 5 в начале сценария, то
и в конце сценария значение этой переменной будет равно 5 (если, конечно, вы не присвоите
ей нового значения). Например, следующий сценарий содержит два отдельных РНР раздела:
<html>
<headxtitle>CiJ,eHapira с использованием nepeMeHHOH</titlex/hea6>
<body>
<?php
$salutation = "Здравствуй, мир!";
echo "<p> $salutation </p>";
?>
<р>Это раздел HTML</p>
<?php
echo "<p>$salutation еще раз</р>";
?>
</body>
</HTML>
Если URL-адрес этого сценария указать в браузере, то на Web-странице отобразится следующая
информация:
Здравствуй, мир!
Это раздел HTML
Здравствуй, мир! еще раз
'Более noqfioduo orf onefiatnofiax вывода
Как упоминалось в главе 3, оператор echo имеет следующий формат:
echo элемент_вывода1,элемент_вывода2,элемент_выводаЗ,...
Вместо любого элемента вывода можно использовать переменную. Например, можно создать
такой РНР-раздел:
<?php
$first_name = "Кларк";
$last_name = "Кент"; echo "Меня зовут ",$first_name," ",$last_name;
?>
Приведем результат выполнения кода этого раздела:
Меня зовут Кларк Кент
Обратите внимание на пробел между переменными $f irst_name и $last_name. Если
не добавить этот пробел, эти две переменные будут выводиться слитно:
Меня зовут КларкКент
Для получения желаемого вывода операторы, содержащие несколько переменных, должны
удовлетворять определенным правилам форматирования. В табл. 4.1 показаны некоторые
операторы echo, которые содержат переменные, а также результаты их использования.
В таблице в операторах echo используются следующие значения переменных:
$number = 12 3;
$wordl = "Здравствуй,";
$word2 = "мир!";
Обратите внимание, что во второй строке таблицы между двумя переменными отсутствует
пробел, поэтому нет никакого пробела и при выводе. В третьей строке между значениями
переменных отображается пробел.
Глава 4. Использование переменных в сценариях РНР 61
Таблица. 4.1. Операторы echo с переменными
Оператор echo Результат вывода
echo $number; 123
echo $word,$word2; Здравствуй,мир!
echo $wordl," ",$word2; Здравствуй, мир!
echo $ w o r d l $word2; Неверно, потому что имена переменных не отделены друг от друга
запятыми. Это приведет к генерации сообщения об ошибке
echo "$wordl $word2 снова"; Здравствуй, мир ! снова
В некоторых операторах echo интерпретатор РНР не может отделить имя переменной,
если сразу за ним следует текст. В подобных случаях имя переменной необходимо заключать
в фигурные скобки. Например, предположим, что в сценарии используются следующие строю к
$type = "bird";
echo "Keep the $typecage clean";
Вместо желаемого результата будет получено следующее сообщение:
Notice: Undefined variable: typecage in testvar.php on l i n e 6
После уведомления о проблеме будет выведен такой текст:
Keep the clean
Для того чтобы этот код работал правильно, необходимо использовать оператор echo
следующего формата:
echo "Keep the {$type}cage clean";
тогда будет получен следующий результат:
Keep the birdcage clean
использование ке/геменнмх пе/геменных
РНР позволяет использовать динамические имена переменных, получившие название
переменных переменных. Переменную можно описать, используя значение, сохраненнэе
в другой переменной, т.е. одна переменная может содержать имя другой переменной. Предположим,
например, что вы хотите создать переменную $ c i t y со значением Лос-Анджелес.
Для этого можно использовать следующий синтаксис:
$name_of_the_variable = "city";
В этой строке создается переменная, содержащая имя, которое можно назначить другой
переменной. Для этого необходимо использовать операторы
$$name_of_the_variable = "Лос-Анджелес";
Обратите внимание на дополнительный символ доллара в начале имени переменной. Э"о
и есть обозначение переменной переменной. Этот оператор создает новую переменную, имг-
нем которой является значение, содержащееся в переменной $name_of _the_variable:
$city = "Лос Анджелес";
Значение переменной $name_of _ t h e _ v a r i a b l e при этом не изменится.
Следующий пример иллюстрирует особенности работы с такими переменными. Операт >
ры приведенного сценария вряд ли окажутся очень полезными, поскольку можно придумаъ
лучший вариант решения данной задачи. Истинное преимущество переменных переменных
становится понятным, когда они используются с массивами и циклами. Эти вопросы обсуждаются
в главах 6 и 7.
62 Часть II. Переменные и данные
Предположим, необходимо создать несколько переменных, имена которых совпадают
с названиями городов, а их значениями является количество людей, населяющих соответствующий
город. Для этого можно использовать такой код:
$Reno = 3 60000;
$Pasadena = 13 8000;
$cityname = "Reno";
echo "Население $cityname - ${$cityname}";
$cityname = "Pasadena"; echo "Население $cityname - ${$cityname}";
Результатом выполнения этого кода является следующий текст:
Население Reno - 360000
Население Pasadena - 13 8000
Обратите внимание, что в операторе echo имена переменных необходимо заключать
в фигурные скобки. Без использования фигурных скобок вы получите совсем другой результат.
Удаление пепеленных
Удалить информацию из переменной можно с помощью оператора
$аде = ;
Этот оператор удаляет значение переменной $аде. Причем это не означает, что теперь переменная
$аде установлена в значение 0. Это лишь значит, что переменная $аде не содержит
никакой информации. Технически это означает, что значением $аде является строка нулевых
символов. Если вы попытаетесь вывести значение $аде на экран с помощью инструкции echo,
то на экран ничего не выведется. (Сообщение об ошибке при этом тоже не выводится.)
Переменную можно удалить и следующим образом:
unset($age);
После выполнения этого оператора переменная $аде больше не будет существовать. Если
вы попробуете вывести ее с помощью оператора echo, то получите сообщение об ошибке
"undefined v a r i a b l e " (неопределенная переменная). Таким образом, можно одновременно
удалить несколько переменных:
unset($age, $name, $address);
Padotna c icoHctiiaHtnaMU
Константы подобны переменным. Константам дают имена и присваивают значения. Однако
константы являются постоянными; их значения не могут быть изменены в сценарии.
После того как значение константы установлено, оно уже не меняется. Если ввести константу
для обозначения погоды и установить для нее значение "солнечная", то впоследствии изменить
это значение нельзя.
Создание констант
Константы описываются с помощью оператора define. Общий формат этого оператора
таков:
define (" имя_константы" , " значение_константы") ,-
Например, чтобы создать константу weather, используйте следующий синтаксис:
define("weather", "солнечная");
Эта команда создает константу с именем weather и значением солнечная.
Глава 4. Использование переменных в сценариях РНР 63
При описании констант, как и при объявлении переменных, нужно использовать осмысленные
имена. Однако, в отличие от переменных, имена констант не начинаются со знака
доллара. В соответствии с негласным соглашением константам присваивают имена, состоящие
из прописных букв латинского алфавита, чтобы их можно было легко отличать от пс ременных.
Однако в языке РНР можно использовать и символы нижнего регистра.
Константа может содержать строку или число. Следующий оператор создает константу
с именем INTEREST и присваивает ей значение .01:
define("INTEREST",.01);
Константам нельзя давать имена, которые являются ключевыми словами РНР. Ключевые
слова— это имена операторов РНР, например echo. Их нельзя использовать в качестве имен
констант, потому что интерпретатор РНР обрабатывает их как команды PHP-сценария, а не как
константы. РНР позволит описать константу с именем ECHO, не выдавая сообщения об ошибке, но
при использовании такой константы возникнут проблемы. Например, если написать оператор ъ\ да
e c h o ECHO;
интерпретатор РНР запутается и выведет сообщение об ошибке. Он рассматривает константу
как начало следующего оператора echo, но не может найти аргументы, чтобы завершить
первую инструкцию echo.
В набор ключевых слов РНР включены следующие:
and echo list
as else new
break empty or
case eval print
class exit require
const for return
continue foreach switch
declare function use
default global var
d i e if while
do include
Если вас беспокоит некоторый код, который выглядит хорошо, но отказывается к< >р-
ректно работать даже после многочисленных изменений, попробуйте изменить имя
константы. Возможно, проблема состоит в том, что в качестве имени константы используется
какое-то ключевое слово. Такое случается редко, но все же случается.
Следует отметить, что ключевые слова вполне можно использовать в качестве имен пе{ ю-
менных, поскольку имена переменных начинаются с символа $. Однако лучше этим не пользоваться,
так как такой стиль может запутать пользователей, которые будут работать с этим
сценарием в дальнейшем.
Когда использовать константы
Если вы знаете, что значение какой-либо переменной не будет изменяться на протяжен ш
всего сценария, рационально использовать для его хранения константу. Применение константы
позволяет выбрать длинное осмысленное имя и сделать сценарий более ясным. Например,
название PR0DUCT_COST более понятно, чем число 20.50.
При использовании константы ее значение можно установить только один раз —
в начале сценария. Если это значение когда-либо понадобится изменить, то при
использовании константы это можно сделать только в одном месте, а не изменя гь
значение переменной в двадцати различных местах сценария. Одна замена лучие,
чем двадцать. Такой подход очень удобен и ускоряет работу.
64 Часть II. Переменные и даннье
Использование константы гарантирует, что данное значение не будет случайно изменено
где-либо в сценарии.
Предположим, имеется сценарий, который переводит значения из одной валюты в другую,
умножая количество долларов на обменный курс. Например, если курс обмена доллара
США на канадский доллар составляет 1.52, можно записать следующий код:
<?php
$US_dollars = 20.00;
$CA_dollars = $US_dollars * 1.52;
?>
Теперь предположим, что этот сценарий содержит 40 000 строк кода и что доллары США
в нем конвертируются в канадские доллары в 50 различных местах. Значит, приведенный
выше код встречается в 50 различных местах. Вы понимаете, что обменный курс изменяется
практически каждую неделю, значит, каждую неделю вам придется редактировать этот сценарий,
вручную изменяя число 1.52 на другое значение в 50 различных местах. Согласитесь,
что это очень утомительно.
Гораздо лучше поместить обменный курс в переменную, чтобы изменять это значение
только в одном месте. Тогда сценарий будет выглядеть следующим образом:
<?php
$rate = 1.52;
$US_dollars = 20.00;
$CA_dollars = $US_dollars * $rate;
?>
Значение $ r a t e можно установить в начале сценария, а затем использовать его в 50 необходимых
местах сценария. Естественно, это более удобная реализация. Если потребуется
изменить курс, то значение переменной потребуется поменять только в одном месте. Например,
если на следующей неделе обменный курс изменится на 1.53, вам придется изменить
лишь первую строку сценария:
$rate = 1.53;
Такой подход вполне пригоден. Однако $ r a t e — не очень осмысленное имя. Вспомните,
что сценарий содержит 40 000 строк кода и 2 строки, определяющие процедуру конвертирования
валюты, которые используются в 50 различных местах. Предположим, где-то в середине
сценария необходимо добавить некоторый код, определяющий степень заинтересованности.
Предположим, где-нибудь в середине сценария вы случайно используете следующий код:
$ i n t e r e s t _ r a t e = 20;
$rate = $ i n t e r e s t _ r a t e - l;
$amount = $principal * $rate;
Теперь всюду после этого фрагмента значение переменной $ r a t e изменится. Значение
1.52, установленное в начале сценария, будет заменено числом 19, определяемым этим кодом.
Этого можно избежать, выбирая более осмысленные имена переменных. А еще лучше
использовать константу, как в следующем сценарии:
<?php
define("RATE", 1.52);
$US_dolars = 20;
$CA_dollars = $US_dollars * RATE;
?>
Теперь вы используете константу RATE, которую нельзя изменить в сценарии. Если в середине
сценария вы попробуете добавить строку
RATE = 20;
интерпретатор РНР не позволит изменить значение. Таким образом можно избежать ошибок,
которые легко допустить при использовании переменных.
Глава 4. Использование переменных в сценариях РНР 65
На следующей неделе, когда обменный курс изменится на 1. 53, этот сценарий придется
лишь слегка отредактировать следующим образом:
<?php
define("RATE", 1.53);
$US_dollars = 20
$CA_dollars = $US_dollars * RATE;
?>
Конечно, лучше использовать более осмысленное имя, например:
define("US_TO_CA", 1.52);
Имейте в виду, что ошибки, которые невозможно допустить при работе с простыми сценариями,
состоящими из десяти строк, вполне возможны при работе со сценариями, включающими
тысячи строк кода, особенно, если такой сценарий разрабатывает целая кома яда
программистов.
Если вы уверены, что некоторое значение не будет изменяться на протяжении
всего сценария, используйте константу. Если значение изменяется в процессе работы
сценария, используйте переменную.
Отображение значений констант
Значение константы можно вывести с помощью функции p r i n t _ r следующим образо и:
print_r(US_TO_CA);
Константу также можно вывести с помощью оператора echo:
echo US_T0_CA;
Если для вывода константы используется оператор echo, имя константы не нужно заключать
в кавычки. Если имя константы все же заключить в кавычки, то на экране отобразится
имя константы, а не ее значение. Константу можно вывести, как показано в предыдущем
примере, или же с использованием круглых скобок. Можно формировать и более сложные
команды вывода, разделяя выводимые объекты запятыми, как в следующем примере:
echo "Курс обмена на канадский доллар составляет $",US_T0_CA;
В результате выполнения этой команды будет выведен следующий текст:
Курс обмена на канадский доллар составляет $1.52
Использование встроенных констант
В языке РНР определено множество встроенных констант, которые можно использов ш>
в сценариях. Для примера, значением константы LINE является номер текущей стро ки,
а константа FILE содержит имя соответствующего файла. (Встроенные константы начинаются
с двух символов подчеркивания и заканчиваются тоже двумя символами подчер си-
вания.) Например, можно использовать команду
echo FILE ;
ее результат выглядит следующим образом:
c:\program files\apache group\apache\htdocs\testvar2.php
В языке РНР имеется и множество других встроенных констант. Например, констакты
E_ALL и E_ERR0R можно использовать для управления процессом обработки ошибок в РНР.
Эти константы описаны в следующем разделе.
66 Часть II. Переменные и данные
OfyaJotnica соо^ш^ний о<$ oiuuSicax
При возникновении проблем с выполнением сценария интерпретатор РНР выдает сообщения
об ошибках. Существуют следующие типы сообщений.
•/ Сообщение об ошибке (error message). Это сообщение выдается при возникновении
проблем, препятствующих выполнению сценария. Сценарий отображает
сообщение об ошибке и прекращает свою работу. Чтобы помочь идентифицировать
проблему, такое сообщение должно содержать как можно
больше информации. Вот пример типичного сообщения об ошибке:
Parse error: parse error in c:\test.php on line 6
Такие сообщения об ошибках часто выдаются при отсутствии символа-
разделителя (точки с запятой, кавычек или скобок).
» Предупреждение (warning message). Предупреждающее сообщение выдается
в том случае, когда интерпретатор РНР встречает проблему, но эта проблема
не препятствует выполнению сценария. Предупреждающие сообщения указывают
на вероятную некорректность кода. Необходимо идентифицировать источник
возникновения сообщения, а затем решить, нужно ли изменять сценарий.
Например, если не указать имя переменной в качестве параметра
функции p r i n t _ r — написать p r i n t _ r (), а не p r i n t _ r ($varname), —
появится следующее сообщение:
Warning: print_r () expects at least 1 parameter, 0 given in
d:\testl.php on line 9
Поскольку это предупреждение, а не сообщение об ошибке, то после выполнения
функции p r i n t _ r работа сценария продолжится. Предупреждение
обычно указывает на более серьезную проблему, а не содержит простое уведомление.
В этом случае необходимо устранить проблему.
•S Уведомление (notice). Такое сообщение выводится в том случае, когда в сценарии
РНР встречается конструкция, которая может быть и ошибочной,
и правильной. Обычно уведомление выводится в ответ на попытку отображения
на экране несуществующих переменных. Рассмотрим пример:
Notice: Undefined v a r i a b l e : age in testing.php on l i n e 9
Сообщения об ошибках, предупреждения и уведомления содержат имя проблемного файла
и номер строки, в которой возникла проблема.
Типы отображаемых сообщений об ошибках зависят от установленного уровня проверки
ошибок. Необходимо видеть все сообщения об ошибках, но далеко не все предупреждения
и уведомления. (Зачастую единственная проблема с уведомлениями — это сами уведомления;
при этом код работает правильно.) Можно сделать так, чтобы предупреждающие сообщения
и уведомления отображались только во время отладки сценария, но не после того, как клиенты
начнут использовать приложение. Все сообщения об ошибках можно записывать в журнал,
чтобы они не выводились для пользователей, а вы могли их потом просмотреть.
Изменение уровня проверки ошибок для Web-узла
Уровень проверки ошибок для Web-узла определяется в файле php. i n i . Если вы являетесь
администратором модуля РНР и имеете доступ к файлу php. i n i , то сможете изменить
уровень проверки ошибок. Если вы не являетесь администратором, то можете изменить уровень
обработки ошибок для каждого сценария в отдельности, как будет описано в следующем
Глава 4. Использование переменных в сценариях РНР 67
разделе. (Более детальную информацию о настройках, содержащихся в файле p h p . i n i,
можно найти в приложении А.)
Для того чтобы определить текущий уровень обработки ошибок, откройте файл p h p . Lni
в текстовом редакторе и найдите строку, подобную следующей:
e r r o r _ r e p o r t i n g = E_ALL; d i s p l a y a l l e r r o r s , warnings and n o t i c es
(выводить все ошибки, уведомления и предупреждения)
Эта инструкция включает обработку всех типов ошибок и вывод сообщений о них. 1 'тот
режим полезен при разработке сценария. Однако после передачи сценария пользователям
предупреждения и уведомления отображать не стоит.
Обратите внимание на то, что в приведенном выше примере точка с запятой находится
после значения E_ALL, а не в начале строки. Точка с запятой — это символ, обозначаю] ций
комментарий в файле p h p . i n i . Поэтому текст в строке после точки с запятой— тагько
комментарий, а не часть команды. Если бы точка с запятой располагалась в начале строки, то
комментарием считалась бы вся строка и данная команда не выполняла бы никаких действий.
При внимательном изучении файла p h p . i n i вы, вероятно, найдете нескохько
закомментированных команд. Эти инструкции включены как примеры, а не как
выполняемые команды. Инструкции файла p h p . i n i без точки с запятой в на1 але
строки являются действующими.
E_ALL— это встроенная константа РНР, которая определяет все ошибки, предупре» рдения
и уведомления; E_NOTICE — встроенная константа, определяющая уведомления. Эти
две константы можно использовать в следующей конструкции:
e r r o r _ r e p o r t i n g = E_ALL & ~E_NOTICE
Наличие E_ALL требует отображения всех сообщений об ошибках, предупрежде та
и уведомлений. Однако использование второго параметра ~E_N0TICE приводит к тому, что
уведомления отображаться не будут. В результате будут отображаться только сообщеню об
ошибках и предупреждения. Этот метод позволяет очень легко определить уровень проверки
ошибок, не задавая перечень всех типов ошибок, которые вы хотите отобразить.
Две инструкции, приведенные в этом разделе, используются наиболее часто. Чтобы устг повить
уровень обработки ошибок, можно использовать и другие константы. Однако констант
E_ALL и E_NOTICE обычно достаточно для большинства сценариев. Список всех констант
можно найти в конфигурационном файле p h p . i n i . Для получения более детальной информации
об установке уровня обработки ошибок прочтите интерактивное руководство по языку Р IP.
Можно отказаться от вывода сразу всех сообщений об ошибках. Иногда нежелательно показывать
пользователям сгенерированные интерпретатором РНР сообщения об ошибках 1ли
предупреждающие сообщения, поскольку они могут содержать компрометирующую информацию.
Обычно при тестировании сценария сообщения об ошибках сохраняются в файле
журнала. Эта процедура будет описана в этой главе ниже.
Чтобы отключить вывод сообщений об ошибках, найдите в файле p h p . i n i строку d i s -
p l a y _ e r r o r s = On и измените значение параметра On на Of f.
Для того чтобы внесенные изменения вступили в силу, после любой модифкка-
ции файла p h p . i n i необходимо перезапустить Web-сервер.
Изменение уровня проверки ошибок в сценарии
Если вы хотите установить уровень проверки ошибок для конкретного сценария, добавьте
в начало сценария команду
error_reporting(ОПЦИИ) ;
л> ч
68 Часть //. Переменные и данные
ОПЦИИ— это одна из встроенных констант, рассмотренных в предыдущем разделе. Например,
добавив в начало сценария следующую инструкцию, можно обеспечить вывод всех
сообщений об ошибках, предупреждений и уведомлений:
error_reporting(E_ALL);
Предположим, что в файле php. i n i уровень обработки ошибок установлен в значение
E_ALL. Такой уровень обработки ошибок может вполне подходить для разработки сценариев,
но после передачи сценария пользователям желательно отменить вывод уведомлений.
Чтобы отменить настройки, заданные в файле php. i n i , можно добавить к готовому сценарию
инструкцию
error_reporting(E_ALL & ~E_N0TICE) ,-
Можно так определить уровень обработки ошибок, чтобы не отображались никакие сообщения.
Для этого используйте команду
error_reporting(0) ;
В готовых отлаженных сценариях вывод предупреждений и сообщений об ошибках
обычно отключают. Не нужно, чтобы пользователи видели сообщения об ошибках, которые
выдает интерпретатор РНР, потому что информация в таких сообщениях может представлять
угрозу для безопасности сервера. Однако вы можете захотеть самостоятельно просматривать
любые сообщения об ошибках. Используя данную функцию с параметром 0, можно отключить
отображение сообщений об ошибках, но одновременно записывать такие сообщения
в файл журнала. Пользователи не увидят сообщений, а вы сможете их просматривать. Запись
сообщений в файл журнала описана в следующем разделе.
Запись сообщений в файл журнала
Сообщения об ошибках и предупреждения интерпретатора РНР можно записывать в файл
журнала. При этом наряду с записью сообщений в журнал можно отображать или не отображать
их на экране для обычных пользователей.
В журнал можно записывать сообщения об ошибках для всего узла. Для этого следует
внести изменения в файл php. i n i , если вы имеете к нему доступ. Откройте файл php. i n i
и найдите строку
log_errors = Off
Значение Off необходимо изменить на On. Нужно также указать, куда записывать сообщения
об ошибках. Чтобы сделать это, найдите строку
;error_log = имя_файла
Теперь удалите точку с запятой в начале строки, превратив комментарий в действующую
инструкцию. Замените значение имя_фашш на путь к файлу, в который вы хотите сохранять
сообщения об ошибках. Например, можно использовать команду
error_log = c:\temp\php_error_log ,
Необходимо указывать существующий каталог (в Windows он часто называется также
папкой). Для того чтобы сообщения об ошибках можно было записывать в указанный файл,
необходимо создать каталог с : \temp. При этом файл создавать не обязательно. Если интерпретатор
РНР сможет найти указанный каталог, то он самостоятельно создаст требуемый файл.
Чтобы внесенные в файл php . i n i изменения вступили в силу, необходимо перезапустить
Web-сервер.
Глава 4. Использование переменных в сценариях РНР 69
(D
Расширенная обработка ошибок
В этом разделе описываются дополнительные возможности обработки ошибок. Новичкам
совсем не обязательно читать этот раздел. Его следует изучить только после того, как вы освоите
методы программирования на языке РНР, описанные в оставшейся части книги.
Стандартных сообщений РНР об ошибках может оказаться недостаточно. Например вы
чувствуете, что сценарий работает неправильно, хотя интерпретатор РНР не обнаруживает
никаких ошибок. Допустим, вы пишете сценарий проектирования дома. В таком случае, (ели
высота двери, определяемая переменной $height_of_door, больше высоты дома
$height_of__house, — это явно неправильно. Вам это известно, а интерпретатору РНР —
нет. Он не распознает эту ситуацию как ошибку. Чтобы интерпретатор РНР проверял эту
ошибку в сценарии, можно написать следующий код:
i f ($height_of_door > $height_of_house)
{
t r i g g e r _ e r r o r ( " I m p o s s i b l e c o n d i t i o n " , E_USER_ERROR);
}
Оператор i f более подробно рассматривается в главе 7.
Параметр E_USER_ERROR свидетельствует о том, что условие является ошибочным.
Строка I m p o s s i b l e c o n d i t i o n является сообщением, которое будет отображаться при юз-
никновении данной ошибки. Если условие истинно, будет выводиться следующее сообщение:
Fatal error: Impossible c o n d i t i o n in d : \ t e s t e r r . p h p on l i n e 9
Сценарий остановится в этой точке, поскольку интерпретатору РНР было указано, что это
ошибка, а не предупреждение или уведомление. Если в качестве параметра вместо
E_USER_ERROR указать E_USER_WARNING или E_USER_NOTICE, то РНР будет обрабагы-
вать данную ситуацию как предупреждение или уведомление соответственно.
Если вы хотите определить свой собственный способ обработки ошибок, а не использовать
стандартные процедуры РНР, то можно написать собственные операторы передачи сообщений,
записи в журнал, отправки электронной почты или остановки сценария. Например,
с помощью следующего кода можно вывести пользователю сообщение об ошибке и прервать
выполнение сценария:
i f ($height_of_door > $height_of_house)
{
echo "Это невозможно<Ьг>";
e x i t () ,-
}
Если значение $ h e i g h t _ o f _ d o o r больше значения переменной $ h e i g h t _ o f _ h o u зе,
будет выведено сообщение об ошибке и функция e x i t () прервет выполнение сценария. Никакие
операторы больше выполняться не будут.
Сообщение об ошибке можно записать в файл журнала, воспользовавшись функцией
e r r o r _ l o g (message, 3, имя_файла_журнала) ,-
Например, можно использовать следующий блок if:
i f ($height_of_door > $height_of_house)
{
e r r o r _ l o g ("Дверь выше дома", 3, " / t e m p / e r r _ l o g " );
e x i t ( ) ;
}
После добавления в сценарий этого оператора, если значение $ h e i g h t _ o f _ d o o r превышает
$ h e i g h t _ o f _ h o u s e , в файл журнала / t e m p / e r r _ l o g будет записано сообщение
Дверь выше дома. Значение 3 в этом операторе означает запись сообщения в указанный
70 Часть II. Переменные и данные
файл журнала. При этом каталог /temp должен существовать. Если файла журнала не существует,
интерпретатор РНР создаст его самостоятельно.
В качестве альтернативы в случае ошибки можно отправить себе почтовое сообщение.
Для этой цели, так же как и для записи сообщения об ошибке в файл журнала, можно использовать
оператор error_log. Значение 1 в списке параметров функции e r r o r _ l o g означает
передачу сообщения по указанному адресу электронной почты:
error_log ("Дверь выше дома", 1, "me@mymail.com");
Использование этого оператора предполагает, что сообщение электронной почты можно
отправить из PHP-сценария. Более подробно этот вопрос рассматривается в главе 13.
С другой стороны, стандартные ошибки РНР можно перехватывать и обрабатывать по-
своему. Можно определить операторы, которые будут выполняться при возникновении
ошибки. Например, можно потребовать, чтобы интерпретатор РНР отображал созданное вами
сообщение или выполнял требуемые инструкции. Допустим, вам захотелось получать сообщения
об ошибках по электронной почте или открывать и закрывать некоторые файлы перед
завершением выполнения сценария.
Для обработки ошибок можно написать собственный код и потребовать от интерпретатора
РНР использовать его всякий раз при возникновении ошибок. Чтобы это реализовать, необходимо
написать код обработки ошибок и сохранить его как функцию. Потом можно вызывать
эту функцию всякий раз при возникновении ошибок. (Принципы создания функций
описаны в главе 8.) Чтобы при обработке ошибок интерпретатор РНР использовал созданную
функцию, а не стандартную процедуру, воспользуйтесь функцией
set_error_handler(имя_функции);
Например, можно использовать следующую команду:
set_error_handler(my_error_handler);
Детальные рекомендации по созданию обработчика ошибок my_error_handler содержатся
в главе 8.
Еще один метод обработки ошибок средствами языка РНР состоит в использовании
функции die, которая выводит сообщение при некорректной работе функции. Этот вопрос
подробно обсуждается в главе 8.
Глава 4. Использование переменных в сценариях РНР 71
Глава 5
Работа с данными
В э/Яой главе...
> Что такое типы данных
> Выполнение арифметических операций
> Обработка текстовых строк
> Использование даты и времени
временные могут содержать значения различных типов. В свою очередь, над
данными различных типов можно выполнять различные операции. Например,
можно складывать два числа— 1+2. Однако сложение двух символов (а+Ь) выполняется
совсем по-другому. В этой главе вы узнаете, какие типы данных существуют в языке ГНР
и как их можно использовать.
У/Сипи данных
В переменных РНР можно хранить данные следующих простых типов.
* Целый тип (integer) позволяет оперировать с целыми числами (без дробной
части), такими как -43, 0, 1, 27 или 543 8. Допустимый диапазон целочисленных
значений в общем случае зависит от операционной системы. Одн жо
обычно допустимые значения переменных целочисленного типа лежат в пределе
от -2 до 2 миллиардов.
S Тип с плавающей точкой (floating point) позволяет манипулировать числами
с дробной частью, например 5 .24 или 123 .456789. Такие числа часто называются
действительными (real number) или числами с плавающей точкой (flc at).
S Строковый тип (string) обеспечивает хранение последовательности символов,
например привет. На длину текстовой строки практически не накладывается
каких-либо ограничений.
•S К булевому (логическому) типу (boolean) относятся два значения: TFUE
(истина) и FALSE (ложь). Данный тип более подробно рассматривается ниже.
Присваивание типов данных
В большинстве языков программирования требуется, чтобы перед использованием кажг зая
переменная была предварительно связана с типом. Однако язык РНР является гораздо менее
формальным. В нем нет необходимости явно определять тип переменных. Интерпрета--ор
РНР самостоятельно проверяет значение, присвоенное некоторой переменной, и после этого
связывает с ней соответствующий тип данных. В общем случае это является очень полезным.
При этом следует отметить, что процедура автоматического определения типа переменной
работает достаточно точно.
Л
Истина или ложь: булевы значения
Переменные логического типа могут содержать два значения: T R U E (истина) и F A L S E (ЛОЖЬ). В основном
они используются в условных выражениях. Например, результатом обработки выражения $а>$Ь будет либо
TRUE (ИСТИНа), ЛИбо FALSE (ЛОЖЬ).
В языке РНР ложными считаются следующие значения.
• строка " F A L S E " (состоящая из символов как в верхнем, так и в нижнем регистрах);
• целое значение 0;
• значение с плавающей точкой о . о;
• пустая строка;
• строка, содержащая единственный символ " о " ;
• константа NULL.
Все остальные значения соответствуют логическому значению TRUE. При выводе булевской переменной с помощью
функции echo отобразится пустая строка, если в этой переменной содержится значение F A L S E , И 1 - в противном
случае. Логические значения зачастую применяются в качестве возвращаемых значений функций. Это позволяет
определить, успешно ли было завершено ее выполнение. Вопросы совместного использования функций
и логических переменных более подробно рассматриваются в главе 8.
По мере необходимости в языке РНР автоматически выполняется и преобразование типов. Например,
в следующем фрагменте требуемое преобразование выполняется без малейших проблем:
$firstNumber = 1 ; # Хранится как целое
$secondNumber = 1.1;# Хранится как число с плавающей точкой
$sum = $firstNuinber+$secondNumber;
С формальной точки зрения, третье выражение лишено смысла, поскольку в нем используются
операнды различных типов. Однако интерпретатор РНР выполняет преобразование целого
значения в значение типа f l o a t , и суммирование двух переменных происходит без каких бы то
ни было проблем. Следует заметить, что вся эта процедура выполняется автоматически.
Приведение типов
Иногда интерпретатору РНР не удается правильно определить тип переменной. Тогда при
ее использовании будет выдана ошибка об использовании неверного типа. В этом случае
нужно самостоятельно определить тип переменной. Такая операция называется приведением
типов (type casting). Явно задать тип можно следующим образом:
$newint = ( i n t ) $ v a r l;
$newfloat = (float)$varl;
$newstring = (string)$varl;
Значение переменной, расположенной справа от символа равенства, присваивается переменной
с указанным типом, находящейся слева. Так, значение $varl присваивается переменной
$newint с типом i n t e g e r ( ( i n t ) ).
При приведении типов будьте очень внимательны. Иногда это может привести
к непредсказуемым результатам. Например, при преобразовании действительного
значения в целое теряется дробная часть. Например, если в переменной $number
содержится значение 1. 8, то после его преобразования в целое — $newnumber
= (int) $number — в переменной $newnumber будет содержаться значение 1.
Определить тип переменной можно с помощью функции
var_dump ($myvariable) ,-
Глава 5. Работа с данными 73
Например, следующее выражение позволяет определить тип переменной $checkvar:
var_dump($checkvar) ;
В качестве результата будет получено выражение i n t (27), что свидетельствует о том,
что в переменной $checkvar содержится целочисленное значение 27.
Padotna с числами
Типы данных f l o a t и i n t e g e r являются числовыми. Инициализацию переменных э гих
типов можно осуществить таким образом:
$intvar =3;
$floatvar =9.3;
При этом интерпретатор РНР автоматически разместит заданные значения в оперативной
памяти с учетом их типа.
Выполнение математических операций
Язык РНР позволяет выполнять над числовыми переменными различные операции. При
этом необходимо задать два операнда и соответствующий символ математической операции.
Например, операцию сложения (+) можно выполнить следующим образом:
1+2
То же самое можно осуществить и с переменными:
$varl + $var2 ;
При использовании чисел в математических операциях их не следует заключать в кавычки.
В противном случае они будут рассматриваться как строковые переменные, над которы ии
нельзя выполнять необходимые арифметические операции. Однако в отличие от других я; ы-
ков программирования в РНР по необходимости строки автоматически преобразуются в числовой
формат. Например:
$varl = " 1 " ;
$var2 = 2;
$total • $varl+$var2;
Формально переменные $varl и $var2 просуммировать нельзя, поскольку в $varl содержится
текстовая строка. Однако при обработке этого выражения интерпретатор РНР автоматически
преобразует строку " 1" в числовое значение 1 и корректно выполнит эту операцию.
В следующем фрагменте также выполняется автоматическое преобразование текстов эй
строки в число, однако конечный результат уже не так очевиден:
$varl = "х";
$var2 = 2;
$total = $varl+$var2;
Поскольку РНР не может преобразовать символ " х" в числовое значение, то при выпс л-
нении сложения вместо него используется значение 0. Таким образом, результат сложен 1Я
переменных $varl и $var2 будет равен 2. Преобразование типов далеко не всегда привод-IT
к получению желаемых результатов. Безусловно, автоматическое приведение типов являет :я
очень удобным и позволяет сэкономить массу усилий. Однако нужно соблюдать осторожность,
поскольку оно может привести к получению непредвиденных результатов, как показано
в предыдущем примере.
Иногда интерпретатору РНР не удается корректно обработать выражения, которые понятны
человеку. Например:
74 Часть II. Переменные и даннь е
$varl = "2,000";
$var2 = 2;
$total = $varl+$var2,-
Хотя человеку и понятно назначение запятой в значении первой переменной, интерпретатору
РНР — нет. Он преобразует строку "2,000" в числовое значение 2, и в результате после
выполнения сложения в переменной $ t o t a l будет содержаться значение 4.
В табл. 5.1 приведены основные математические операции языка РНР.
Таблица 5.1. Математические операции РНР
Операция Описание
+ Сложение двух чисел
Вычитание второго числа из первого
* Умножение двух чисел
/ Деление первого числа на второе
% Остаток от деления (или деление по модулю). Например, в результате вычисления выражения
$а = 13%4 в переменной $а будет содержаться значение 1
Порядок выполнения операций
Несколько математических операций можно выполнять одновременно. Например, в следующем
выражении используется сразу три операции:
$ t o t a l = 1+2*3+1,-
Порядок выполнения операций очень важен, поскольку от этого зависит конечный результат.
В языке РНР сначала выполняются операции умножения и деления и лишь потом
сложение и вычитание. При равном приоритете операций действия выполняются слева направо.
Так, в приведенном выше примере значение переменной $ t o t a l становится равным 8.
$ t o t a l = 1+2*3+1 #сначала выполняется умножение
$ t o t a l = 1+6+1 #затем - левая операция сложения
$total = 7+1 #затем - сложение справа
$ t o t a l = 8
Изменить последовательность выполнения арифметических операций можно с помощью
круглых скобок. Тогда математические операции в скобках будут выполняться в первую очередь.
Например, предыдущее выражение можно переписать в следующем виде:
$ t o t a l = (l+2)*3+l;
После выполнения всех математических преобразований в переменной $ t o t a l будет содержаться
значение 10:
$ t o t a l = (l+2)*3+l #сначала выполняется сложение в скобках
$ t o t a l = 3*3+1 #затем умножение
$result = 9+1 #и наконец сложение
$result = 10
Порядок вычислений в скобках соответствует общим правилам выполнения арифметических
операций. Например, в выражении (3+2*5) сначала выполняется умножение, а затем
— сложение. Естественно, внутри скобок можно использовать другие скобки и таким образом
изменять последовательность выполнения операций.
Лучше руководствоваться поговоркой "Семь раз отмерь — один раз отрежь"
и использовать скобки во всех случаях, когда арифметическое выражение выглядит
неоднозначным.
Глава 5. Работа с данными 75
Инкрементирование и декрементирование
Увеличить значение переменной на 1 можно следующим образом:
$counter • $counter+l;
Однако для этого можно воспользоваться и сокращенной конструкцией языка РНР:
$counter++;
Например, рассмотрим выражения
$counter=0;
$counter++;
echo $counter;
В результате в переменной $counter будет содержаться значение 1 (что и будет выведено
на экран). Точно так же можно выполнить и вычитание:
$counter--;
Для увеличения значения переменной на 1 можно воспользоваться еще одним выражением:
"+=1". С помощью такой конструкции значение переменной можно изменить прсиз-
вольным образом. Например:
$counter+=2;
$counter-=3;
$counter*=2;
$counter/=3;
В приведенных примерах выполняется увеличение значения переменной $counter Hi. 2,
его уменьшение на 3, умножение на 2 и деление на 3 соответственно.
Использование встроенных математических функций
Более сложные математические вычисления можно выполнять с помощью встроенных
функций. (Функции более подробно рассматриваются в главе 8.) Например, если нужно найти
квадратный корень некоторого значения, нет необходимости создавать новую функцию, так
как она уже существует. Например:
$rootvar = sqrt(91);
$rootvar = sqrt($number);
В первом выражении вычисляется квадратный корень числа 91, а во втором — значения,
содержащегося в переменной $number.
Для округления действительного числа к ближайшему большему целому можно воспользоваться
функцией
$upnumber = ceil(27.63);
Результатом этого выражения будет 28. Существует аналогичная функция, которая округляет
действительное значение к ближайшему меньшему целому. Например:
$downnumber = floor(27.63);
В этом случае функция f l o o r () вернет значение 27.
В языке РНР определено и много других математических функций: для выполнения простых
операций, например поиска максимума, минимума или генерирования случайных чисел,
или более сложных— вычисления синуса, тангенса или преобразования чисел в двоичный
или восьмеричный формат. Перечень математических функций вы найдете в приложении Б
Форматирование чисел для вывода
Зачастую числа необходимо отображать в каком-то определенном формате, например использовать
запятую для разделения тысяч или использовать два знака после запятой для обозначения
76 Часть II. Переменные и даннь \е
денежной суммы. Однако при использовании РНР числа хранятся и отображаются в наиболее эффективном
формате. Так, если в переменной содержится число 10.00, он будет выведено как 10.
Если же нужно вывести это число в другом виде, придется явно указать соответствующий формат.
Для определения формата в РНР предназначена функция number_f ormat () с синтаксисом
number_format(число, количество_десятичных_знаков, "разделитель!",
"разделитель2")
и со следующими параметрами:
•S число. Форматируемое число, которое является обязательным аргументом.
«^ количество_десятичных_знаков. Определяет количество знаков после запятой.
Если этот параметр отсутствует, то по умолчанию его значение равно 0 и, таким
образом, число округляется до ближайшего целого числа (т.е. отображается без
дробной части). Если используются аргументы разделительI и разделитель!, то
количество_десятичных_знаков является обязательным параметром.
•S разделителе. Определяет символ, который будет использоваться в качестве
символа-разделителя целой и дробной частей. По умолчанию таким символом
является точка. Параметр разделитель! является обязательным, если используется
параметр разделитель!.
S разделитель!. Определяет символ, который будет разделителем в целой части
числа. По умолчанию в качестве такого символа используется запятая.
В табл. 5.2 приведено несколько примеров использования функции number_f ormat ().
Таблица 5.2. Примеры использования функции number_f ormat ()
$number Формат Результат
12321
12321.66
12321.66
12321.6
12321
12321.66
number_format($number)
number_format($number, 2)
number_format($number)
number_format($number, 3)
number_format($number, 0,
number_format($number, 2,
12,321
12,321.66
12,322
12,321.600
12.321
12321.66
После форматирования число конвертируется в текстовую строку. Поэтому все
арифметические операции необходимо выполнить до форматирования.
Для более сложного форматирования в языке РНР предназначены функции p r i n t f ()
и s p r i n t f ().
S Функция p r i n t f () позволяет напрямую выводить число в заданном формате.
S Функция s p r i n t f О сохраняет форматируемое число в переменной.
Функции p r i n t f () и s p r i n t f () одновременно позволяют форматировать как строки,
так и числовые значения. Более подробно эти функции рассматриваются ниже, в разделе
"Форматирование текстовых строк".
Глава 5. Работа с данными 77
Parfo/na со cfnfiOKcuiu символов
К символам (character) относятся буквы, числа и знаки пунктуации. Строка символов (1ли
текстовая строка) (character string) является последовательностью символов. Если числа используются
в качестве символов, они сохраняются так же, как и буквы, т.е. над ними невозможно
выполнять арифметические операции. Например, номер телефона обычно хранится
как строка, поскольку над ним не нужно выполнять никаких математических действий.
Для присваивания переменной строкового значения используются одинарные или двойные
кавычки. Это позволяет указать интерпретатору РНР начало и конец последовательно :ти
символов. Например, следующие два выражения идентичны:
$ s t r i n g = "Здравствуй, мир!";
$ s t r i n g = 'Здравствуй, мир!';
-~ ^шшштшшшшшшштш.мшякешаг'"' '"ТЗШШШШЯ
| ^ И * ^ Работа с длинными текстовыми строками
\. В языке РНР имеется neredoc-механизм, позволяющий сохранять в переменных длинные последовательное гм
] символов, которые могут занимать несколько строк. Этот механизм позволяет указать начало и конец стро :и
t символов с использованием следующего синтаксиса:
[ $имя_переменной - <«МЕТКА
j текст
[МЕТКА;
\ Здесь МЕТКА представляет собой произвольное имя. Если в переменной $имя_переменной необходиь о
I сохранить некоторый текст, его нужно заключить между метками МЕТКА. Тогда при обработке этого
| выражения интерпретатор РНР сможет определить, где находится начало и конец строки, и разместит текст !
| в переменной $имя_переменной.
j В строке, созданной с помощью neredoc-механизма, могут содержаться переменные и специальные символн ;
| как и в обычной строке в двойных кавычках. (Такие строки более подробно будут рассматриваться ниж*
I в разделе "Сравнение строк в одинарных и двойных кавычках".)
i Ниже приведен пример создания строки с использованием легес/ос-механизма.
I $distance = 10;
{ $herevariable = <«ENDOFTEXT
j Расстояние между
i Лос-Анджелесом и Пасаденой
j составляет $distance миль.
| ENDOFTEXT;
j echo: $herevariable;
j При выводе значения переменной $ h e r e v a r i a b l e на экран будет получено следующее:
j Расстояние между
| /Лос-Анджелесом и Пасаденой
I составляет 10 миль.
) Однако при использовании таких строк нужно соблюдать осторожность. К выбору меток интерпретатор РН3
\ предъявляет достаточно жесткие требования. При первом появлении МЕТКА (в данном примерз
| ENDOFTEXT) должна находиться в конце первой строки так, чтобы за ней не было ни одного символа, даж;
\ пробела. То же самое касается и завершающей метки: за ней не должно быть никаких символов, кроме точкл
j с запятой. Если эти правила не выполняются, символ конца строки не будет распознан, интерпретатор PHI1
i продолжит поиск этого символа в оставшейся части сценария и в конечном счете будет сгенерировано
i сообщение об ошибке.
78 Часть II. Переменные и данные
Использование в строках специальных символов
В языке РНР определены специальные символы, \п и \ t , которые можно использовать в
строках. Символ \п является символом перехода на новую строку. Например:
$ s t r i n g = "Здравствуй, \пмир";
echo $string;
В результате будет выведено следующее:
Здравствуй,
мир
Символ \ t является символом табуляции. Например, использование фрагмента
$ s t r i n g = "Строка 1 \n\tcTpc-Ka 2";
echo $string;
приведет к тому, что вторая строка будет выведена с отступом:
Строка 1
строка 2
Специальные символы можно использовать только в строках, заключенных
в двойные кавычки. При использовании одинарных кавычек с этими символами
не будет связано никакого особого смысла. Различия между этими двумя представлениями
строк рассматриваются в следующем разделе.
Сравнение строк в одинарных и двойных кавычках
Строки в одинарных и двойных кавычках обрабатываются интерпретатором РНР по-
разному.
S Последовательность символов, заключенная в одинарные кавычки, хранится
"как есть", за исключением символа \ ', который хранится как символ апострофа.
(Более подробно этот вопрос рассматривается в следующем разделе.)
S В строках в двойных кавычках обрабатываются переменные и специальные
символы, и лишь после этого может использоваться сама строка.
В следующих примерах проиллюстрированы различия между строками в одинарных
и двойных кавычках.
Если имя переменной разместить в двойных кавычках, интерпретатор РНР будет использовать
ее значение, а если в одинарных — ее имя. Например:
$name = "Сэм";
$outputl = "$name";
$output2 = '$name';
echo $outputl;
echo $output2;
При выполнении этого выражения будет получен следующий результат:
Сэм
$name
Аналогично обрабатываются и специальные символы. Если их разместить в строке
с двойными кавычками, то специальные символы будут интерпретироваться, а если в строке
с оди-нарными кавычками — нет. Эти отличие проиллюстрированы в следующем примере:
$ s t r i n g l = "Строка в \п\ЗДвойных кавычках";
$string2 = 'Строка в \п\Одинарных кавычках';
Глава 5. Работа с данными 79
Первая строка отобразится так:
Строка в
двойных кавычках
а вторая — так:
Строка в \п\Одинарных кавычках
Наличие разных кавычек определяет, каким образом будут обрабатываться другие кавычки
в текстовой строке. Например:
$number = 10;
$stringl = "В очереди находится '$number' людей.";
$string2 = 'В очереди находится "$number" людей.';
echo $stringl, "\n";
echo $string2;
При обработке этого выражения будет получен следующий результат:
В очереди находятся '10' людей.
В очереди находятся "$number" людей.
Обратите внимание, что, несмотря на то, что в строке $ s t r i n g l имя переменной
$number заключено в одинарные кавычки, двойные кавычки приводят к интерпретации ее
значения, а не имени. При выводе второй строки происходит обратное. Поскольку вся строка
заключена в одинарные кавычки, то она выводится без интерпретации переменных, им«на
которых включены в нее.
Сокрытие символов
Иногда необходимо, чтобы в строках с двойными кавычками символы использовались
"как есть", т.е. без учета их специального назначения. Например, может понадобиться, чтобы
символ доллара интерпретировался как обычный символ, а не как первый символ имени переменной.
Такого эффекта можно добиться с помощью символа обратной косой чер^ы
(backslash) (\). Например:
$string = 'Имя переменной — $ v a r l ' ;
$ s t r i n g = "Имя переменной - \$varl";
При выводе обе строки будут выглядеть одинаково:
Имя переменной — i s $varl *•
Пусть, например, необходимо присвоить строковой переменной следующее значение:
$ s t r i n g = 'Где находится дом О'Хары?';
echo $string;
Это выражение будет интерпретировано неправильно, поскольку после символа О следу ;г
символ кавычки ('), который будет рассматриваться как символ конца строки. При выводе
строки будет получен следующий результат:
Где находится дом О
Поэтому интерпретатору РНР необходимо указать, что символ кавычки нужно отображать
как символ апострофа, а не считать его концом строки. Для этого символ обратной кэ-
сой черты нужно поместить перед символом кавычки, т.е. для корректного отображения
строки нужно внести следующие изменения:
$string s 'Где находится дом 0\'Хары?';
Точно так же, если в строке, заключенной в двойные кавычки, необходимо разместить
символ ", то перед ним нужно разместить символ \.
80 Часть II. Переменные и данные
Объединение текстовых строк
Процедура объединения текстовых строк называется конкатенацией (concatenation).
В языке РНР для выполнения конкатенации используется операция точки (.). Рассмотрим
следующий пример:
$ s t r i n g l = "Здравствуй,";
$string2 = "мир!";
$ s t r i n g a l l = $ s t r i n g l . $ s t r i n g 2;
echo $ s t r i n g a l l;
При выполнении этого фрагмента будет получен следующий результат:
Здравствуй,мир!
Обратите внимание, что в результирующей строке не содержится символ пробела (""),
поскольку он отсутствует в обеих исходных строках. Для добавления символа пробела между
отдельными словами нужно объединить три строки: две переменные и непосредственно
строку с символом пробела. Например:
$ s t r i n g a l l = $ s t r i n g l . " ".$string2;
Для добавления символов к существующей строке можно воспользоваться операцией . =.
Например, предыдущие примеры можно модифицировать таким образом:
$ s t r i n g a l l = "Здравствуй,";
$ s t r i n g a l l .= " мир!";
echo $ s t r i n g a l l;
В результате получим следующее:
Здравствуй, мир!
Манипуляция строками
Для обработки текстовых строк язык РНР предоставляет множество встроенных функций.
(Более подробно функции рассматриваются в главе 8.) С помощью стандартных функций
в строке можно находить подстроки или отдельные символы, заменять часть строки новыми
символами, разбивать строку, находить длину строки и т.д.
Зачастую в начале или в конце строки нужно удалить ненужные пробелы. Это можно
осуществить следующим образом:
$ s t r i n g = trim($string) # удаляет пробелы в начале и в конце строки
$string = l t r i m ( $ s t r i n g ) # удаляет пробелы только в начале строки
$ s t r i n g = r t r i m ( $ s t r i n g ) # удаляет пробелы только в конце строки
С использованием функции str_word_count () строку можно легко разбить на отдельные
слова:
str_word_count("строка", формат)
Параметр формат может иметь два значения: 1 или 2. При использовании значения 1 результатом
выполнения функции str_word_count () будет простой массив, элементами которого
будут отдельные слова. При использовании значения 2 эта функция возвращает ассоциативный
массив, ключами которого будут позиции первых символов слов в строке. (Более
подробно массивы рассматриваются в главе б.) Если параметр формат отсутствует, возвращаемым
значением функции str_word_count () будет количество символов в строке. Рассмотрим
следующий пример:
$etring я "Подсчет слов";
$numberO?Words = str_word_oount($string);
Глава 5. Работа с данными 81
$wordl = str_word_count($string, 1);
$word2 = str_word_count($string, 2);
При выполнении этого фрагмента будут получены такие результаты:
$numberOfWords = 2
$wordl[0] = Подсчет
$wordl[l] = слов
$word2[0] = Подсчет
$word2[9] = слов
Обратите внимание, что первое слово начинается с позиции с 0 (а не с 1, как многие ivor-
ли бы предположить), а следующее— с позиции 9. Все эти вопросы более подробно рассматриваются
в главе 6 при обсуждении массивов.
Некоторые полезные функции, которые можно использовать для обработки текстовых
строк, приведены в табл. 5.3. Рассматривая примеры, не забывайте о том, что нумерация с ш-
волов в строке начинается с нуля.
Форматирование текстовых строк
В языке РНР все значения всегда выводятся в строковом формате. Другими словами, эе- •
зультатом функции echo является строка, даже если среди ее параметров содержатся числовые
значения. Рассмотрим такой пример:
$number = 4 ;
echo "У Салли $number детей.";
В результате выполнения этого фрагмента получим следующую строку:
У Салли 4 детей.
Несмотря на то что в переменной $number содержится число 4, функция echo отображает
его как часть символьной строки.
Форматирование данных является одним из важных этапов написания сценариев. Однако
функция echo оказывается недостаточно гибкой. В разделе "Форматирование чисел для вывода"
этой главы уже рассматривались возможности функции number_f ormat (), связанные
с форматированием чисел. Для форматирования строк в языке РНР также имеются ^ о-
полнительные возможности. Функции p r i n t f () и s p r i n t f () позволяют форматировать
строки, числа, а также их произвольную комбинацию.
Функции p r i n t f () и s p r i n t f () имеют следующий общий синтаксис:
printf("формат", $имя_переменной1, $имя__переменной2, ...);
$newvar = sprintf("формат", $имя_переменной1, $имя_переменной2, ...);
Функция p r i n t f () предназначена для вывода уже отформатированной строки, а функция
s p r i n t f () сохраняет ее в переменной. При этом обе функции позволяют обрабатывать
комбинацию чисел, строк и значений переменных. Параметр формат позволяет задать ша 5-
лон, в соответствии с которым будут форматироваться переменные $имя_переменной. Например,
следующее выражение является абсолютно корректным:
$newvar = sprintf("Здравствуй, мир!");
В этом выражении не выполняется никакого форматирования, и строка Здравствуй ,
мир! сохраняется в переменной $newvar. Однако строковые литералы можно объединять
с переменными с текстовыми символами, как показано в следующем примере:
--1?nboys = 3 ;
$ngirls = 2;
printf("%s парней и %s девушек", $nboys, $ngirls);
82 Часть II. Переменные и данныв
Таблица 5.3. Функции для обработки текстовых строк
Функция Описание Пример Результат
str_repeat("строю", Л)
s t r _ r e p l a ce
("а", "Ь "строга")
s t r c h r
("строга", "символ")
s t r i s t r
{"строка", "символ")
s t r l e n ( "строка")
s t r p os
("строка", "подстрока
s t r r c h r
{"строка", "символ")
s t r r e v l "строка")
s t r r p os
{"строка", "подстрока"
strtolower ("строга")
strtoupper ("строка")
s t r t r ("строга", "стр 1
"стр2")
s u b s t r
{"строка", п1, п2)
substr_count
{"строка", "sub")
s u b s t r _ r e p l a ce
("S", "Г", П, I)
u c f i r s t ( "строга")
ucwords ("строга")
Повторяет строку л раз
В строга заменяет все фрагменты а фрагментами b
Возвращает часть строки, начиная с символа и до
конца строки
Аналогична функции s t r c h r ( ) , но не учитывает
регистр
Возвращает длину строки
Возвращает позицию первого вхождения подстроки в
) строку
Аналогична функции s t r c h r ( ) , но осуществляет поиск
последнего фрагмента символа
Возвращает строку в обратном порядке
Возвращает позицию последнего вхождения подстроки
) в строку
Преобразует все символы строки в нижний регистр
Преобразует все символы строки в верхний регистр
, Заменяет все вхождения подстроки стр1 в строке
значением стр2
Возвращает часть строки, начиная с позиции л J
и заканчивая п2
Возвращает количество вхождений подстроки sub
в строку
Заменяет в строке s фрагмент из 1 символов, начиная
с позиции п, фрагментом г
Преобразует первый символ строки в верхний регистр
Преобразует первый символ каждого слова строки в
верхний регистр
$х = str_repeat("х", 5) ;
$а = "abc abc";
$s = str_replace("b", "i", $a);
$str = "aBc abc";
$sub = strchr($str, "b");
$str = "aBc abc";
$sub = stristr($str, "b");
$n = strlen("привет");
$str = "привет";
$n = strpos {$str, "и"),-
$str = "abc abc";
$sub = strrchr($str, "b");
$n = strrevl"abcde");
$str = "abc abc";
$n = strrpos($str, "be");
$str = strtolower("ДА");
$str = strtoupper("да");
$str = "aa bb cc";
$new = strtr($str, "bb", "xx");
$sstr = substr("привет", 2, 4);
$str = "abc ab abc";
$s = "be";
$n = substr_count($str, $s) ;
$s = "abc abc";
$t = substr_replace($s, "x", 2, 3);
$str = "а В с";
$str2 = ucfirst($str);
$str = "aa Bb cc";
$str2 = ucwords($str) ;
$x =
$s =
$sub
$sub
$n =
$n =
xxxxx
aic aic
= be
= Be abc
6
2
$sub = be
$n = edeba
$n = 5
$str = да
$str = ДА
$new = aa xx cc
$sstr = иве
$n = 2
$ t = abxbc
$str2 = А В с
$str2 = Aa Bb Cc
Строка %s представляет собой инструкцию форматирования, которая указывает футами
p r i n t f () на необходимость вставки значения переменной как строки. Таким образом, результатом
выполнения приведенного выше примера будет строка 3 парней и 2 девушек.
Символ % сообщает функции p r i n t f О о том, что дальше следует инструкция форматирования.
Инструкции форматирования имеют следующий общий формат:
%заполнитель-длина.точностьтип
В инструкции форматирования используются следующие параметры.
S Символ процента (%) является первым символом инструкции форматирования.
S Заполнитель. Символ-заполнитель, используемый для дополнения стрски
до заданной длины (этот параметр описывается ниже). Параметр
заполнитель может содержать пробел (по умолчанию), 0 или любой другой
символ, которому предшествует символ одинарной кавычки. Часто в качест ве
символа-заполнителя используется значения 01 или 0001.
S Символ выравнивания (-). При его использовании результат будет выравниваться
по левой стороне, в противном случае — по правой (режим по умолчанию).
S Длина определяет ширину выводимого значения. Если количество выводим >ix
символов меньше длины, то недостающее пространство заполняется символом-
заполнителем. Например, если длина равна 5, заполнитель— 0,
а форматируемое значение — 1, то в результате будет получена строка 00001
S . точность. Определяет, сколько десятичных знаков после точки долж ю
выводиться при форматировании действительных чисел.
S тип значения. Обычно используется строковый тип — s (string). Для выво на
чисел с плавающей точкой используется тип f (float).
Ниже приведено несколько примеров использования функции s p r i n t ? ( ).
$money = 30;
$pet = "Kitten";
$new = sprintfC'It costs $%03.2f for a %s.\n", $money, $pet);
$new2 = sprintf("%'.-20s%3.2f", $pet, $money);
echo $new;
echo $new2;
В результате выполнения этого фрагмента получим следующий результат.
I t costs $030.00 for a Kitten.
Kitten 30.00
Обратите внимание на то, что для форматирования значения переменной $money использ f-
ется шаблон 3.2 f (три цифры до десятичной точки и две после нее). Этот шаблон используеп :я
при формировании обеих строковых переменных, $new и $new2. В то же время в переменнс й
$new значение переменной $money дополняется символом 0, а в $new2 — пробелом.
При добавлении переменной $pet в переменную $new2 использовался шаблон ' . -20.
Значение 20 определяет количество символов, которые будут использоваться для переменней
$pet. Поскольку значение этой переменной K i t t e n занимает шесть символов, оставшееся
пространство дополняется символом-заполнителем (' .), т.е. дополнительно будет выведено
14 точек (.). Инструкция выравнивания (-) определяет, что строка K i t t e n будет выравниваться
по левому краю. В противном случае использовалось бы выравнивание по правому краю.
Зачастую необходимо вывести столбцы чисел. Пусть, например, имеется три числа: 12 . :i,
1 и 234.55. При использовании функции echo будет получен следующий результат:
84 Часть II. Переменные и данны э
12.3
1
234.55
Даже при использовании функции number_f ormat () для задания двух десятичных знаков
после точки нужный результат не будет достигнут:
12.30
1.00
234.55
Для вывода чисел в упорядоченном столбце лучше всего воспользоваться функцией
p r i n t f ( ) :
printf("%5.2f\n", $numberl);
printf("%5.2f\n", $number2);
printf("%5.2f\n", $number3);
Только теперь получен необходимый результат:
12.30
1.00 /
234.55
Для вывода числовых значений в данном случае использовался шаблон форматирования
%5. 2f \п. Рассмотрим его составные части более подробно.
S %. Первый символ инструкции форматирования.
/ 5. Определяет ширину, т.е. количество знаков, которое будет использоваться
для вывода чисел. Если количество цифр в числе меньше 5, то спереди
добавляются символы-заполнители (в данном случае пробелы). Поскольку
выравнивание справа используется по умолчанию, то символ выравнивания
не используется.
S 2. Определяет количество знаков после десятичной точки.
•S Тип f определяет, что числа будут выводиться как числа с плавающей точкой.
/ \п. Символ перевода строки.
Для того чтобы вывести число в денежном формате (со знаком $), можно воспользоваться
функцией s p r i n t f (). Например:
$newvariablename = sprintf("$%.2f", $oldvariablename);
В этом выражении форматируется значение переменной $oldvariablename, а результат
сохраняется в переменной $newvariablename. В следующем примере денежное значение
выводится в правильном формате:
$price = 25;
printf("$%.2f", $price);
В результате получим следующее:
$25.00
использование qounbt и в[гемени
Дата и время являются важными элементами сценариев. Поэтому язык РНР предоставляет
широкие возможности для их обработки. Компьютер хранит значения даты и времени в формате
timestamp в секундах. Поскольку этот формат использовать неудобно, в языке РНР имеются
различные встроенные функции для его преобразования.
Глава 5. Работа с данными 85
<.<?r~~5fe Формат timestamp используется в операционной системе Unix и отсчитывает ш-
ЛТря Л личество секунд, прошедших с 1 января 1970 года, 0 0 : 0 0 : 0 0 GMT. Этот формат
^JLLJ чрезвычайно удобен при вычислении временной разницы между двумя событ ия-
""^обно^ ми. Для этого достаточно просто вычесть одно значение из другого.
Форматирование даты
Для форматирования даты чаще всего используется функция d a t e ( ) . Она возвращает
строковое значение даты и времени в специальном формате. Функция d a t e О имеет с целующий
общий синтаксис:
$mydate = date("формат", $ times tamp);
Параметр $ times tamp содержит количество секунд. Как описывается в следующем разделе,
это значение можно получить с помощью функции time () или mktime (). Если параметр
$ times tamp не указан, то используется текущая дата и время. Например:
$today = date("Y/m/d");
Если бы сегодня было 10 марта 2004 года, то в результате было бы выведено следующее
значение:
2004/03/10
Строковый параметр формат определяет формат отображения даты и времени. Например,
при использовании формата y - m - d функция d a t e () вернула бы значение 0 4 - 3 - : . 0,
а при использовании M.d.Y — Mar. 1 0 . 2 0 0 4 . В табл. 5.4 приведены различные символы,
которые можно использовать в строковом параметре формат. (Их полный перечень можно
найти на Web-узле www. p h p . n e t . ) Различные элементы шаблона даты могут быть отделе ны
друг от друга дефисом (-), точкой (.), косой чертой ( / ) или пробелом.
Таблица 5.4. Символы форматирования даты
Символ Значение Пример
м Трехбуквенное английское сокращение месяца
F Английское название месяца
m Месяц (две цифры с нулями)
п Месяц (одна-две цифры без нулей)
d День месяца (две цифры с нулями)
j День месяца (две цифры без нулей)
1 Английское название дня недели
D Трехбуквенное английское сокращение дня недели
w Порядковое число дня недели, от 0 (воскресенье) до 6 (суббота)
Y Год (четыре цифры)
у Год (две цифры)
g Часы (12-часовой формат без нулей, от 1 до 12)
G Часы (24-часовой формат без нулей, от о до 23)
h Часы (12-часовой формат с нулями, от 0 1 до 12)
н Часы (24-часовой формат с нулями, от о0 до 23)
i Минуты
s Секунды
Jan
January
02 ИЛИ 12
1 ИЛИ 12
01 ИЛИ 14
3 или з о
Friday
Fri
5
2004
04
2 ИЛИ 10
2 ИЛИ 15
01 ИЛИ 10
00 ИЛИ 23
00 ИЛИ 59
00 ИЛИ 59
86 Часть II. Переменные и данные
Окончание табл. 5.4
Символ
а
А
и
Значение
до или после полудня: am или рш (в нижнем регистре)
ДО или ПОСЛЕ полудня: AM ИЛИ РМ (В верхнем регистре)
Целое число секунд, прошедших с 1 января 1970 года, 00:00:00 GMT
Пример
am
AM
1056244941
Хранение значений в формате timestamp
Для присваивания текущего значения даты и времени в формате timestamp предназначена
функция time ():
$today = timet);
То же самое можно осуществить с помощью выражения
$today = strtotime("today");
Для получения любого другого значения даты и времени в формате timestamp предназначена
функция mktime (). Она имеет следующий синтаксис:
$importantDate = mktimefh, m, s, mo, d, y );
где аргумент h соответствует часам; m— минутам; s— секундам; mo — месяцу; d— дню;
у — году. Например, для вычисления секунд, прошедших к 15 января 2004 года, необходимо
использовать следующее выражение:
$importantDate = mktime(0, 0, 0, 1, 15, 2003);
Для получения значений в формате timestamp можно использовать различные английские
ключевые слова или сокращения. Например, приведенное выше выражение можно переписать
следующим образом:
$importantDate = strtotime("January 15 2003");
Функция s t r t o t i m e () может распознавать следующие слова и сокращения.
•S Название месяцев: 12 месяцев и соответствующие сокращения.
•S Название дней недели: 7 дней и соответствующие сокращения.
•S Название единиц времени: year (год), month (месяц), f o r t n i g h t (две недели),
week (неделя), day (день), hour (час), minute (минута), second
(секунда), am (до полудня), рт (после полудня).
•/ Некоторые английские слова: ago (тому назад), now (сейчас), l a s t (длиться),
next (следующий); t h i s (этот), tomorrow (завтра), y e s t e r d a y (вчера).
•S Знаки "плюс" и "минус".
•S Все числа.
•S Временные зоны: например, gmt (Greenwich Mean Time — среднее время по
Гринвичу) или pdt (Pacific Daylight Time — дневное тихоокеанское время).
Слова и сокращения можно по-разному комбинировать. Например:
$importantDate = strtotime("tomorrow"); # 24 часа от сегодня
$importantDate = strtotime("now + 24 hours");
$importantDate = s t r t o t i m e ( " l a s t Saturday");
$importantDate = strtotime("8pm + 3 days");
$importantDate = strtotime("2 weeks ago"); # две недели назад
$importantDate = strtotime("next year gmt"); # на один год вперед
$importantDate = s t r t o t i m e (" tomorrow 4am"),-
Глава 5. Работа с данными 87
Для нахождения временной разницы между событиями достаточно просто вычесть о IHO
значение из другого. Например, если переменная $importantDate описывает прошедшее
событие, то для определения его "давности" соответствующее значение нужно отнять от: качения
переменной $ today (которая должна быть определена ранее). Например:
$timeSpan = $today-$importantDate;
Полученное значение и будет временной разницей в секундах между двумя событиями.
Перевести это значение в часы можно следующим образом:
$timeSpan = (($today-$importantDate)/60)/60;
88 Часть II. Переменные и данные
Глава 6
Объединение данных с помощью
массивов
вэ/ной главе...
> Создание массивов
> Присваивание значений элементам массивов
> Сортировка массивов
> Обработка значений в массивах
> Создание многомерных массивов
ассивы представляют собой составные переменные, позволяющие объединять
данные под одним именем. Например, в одной переменной $FordInf о можно
хранить такую информацию о машине, как название модели, цвет или стоимость. При этом
массивы можно легко обрабатывать, получать к ним доступ или изменять информацию. Например,
в РНР предусмотрено несколько методов сортировки данных в массивах.
В этой главе предлагается описание методов создания, изменения, копирования и использования
массивов.
Создание массивов и fiarfoina с ними
Массивы являются важным элементом программирования на языке РНР. В этом разделе
описывается, как создавать, изменять и удалять массивы.
Создание массивов
Для создания переменной в РНР ей можно присвоить значение. Аналогично, чтобы создать
массив, необходимо присвоить ему соответствующие значения. Например, пусть
$customers — переменная, которая ранее не использовалась в сценарии. Тогда для создания
массива с именем $customers воспользуемся выражением
$customers[1] = "Сэм Смит";
Теперь $customers — имя массива с единственным значением " Сэм Смит". Рассмотрим
следующий фрагмент кода:
$customers[2] = "Сью Джонс";
$customers[3] = "Мэри Хуанг";
Теперь массив $customers содержит три значения: "Сэм Смит", "Сью Джонс"
и"Мэри Хуанг".
Массив можно рассматривать как набор пар ключ-значение (key/value), т.е.
$arrayname['ключ1'] = значение!;
$arrayname['ключ2'] = значение2;
$arrayname['ключЗ'] = значениеЗ;
и т.д. по всем элементам массива.
Ключ (key) также называют индексом (index).
м
В качестве индекса в массивах могут использоваться числа или строки. В массиве
$customers индексами являются 1, 2 и 3. Однако можно использовать и текстовые стрс ки.
Рассмотрим пример создания массива, в котором индексами являются прописные буквы некоторых
штатов:
$ c a p ' i t a l s ['СА'] = "Сакраменто";
$ c a p i t a l s [ ' T X ' ] = "Остин";
$ c a p i t a l s [ ' O R ' ] = "Салем";
Для создания массива можно также использовать сокращенную запись, а не писать отдельное
выражение для каждого значения индекса. Одним из возможных вариантов являет;я
$ s t r e e t s [ ] = "ул. Вязов";
$ s t r e e t s [ ] = "ул. Дубов";
$ s t r e e t s [ ] = "7-ая авеню";
В таком случае создается массив с автоматической нумерацией индексов — числами, начиная
с 0. Например, для отображения первого элемента массива можно воспользоваться
следующим выражением:
echo " $ s t r e e t s [ 0 ] " ;
В результате получим:
ул. Вязов
Отсчет значений индекса массивов начинается с 0, если только специально не
присвоить другое значение. Одной из часто совершаемых ошибок является использование
в качестве первого значения индекса массива 1, а не 0.
Еще более сокращенной записью создания массива является
$ s t r e e t s = а г г а у ( " у л . Вязов", "ул. Дубов", "7-ая авеню");
В результате выполнения этого оператора создается массив, аналогичный создание му
в предыдущем примере. Если, например, необходимо, чтобы отсчет в массиве начина, [ся
с 12, а не с 0, можно воспользоваться выражением
$ s t r e e t s = a r r a y ( 1 2 => "ул. Вязов", "ул. Дубов", "7-ая авеню");
В результате будет создан следующий массив:
$ s t r e e t s [ 1 2 ] = "ул. Вязов";
$ s t r e e t s [ 1 3 ] = "ул. Дубов";
$ s t r e e t s [ 1 4 ] = "7-ая авеню",-
Аналогичным образом можно создавать массивы с текстовыми индексами. Например,
с помощью следующего выражения можно создать массив сокращенных названий штатов:
$ c a p i t a l s = arrayC'CA" => "Сакраменто",
"ТХ" => "Остин",
"OR" => "Салем"));
Обратите внимание на структуру этого выражения. РНР не учитывает пробелы
и перевод строки. Все выражение можно было бы написать в одну длинную строку.
Однако приведенная выше структура позволяет программистам облегать
анализ кода сценария, который стоит создавать настолько прозрачным и четмм,
насколько это возможно. При тестировании кода сценария вы с удовольстви гм
сможете оценить затраченные усилия.
РНР также позволяет создавать массивы, значения которых будут находиться в некотор эм
промежутке. Например:
$years = r a n g e ( 2 0 0 1 , 2010);
В результате будет создан следующий массив:
90 Часть II. Переменные и данные
$years[0] = 2001
$years[l] = 2002
$years[8] = 2009
$years[9] = 2010
Можно также воспользоваться выражением
$ r e v e r s e _ l e t t e r s = r a n g e ( " z " , " a " );
и в результате будет создан массив из 26 элементов:
$ r e v e r s e _ l e t t e r s [ 0 ] = z
$ r e v e r s e _ l e t t e r s [ 1 ] = у
$ r e v e r s e _ l e t t e r s [ 2 4 ] = b
$ r e v e r s e _ l e t t e r s [ 2 5 ] = a
Вывод элементов массивов
Для просмотра структуры и значений элементов массива можно воспользоваться одной из
двух функций: var_dump () или p r i n t _ r ( ) . Однако функция p r i n t _ r () не так полезна.
Рассмотрим следующее выражение для вывода массива $customers:
p r i n t _ r ( $ c u s t o m e r s ) ;
В результате получим:
Array
(
[1] => Сэм Смит
[2] => Сью Джонс
[3] => Мэри Хуанг
)
Таким образом, выводятся только индекс и значение каждого элемента массива. Для получения
более подробной информации о массиве следует использовать функцию var_dump ():
var_dump($customers) ;
В результате получим следующее:
a r r a y ( 3 ){
[ 1 ] =>
s t r i n g ( 9 ) "Сэм Смит"
[2]=>
s t r i n g ( 9 ) "Сью Джонс"
[3]=>
s t r i n g ( 1 0 ) "Мэри Хуанг"
}
В этом случае вместе с индексом и значением будет также выводиться тип данных каждого
элемента массива (например, текстовая строка из девяти символов). Так, массив, содержащий
информацию об имени покупателя и его возрасте, отобразится с помощью функции
var_dump () следующим образом:
a r r a y ( 2 ){
["name"]=>
s t r i n g ( 9 ) " С э м Смит"
["age"]=>
i n t ( 1 2 )
>
Целочисленный тип элемента массива определяется ключевым слова i n t . В данном примере
элемент с индексом age имеет значение 12.
Глава 6. Объединение данных с помощью массивов 91
Необходимо помнить, что в таком виде информация о массиве возвращается интерпретатором
РНР. Однако при использовании РНР для Web результат выполнения
функций p r i n t _ r () и var_dump () будет отображаться с помои ью
HTML, т.е. будет выведен в одну длинную строку. Для форматирования вывозимой
в браузер информации о массивах следует воспользоваться соответств; тощими
HTML-дескрипторами, например:
echo "<рге>";
var_dump($customers);
echo "</pre>";
Изменение массивов
Массивы можно изменять таким же образом, как и переменные. РНР позволяет измен ать
значения, добавлять или удалять элементы и производить сортировку. Например, если имеется
массив $ c a p i t a l s , значение его элемента можно легко изменить следующим образом:
$capitals['ТХ'] = "Биг Спрингс";
Это выражение присваивает элементу с индексом ТХ новое значение "Биг Спрингс",
хотя жители Остина (Austin) могут возразить (Остин— столица штата Техас). Для создания
нового элемента массива $ c a p i t a l s можно воспользоваться следующим кодом:
$ c a p i t a l s [ ' R I ' ] = "Провиденс";
Это выражение добавляет новый элемент, не изменяя существующие.
Предположим, имеется созданный ранее массив, в котором индексами являются целые числг:
$customers[1] = Сэм Смит
$customers[2] = Сью Джонс
$customers[3] = Мэри Хуанг
При использовании выражения
$customers[] = "Хуан Лопес";
массив $customers будет уже состоять из четырех элементов:
$customers[1] • Сэм Смит
$customers[2] = Сью Джонс
$customers[3] = Мэри Хуанг
$customers[4] = Хуан Лопес
РНР позволяет легко копировать существующий массив в новый, например:
$customerCopy = $customers;
Удаление значений из массива
Иногда необходимо полностью удалить значение из массива. Например, предположи,
что имеется массив
$colors = array("красный", "зеленый", "синий", "розовый", "желтый"));
который содержит пять значений. А теперь предположим, что вам больше не нравится розовый
цвет и вы хотите от него избавиться. Этого можно добиться таким образом:
$colors[3] = "";
Однако это выражение присваивает элементу $colors [3] пустое значение, но не удаляет
его. Массив $colors все еще содержит пять элементов, значение одного из которых —
пустая строка. Для того чтобы полностью удалить его из массива, необходимо восполко-
ваться следующим выражением:
unset($colors[ 3 ] ) ;
92 Часть II. Переменные и данные
Теперь массив $colors содержит четыре значения:
$colors[0] = красный
$colors[l] = зеленый
$colors[2] = синий
$colors[4] = желтый
Следует заметить, что при удалении элемента с индексом 3 все остальные остались неизмененными.
После того как массив создан, он не перестает существовать до тех пор, пока его специально
не удалить. При этом удаление его элементов по отдельности не влечет за собой удаление
массива как такового, точно так же, как извлечение всей одежды из шкафа не говорит
о ее исчезновении. Для того чтобы удалить массив, необходимо использовать выражение
unset($colors);
•
CofitfiufioeKa массивов
Одной из самых замечательных возможностей, предоставляемых языком РНР при работе
с массивами, является их сортировка. Исходно интерпретатор РНР размещает значения элементов
массива в указанном вами порядке и позволяет соответствующим образом выводить
их. Очень часто необходимо изменить порядок следования элементов. Например, нужно отсортировать
элементы массива в алфавитном порядке по индексу или по значению.
Язык РНР предоставляет широкие возможности при сортировке массивов. Например,
чтобы изменить порядок следования элементов массива с числами в качестве индексов, следует
воспользоваться функцией s o r t ():
sort($имя_массива);
Это выражение сортирует элементы массива по значению и присваивает им новые индексы
в порядке следования. При этом сначала идут значения, начинающиеся с чисел, потом —
с прописных и строчных букв. Например, рассмотрим массив $ s t r e e t s :
$streets[0] = "ул. Вязов";
$streets[l] = "ул. Дубов";
$streets[2] = "7-ая авеню";
Использование выражения
sort($streets);
приведет к следующему:
$streets[0] = "7-ая авеню";
$streets[lj = "ул. Вязов";
$streets[2] = "ул. Дубов";
Если же использовать функцию s o r t () для сортировки массива, индексами которого
являются текстовые строки, РНР преобразует их в числа.
Поэтому для таких целей необходимо воспользоваться функцией a s o r t ():
a s o r t ( $ c a p i t a l s ) ;
Это выражение сортирует значения столиц по значению, при этом не изменяя индексы
массива. Рассмотрим массив $ c a p i t a l s , созданный в предыдущем разделе:
$capitals['СА'] = "Сакраменто";
$capitals['TX'] = "Остин";
$capitals['OR'] = "Салем";
Глава 6. Объединение данных с помощью массивов 93
При использовании выражения
a s o r t ( $ c a p i t a l s ) ;
получим следующее:
$capitals['TX'] = "Остин"
$capitals['СА'] = "Сакраменто"
$capitals['OR'] = "Салем"
Заметим, что порядок следования индексов массива изменяется в соответствии со значен 1я-
ми. Теперь столицы расположены в алфавитном порядке. Если бы в качестве индексов маса ша
использовались числа, то они бы тоже поменяли свой порядок. Например, пусть имеется масс т
$capitals[1] = "Сакраменто";
$capitals[2] = "Остин",-
$capitals[3] = "Салем";
Результатом выполнения функции a s o r t () будет
$capitals[2] = "Остин"
$ c a p i t a l s [ l ] = "Сакраменто"
$capitals[3] = "Салем"
Вряд ли эта функция будет полезна для массивов с числовыми индексами.
Язык РНР предоставляет также и другие возможности для сортировки массивов различными
способами. В табл. 6.1 представлены необходимые для этого функции.
Таблица 6.1. Сортировка массивов
Сортировка массивов Описание
Сортирует значения элементов массива по возрастанию, присваивая им пр 1
этом новые числовые индексы
Сортирует значения элементов массива по возрастанию, не изменяя при
этом индексы
Сортирует значения элементов массива по убыванию, присваивая при этом
новые числовые индексы
Сортирует значения элементов массива по убыванию, не изменяя при этом
индексы
Сортирует индексы элементов массива по возрастанию
Сортирует индексы элементов массива по убыванию
Пользовательская сортировка, определяемая функцией имя_функции
(функции рассматриваются в главе 8)
Сортирует смешанные значения (текстовые и числовые) элементов массив;, и
устанавливает "естественный" порядок. Например, массив со значениями
d a y l , day5, d a y l l , day2 будет отсортирован следующим образом: d a y l ,
day2, days, d a y l l . В то время как результатом выполнения функции
s o r t () будет: d a y l , d a y l l , day2, day5
использование массивов в выражениях
Массивы можно использовать в выражениях точно так же, как и переменные. Этот раз; №1
как раз и посвящен этому вопросу.
Значения отдельных элементов массива можно легко получать путем прямого доступа
к ним, как, например, в следующем выражении:
$CAcapital = $capitals['СА'];
echo $CAcapital,-
s o r t ($имя_массива)
a s o r t ($имя_масстша)
r s o r t ($шя_массива)
ar sor t ($имя_массива)
ksor t ($имя_массива)
k r s o r t ($иш_массива)
u s o r t ($имя_массива,
имя_функции)
n a t s o r t ($имя_массива)
94 Часть II. Переменные и данное
Результатом выполнения будет
Сакраменто
Если попытаться получить доступ к несуществующему элементу массива, РНР выдаст сообщение
об ошибке:
$CAcapital = $capitals['CAx'];
Поскольку в массиве $ c a p i t a l s нет элемента с индексом САх, будет выведено следующее:
Notice: Undefined index: CAx in d:\testarray.php on l i n e 9
(Предупреждение: Неизвестный ключ: САх в файле d:\testarray.php в строке 9)
При этом сообщение об ошибке не прекращает выполнения последующих строк кода сценария.
Но поскольку переменной $CAcapital не было присвоено никакого значения, при
использовании функции echo будет выводиться пустая строка. Для предотвращения сообщения
об ошибке необходимо использовать символ @:
@$CAcapital = $capitals['САх'];
Использование массивов в операторе echo
Для вывода элементов массива с помощью функции echo следует воспользоваться
выражением
echo $capitals[ ' ТХ' ] ;
В результате получим:
Остин
Если необходимо поместить массив в длинную строку в двойных кавычках, его название
нужно заключить в фигурные скобки:
echo "Столица штата Техас — { $ c a p i t a l s [ ' Т Х ' ] } " ;
Результатом выполнения этого выражения будет следующее:
Столица штата Техас — Остин
Использование массивов в функции l i s t
РНР позволяет получать значения и индексы нескольких элементов массива одновременно.
С помощью функции l i s t () можно копировать значения массивов в переменные.
Пусть, например, имеется массив
$shoeInfo = array("мокасины", "черные", 22.00);
Информацию о нем можно получить, используя функцию p r i n t _ r ():
print_r($shoeInfo) ;
Результатом выполнения будет следующее:
Array
[0] => мокасины
[1] => черные
[2] = > 22
)
Следующий пример иллюстрирует использование функции l i s t О :
l i s t ( $ f i r s t , $second) = $shoeInfo;
echo $second, " " , $ f i r s t;
В результате РНР создаст две переменные, $f i r s t и $second, которым будут присвоены
значения первых двух элементов массива $shoeInf о, что эквивалентно выполнению операторов:
$ f i r s t = $shoelnfo[0] ;
$second = $shoe!nfo[l];
Глава 6. Объединение данных с помощью массивов 95
Значение третьего элемента массива, $shoeInfo, не будет скопировано, поскольку
функция l i s t () содержит только два аргумента. В результате функция echo выведет
черные мокасины
В некоторых случаях необходимо получить индекс элемента массива, а не его значение. Цля
этих целей предназначена функция key (). Предположим, что первым элементом массива явлжггся
$ s h o e I n f o [ ' s t y l e ' ] = "мокасины";
В следующем выражении с помощью echo выводятся индекс и значение первого элемента
массива $shoeInf о:
$value = $ s h o e I n f o [ ' s t y l e ' ];
$key = key($shoeInfо);
echo "$key: $value";
Результатом выполнения будет
стиль: мокасины
В первой строке кода переменной $value присваивается значение "мокасины", во иго-
рой с помощью функции key () переменной $кеу присваивается индекс элемента. В дашсом
случае мы получаем информацию о первом элементе, поскольку указатель массива, который
отвечает за перемещение по массиву, установлен в текущей позиции. В следующем раз; еле
более подробно рассматриваются вопросы, связанные с указателями на массивы.
Ле/гемесцение /го массивам
Часто необходимо производить различные операции над каждым элементом массива. Например,
нужно вывести все значения, сохранить их в базе данных или прибавить к кажд эму
элементу число 6. Формально выражаясь, процесс перебора всех элементов массива является
итеративным, т.е. состоящим из итераций, или проходом (traversing). В данном разделе списаны
два таких способа.
S Перебор вручную. Использование указателя для перехода от одного элемента
массива к другому,
*/ С помощью оператора f oreach. Поэлементный автоматический прохо; по
массиву от его начала до конца.
Перебор элементов массива вручную
Для перебора элементов массива вручную можно воспользоваться указателем. При этом
массив представляется как список, содержащий указатель на его элементы. Указатель не изменяет
свое положение до тех пор, пока его не переместить. Для этого в языке РНР предназначены
следующие функции.
•S c u r r e n t (%имя_массива). Возвращает текущее значение элемента массива,
не перемещая указатель.
•/ next ($имя_массива). Перемещает указатель вперед на один элемент.
S previous ($имя_массива). Перемещает указатель назад на один элемент.
•S end (%имя_массива). Перемещает указатель в конец массива.
S r e s e t ($имя_массива). Перемещает указатель в начало массива.
С помощью следующего выражения осуществляется проход по всем элементам массива,
содержащего названия столиц штатов:
96 Часть II. Переменные и дань ые
$value = current($capitals);
echo "$value<br>";
$value = next($capitals);
echo "$value<br>";
$value = next($capitals);
echo "$value<br>";
Поскольку указатель ранее не перемещался, по умолчанию он установлен на первый элемент
массива. Если же положение указателя изменялось в предыдущих строках кода или нет
уверенности, что отсчет начнется с первого элемента, то следует предварительно воспользоваться
функцией r e s e t ():
r e s e t ( $ c a p i t a l s ) ;
Использование этого метода для прохода по массиву предполагает выполнение оператора
присваивания и функции echo для каждого элемента (в общем случае для каждого из 50 штатов).
В результате будет выведен список названий штатов.
Этот метод достаточно гибок. Можно просто перемещаться по массиву в произвольном порядке
и обрабатывать его элементы. Можно перемещаться назад, непосредственно перейти в конец,
пропускать элементы, используя подряд два выражения next, или применять любой другой полезный
прием. Однако, если необходимо пройти поэлементно массив от начала до конца, язык РНР
позволяет использовать более простой метод, а именно оператор f о reach, который выполняет
те же действия намного эффективнее. Этот оператор рассматривается в следующем разделе.
Использование оператора foreach для прохода по массиву
Оператор foreach осуществляет поэлементный проход по массиву и позволяет выполнить
набор инструкций со значениями и индексами. Общий синтаксис имеет вид:
foreach{$имя_массива as $ключ => ^значение)
{
набор операторов;
}
Параметрами выражения foreach являются следующие.
•S $имя_массива. Имя массива.
•f $ключ. Имя переменной, которой будут присваиваться значения индексов элементов
массива. Этот параметр является необязательным, т.е. без его использования
сохранится только значение элемента массива в переменной $значение.
J $значение. Имя переменной, которой будут присваиваться значения элементов
массива.
Рассмотрим следующий пример, в котором оператор foreach используется для вывода
численности населения по штатам:
$state_population = array ("CA" => 34501130,
"WY" => 494423,
"OR" => 3472867);
ksort($state_population);
foreach($state_population as $state => $population)
С
$population = number_format($population);
echo "$state: $population.<br>";
>
В результате на Web-странице отобразится следующее:
СА: 34,501,130
OR: 3,472,867
WY: 494,423
Глава 6. Объединение данных с помощью массивов 97
Можно воспользоваться и следующей строкой кода:
foreach($state_population as $population)
Однако в этом случае мы будем иметь доступ только к значениям (численности населения)
массива, но не к индексам.
При использовании оператора foreach указатель автоматически перемещается в начато,
т.е. нет необходимости использовать функцию r e s e t ().
Onftec/елеяие /газме/га массива
Для получения информации о структуре и значениях массива можно использовать функцию
var_dump () или p r i n t _ r () (см. выше раздел "Вывод элементов массивов"). Но т о гда
необходимо просто знать размер массива. Для этого в языке РНР предусмотрены две
функции: count () и s i z e o f (). Их общий синтаксис имеет следующий вид:
$n = count($имя_мас сива);
$n = sizeof($имя_массива);
В результате выполнения переменной $п будет присвоено значение количества элементов
в массиве.
7Lfie6<$fia3oeanue массивов в &екапбвые
anfioicu (и Haodofioifi)
Иногда необходимо выполнять операции над данными в специальном формате. Например,
надо вывести слова предложения в отдельных строках. Одним из вариантов решения
данной задачи является добавление перед выводом после каждого слова символа ' \ п ' . Это
легко можно осуществить с помощью оператора foreach, если предложение представляет
собой массив, а не текстовую строку. РНР как раз позволяет создавать массив, элементами
которого являются слова некоторого предложения.
Для того чтобы переписать содержимое текстовой строки в массив, можно воспользоваться
функцией
$arrayname = explode("символ", строка);
Первым аргументом данной функции является символ, который используется для ](аз-
биения строки и представления ее в виде массива. Рассмотрим следующий пример:
$ s t r i n g l = "Это: НОВЕЛИ: дом";
$ t e s t a r r a y = explode(":", $ s t r i n g l );
p r i n t _ r ( $ t e s t a r r a y ) ;
Функция explode () используется для разделения строки $ s t r i n g l символом двоеточия (:)
и создания массива $ t e s t a r r a y , содержащего подстроки. Результатом ее выполнения будет
Array
(
[01 => Это
[1] => новый
[2] => дом
)
При этом переменная $ s t r i n g l не изменяет свое значение.
И наоборот, аналогичным образом массивы можно преобразовывать в строки. Для выполнения
этой операции предназначена функция
$resString = implode("символ", $массива);
98 Часть II. Переменные и данные
В результате будет создана строка $resString, состоящая из элементов массива
$массива, разделенных символом. Рассмотрим следующий пример:
$arrayln = array("красный", "синий", "зеленый");
$stringOut = implode(";", $arrayln);
echo $stringOut;
Результат выполнения функции implode () будет присвоен переменной $stringOut.
Так же как и в случае с функцией explode (), implode () не изменяет значения входных
аргументов, а только считывает их. Если какая-то функция будет преобразовывать входные
параметры, об этом будет сказано отдельно.
В результате выполнения последнего выражения получим:
красный;синий;зеленый
Между вставленными в строку элементами массива нет пробелов, поскольку они не были
указаны в параметрах функции implode ( ) . Следующее выражение позволяет выполнить
эту операцию:
$stringOut = implode("; ", $arrayIn);
Таким образом, в результате выполнения этой функции получим:
красный; синий; зеленый
ЛкеоЯ^сгзование пе[гемеяных € массивы
(и HaoJoftotn)
Иногда данные элементов массива необходимо сохранить в переменных, которые впоследствии
можно использовать в выражениях РНР. Либо может возникнуть потребность
в обратной операции — преобразовать переменные в элементы массива. Например, нужно
выполнить одну и ту же операцию (прибавление 1) над несколькими переменными. Если
преобразовать переменные в массив, с помощью одного оператора f oreach можно получить
доступ ко всем значениям и выполнить требуемые действия. В противном случае пришлось
бы отдельно для каждой переменной писать свою строку кода.
Для решения этих задач в языке РНР предусмотрены функции e x t r a c t () и compact ().
Функция e x t r a c t () позволяет получать значения элементов массива и присваивать их переменным,
именами которых являются соответствующие индексы. Другими словами, значение
каждого элемента копируется в переменную с именем индекса. Рассмотрим следующий
пример, в котором с помощью функции e x t r a c t () выводятся все данные массива:
$testarray = array("pink" => "гвоздика", "red" => "роза");
extract($testarray);
echo "Моим любимым красным цветком является $red.\n";
echo "Моим любимым розовым цветком является $pink.";
В результате будет выведено:
Моим любимым красным цветком является роза.
Моим любимым розовым цветком является гвоздика.
Функция compact () предназначена для выполнения обратного действия — преобразования
набора переменных в массив. При этом значения переменных копируются в массив.
Рассмотрим следующий пример:
$colorl = "красный";
$color2 = "синий";
$а = "фиолетовый";
$Ь = "оранжевый";
Глава 6. Объединение данных с помощью массивов 99
$arrayln = arrayC'a", "b");
$arrayOut = compact ("colorl", "color2", $ a r r ay In) ,-
В результате получим следующий массив:
$arrayOut[colorl] = красный
$arrayOut[color2] = синий
$arrayOut[a] = фиолетовый
$arrayOut[b] = оранжевый
Видно, что имена переменных использовались в качестве индексов.
Следует заметить, что в функции compact () использовались два метода для созда-шя
массива.
•S Первый состоит в использовании имен переменных напрямую для индексов.
Так происходит с переменными $ c o l o r l и $color2.
•S Второй состоит в использовании массива, содержащего имена переменвых.
В предыдущем примере таковым является $arrayln с переменными $а
и $Ь. Функция compact () добавляет эти имена в результирующий массив
$arrayOut.
Язык РНР позволяет использовать оба метода. Если имеется несколько переменных, которые
необходимо сгруппировать в массив, первый метод является более предпочтительным.
В противном случае лучше применять второй метод, объединив сначала имена переменных
в некоторый массив, а затем использовать его в качестве аргумента функции compact ().
Разбиение и слияние массивов
Часто необходимо объединять или разделять массивы. Предположим, например, что имеются
два класса студентов и два соответствующих массива, содержащих их имена. Если ну кно
было бы объединить оба класса, это же действие пришлось бы выполнять и для массивов.
РНР позволяет разбить массив и создать новый, содержащий подмножество элементов
исходного. Общий синтаксис функции, выполняющей это действие, имеет следующий вщ:
$subArray = array_slice($массив, nl, п2) ;
Параметр nl указывает позицию элемента, с которого начнется разбиение исходного
$массива (0 — с первого элемента, 1 — со второго), а п2 — количество элементов нового
массива. Например:
$ t e s t a r r a y = array("красный", "зеленый", "синий", "розовый");
$subArray = a r r a y _ s l i c e ( $ t e s t a r r a y , 1, 2);
В результате массив $ subArray будет иметь вид
[0] => зеленый
[1] => синий
Разбиение массива $ t e s t a r r a y начинается с позиции номер 1 и содержит два элемента.
По умолчанию отсчет начинается с 0, а не с 1, поэтому первый элемент результирующего
массива имеет значение " зеленый", а не " красный".
Аналогичным образом можно объединить различные массивы, используя следующее
выражение:
$bigArray = array_merge($массив2, %массив2, ...);
100 Часть II. Переменные и данные
Рассмотрим пример объединения двух массивов:
$arrayl = array("красный", "синий");
$array2 = array("зеленый", "желтый");
$bigArray = array_merge($arrayl, $array2);
В результате будет создан массив $bigArray:
$bigArray[0] = красный
$bigArray[1] = синий
$bigArray[2] = зеленый
$bigArray[3] = желтый
Таким же образом можно объединять массивы не только с числовыми индексами, но
и с текстовыми. Однако, если индексы для некоторых элементов совпадают, последний из
них заменит первоначальный. Рассмотрим следующий пример:
$arrayl = array("color1" => "красный", "color2" => "синий");
$array2 = a r r a y ( " c o l o r l " => "зеленый", "color3" => "желтый");
$bigArray = array_merge($arrayl, $array2);
В результате получим:
$bigArray[colorl] = зеленый
$bigArray[color2] = синий
$bigArray[color3] = желтый
" $ 2 ^ . Если необходимо объединить массивы с одинаковыми индексами, следует вос-
ц к ф Л пользоваться функцией array_merge_recursive(), а не array_merge ().
W^iL/ В этом случае будет создан многомерный массив, а не заменены исходные значе-
^БНО"^ ния. Многомерные массивы более подробно рассматриваются в разделе
"Многомерные массивы" далее в этой главе.
Сравнение массивов
Очень часто необходимо знать, совпадают ли массивы. Для этого надо найти одинаковые
и различные элементы. Эта операция может быть выполнена с помощью функции
$diffArray = array_diff(%массив1, $массив2, ...);
В результате выполнения функции array_dif f () массив $diff Array будет содержать
элементы из $arrayl, отсутствующие в $аггау2. При этом в результирующем массиве
ключи сохранят свои значения. Рассмотрим следующий пример:
$arrayl = аггауС'а" => "яблоко", "Ь" => "апельсин", "с" => "банан");
$array2 = array("слива", "апельсин", "банан");
$diffArray = array_diff($arrayl, $array2);
В результате выполнения этого фрагмента кода получим:
$diffArray[a] = яблоко;
Поскольку элемент со значением "яблоко" находится в массиве $arrayl, но не
в $аггау2, он записывается в результирующий $dif f Array с индексом "а".
Порядок следования аргументов в функции a r r a y _ d i f f () является очень важным. Так,
если последнюю строку кода в предыдущем примере переписать как
$diffArray = array_diff($array2, $arrayl);
то результирующий массив $dif f Array будет иметь вид
$diffArray[0] = слива;
Единственным элементом, который находится в массиве $аггау2, но не в $arrayl, будет
элемент со значением " слива". Именно поэтому он и записывается в $dif f Array.
Глава 6. Объединение данных с помощью массивов 101
Если необходимо найти элементы, отличающиеся либо своим значением, либо ключом,
следует воспользоваться следующей функцией:
$ d i f f A r r a y = a r r a y _ d i f f _ a s s o c ( $ a r r a y l , $array2);
Подставляя в качестве аргументов функции a r r a y _ d i f f _ a s s o c () массивы, которые
использовались в предыдущем примере, получим следующий результат:
$ d i f f A r r a y [ a ] = яблоко
$ d i f f A r r a y [ b ] = апельсин
$ d i f f A r r a y [ с ] = банан
В этом случае ни один из элементов массива $ a r r a y l не содержится в $аггау2, поскольку
индексы у них различны.
Чтобы найти одинаковые элементы в двух и более массивах, в РНР предусмотрена функц 1я
$simArray = a r r a y _ i n t e r s e c t(%массив1, $массив2, ...);
Рассмотрим пример использования этой функции для массивов из предыдущих примеров:
$simArray = a r r a y _ i n t e r s e c t ( $ a r r a y l , $array2);
В результате массив $simArray будет иметь такие элементы:
$simArray[b] = апельсин
$simArray[c] = банан
Функция a r r a y _ i n t e r s e c t О считает элементы одинаковыми, если их значения равны.
Для того чтобы учитывать равенство как ключа, так и значения элемента, в языке ГНР
предназначена функция a r r a y _ i n t e r s e c t _ a s s o c (), которая имеет следующий синтаксьс:
$simArray = a r r a y _ i n t e r s e c t _ a s s o c ( $ a r r a y l , $array2);
В результирующий массив $simArray будут записаны только те элементы $ a r r a yl
и $аггау2, которые имеют одинаковые ключ и значение. Используя в качестве аргумектов
все те же массивы, результатом будет пустой массив, поскольку исходные не содержат с ди-
наковых индексов.
Dfiifiue опе/гсщии с массивами
В этом разделе мы рассмотрим другие операции над массивами.
•S Суммирование массивов.
S Удаление повторяющихся элементов.
•S Перестановка ключей и значений в массиве.
Суммирование массивов
Для сложения всех значений массива следует использовать функцию
$sum = a r r a y _ s u m ( $ a r r a y );
Например:
$arrayAdd = a r r a y ( 3 , 3, 3);
$sum = array_sum($arrayAdd);
echo $sum;
В результате будет получено значение 9.
Просуммировать можно только числовые массивы. Но, как уже упоминалось в mate 5,
при использовании (в данном случае при попытке их "сложения") текстовые строки автоматически
преобразуются в 0.
102 Часть II. Переменные и данные
Удаление повторяющихся элементов
Очень часто необходимо удалить повторяющиеся элементы в массиве. Например, имеется
массив с именами покупателей, который нужно вывести на экран без повторений. Это можно
осуществить, используя выражение
$names = array("Мэри", "Салли", "Салли", "Сэм");
$names2 = array_unique($names);
В результате массив $names2 будет иметь такой вид:
$names2[0] => Мэри
$names2[l] => Салли
$names2[3] => Сэм
Как можно увидеть, в результирующем массиве продублированный элемент был удален.
Перестановка ключей и значений в массиве
РНР позволяет менять местами индексы (а точнее, ключи) и значения элементов массива.
Пусть, например, имеется следующий массив:
$ t e s t a r r a y [ ' r o s e ' ] = red
$ t e s t a r r a y [ ' i r i s ' ] = purple
Для перестановки значений и ключей следует воспользоваться функцией
$arrayFlipped = a r r a y _ f l i p ( $ t e s t a r r a y );
В результате будем иметь:
$testarray['red'] = rose . .
$testarray['purple'] = iris
Многомерные массивы
В предыдущих разделах речь шла об одномерных списках пар ключ-значение. Однако
в некоторых случаях необходимо сохранять данные с несколькими ключами. Пусть, например,
имеется информация о ценах на некоторые продукты:
S лук (onion) — 0,50;
S яблоко (apple) — 2,50;
? апельсин (orange) — 2,00;
S бекон (bacon) — 3,50;
S картофель (potato) — 1,00;
S ветчина (ham) — 5,00.
Ее можно сохранить в одномерном массиве следующим образом:
$foodPrices['onion'] = 0.50;
$foodPrices['apple'] = 2.50;
$foodPrices['orange'3 = 2.00;
$foodPrices['bacon'] =3.50; ' SfoodPrices['potato'] = 1.00;
$foodPrices['ham'] = 5.00,-
Тогда в любой момент можно просмотреть информацию о ценах на продукты путем прямого
доступа к элементам массива $foodPrices. Но представим, что список товаров содержит
3000 наименований. В этом случае необходимо будет просмотреть 3000 элементов массива,
чтобы найти информацию о конкретном продукте, например о луке (onion) или ветчине (ham).
Глава 6. Объединение данных с помощью массивов 103
Однако список товаров можно разделить на три группы: овощи (vegetable), фрукты (fiuit)
и мясные изделия (meat). И тогда необходимо будет просматривать информацию о продуктах
только в рамках одной категории, а не весь список, что является более эффективным. Это
можно осуществить, используя многомерные массивы:
$ f o o d P r i c e s [ ' v e g e t a b l e ' ] [ ' o n i o n ' ] = 0.50;
$foodPrices [ ' v e g e t a b l e ' ] [ ' p o t a t o ' ] = 1.00;
$ f o o d P r i c e s [ ' f r u i t ' ] [ ' a p p l e ' ] = 2.50;
$ f o o d P r i c e s [ ' f r u i t ' ] [ ' o r a n g e ' ] = 2.00;
$foodPrices['meat']['bacon'] = 3.50;
$foodPrices['meat']['ham'] = 5.00;
Такой массив называется многомерным (multidimensional), поскольку представляет со эой
массив массивов. На рис. 6.1 показана структура массива $f oodPrices. На рисунке ви;;но,
что массив $f oodPrices содержит три пары ключ-значение. При этом значение каждого >ле-
мента с ключами vegetable, f r u i t и meat — массив с двумя элементами. Например, элел ент
с ключом meat — это массив с двумя парами ключ-значение: bacon-3 . 5 0 и ham-5 .00.
$foodPrices ключ
vegetable
f r u i t
meat
значение
ключ
onion
potato
orange
apple
bacon
ham
значение
0,50
1,00
2,00
2,50
3,50
5,00
Рис. 6. /. Структура массива $foodPrices - массив
массивов
Массив $f oodPrices является двумерным. Язык РНР также позволяет работать с четырех-,
пяти-, шестимерными или массивами большей размерности. Однако их использование
может внести большую путаницу в код сценария.
Создание многомерных массивов
РНР позволяет создавать многомерные массивы точно так же, как и одномерные. Например,
можно воспользоваться прямым присваиванием значений элементам массива:
$ f o o d P r i c e s [ ' v e g e t a b l e ' ] [ ' p o t a t o ' ] = 1.00;
$ f o o d P r i c e s [ ' f r u i t ' ] [ ' a p p l e ' ] = 2.50;
Можно также воспользоваться сокращенной записью:
t r a n s p o r t a t i o n [ ' c a r ' ] [ ] = "Форд";
t r a n s p o r t a t i o n [ ' c a r ' ] [ ] = "Джип";
По умолчанию в качестве индексов будут использоваться целые числа, начиная с 0:
t r a n s p o r t a t i o n [ c a r ] [ 0 ] = Форд;
transportation[саг][1] = Джип;
Создать многомерный массив можно с помощью выражения array:
$foodPrices = array(
"vegetable" •> array("potato" =>1.00, "onion" => .50),
"fruit" => array("apple" => 2.50, "orange" -> 2.00));
104 Часть II. Переменные и данные
Следует заметить, что массив $foodPrices с индексами vegetable и f r u i t создается
с помощью первого вызова функции array. Его элементы также представляют собой массивы, что
приводит к созданию массива массивов. В результате получим следующий многомерный массив:
$foodPrices[vegetable][potato] = 1.00
$foodPrices[vegetable][onion] = .50
$foodPrices[fruit][apple] = 2.50
$foodPrices[fruit][orange] = 2.00
Вывод многомерных массивов
Для вывода информации о многомерном массиве можно воспользоваться теми же функциями,
что и для одномерного, — p r i n t _ r () или var_dump (). Рассмотрим следующий пример:
array(2) {
["vegetable"] =>
array(2){
["potato"] =>
f l o a t ( l )
["onion"] =>
f l o a t ( 0 . 5)
}
["fruit"] =>
array(2){
["apple"] =>
f l o a t ( 2 . 5)
["orange"] =>
float(2)
}
}
Первая строка указывает на массив, содержащий два элемента. Его первый элемент
с индексом v e g e t a b l e — массив с двумя элементами типа f l o a t с индексами p o t a to
и onion и значениями 1 и 0 . 5 соответственно. Второй элемент основного массива с индексом
f r u i t также состоит из двух элементов.
Использование многомерных массивов в выражениях
Для получение значений элементов многомерного массива используются те же процедуры,
что и для одномерного. Рассмотрим пример, в котором доступ к элементам осуществляется
напрямую:
$hamPrice = $foodPrices['meat']['ham'];
Для вывода значений можно использовать функцию echo:
echo $foodPrices['meat']['ham'];
Если же значение элемента необходимо вывести в выражении с двойными кавычками,
имя массива следует заключить в фигурные скобки. При этом символ $ (начало имени переменной)
должен следовать сразу же за открывающей фигурной скобкой без пробелов:
echo "Ветчина стоит \${$foodPrices['meat']['ham']}";
Заметим, что перед первым символом $ стоит символ \. Он используется для того, чтобы
РНР интерпретировал $ не как символ начала имени переменной, а буквально. В результате
будет выведено:
Ветчина стоит $5
Ранее в этой главе приводилось описание различных функций для преобразования текстовых
строк в массивы (и наоборот), массивов в отдельные переменные и осуществления других
Глава 6. Объединение данных с помощью массивов 105
операций. Многие из этих операций не имеет смысла использовать для многомерных массивов,
так как они будут работать некорректно. Однако это можно осуществить для отдельных
элементов, которые сами по себе являются массивами. Рассмотрим, например, функцию
implode (), которая преобразует массив в текстовую строку. Ее нельзя напрямую использовать
для многомерного массива, поскольку его значения— массивы. Но, как уже упоминалось,
эту операцию можно выполнить для отдельных элементов:
$resString = implode(":", $foodPrices['vegetable']);
Это выражение преобразует элементы массива $f oodPrices [ ' v e g e t a b l e ' ] в строку,
в которой в качестве символа-разделителя используется двоеточие и пробел ": ". Если результат
выполнения функции implode () вывести на экран, получим следующее:
1: 0.5
Будут выведены значения элементов 1 и 0.5 массива $ f oodPrices [ ' v e g e t a b l e ' ]
с индексами p o t a t o и onion соответственно, разделенные двоеточием и пробелом, как указано
в функции implode ().
Проход по многомерному массиву
Проход по многомерному массиву можно осуществить с помощью функции f oreach (ее описание
см. выше). Поскольку двумерный массив, такой как $f oodPrices, содержит в качоггве
элементов два массива, для прохода необходимо дважды использовать оператор f oreach: один
внутри другого. (Использование оператора внутри другого называется вложением (nesting).)
Нижеприведенный фрагмент кода позволяет вывести значения элементов многомерюго
массива.
foreach ($foodPrices as $category )
{
foreach ($category as $food =>$price )
{
$f_price =sprintf("%01.2f",$price);
echo "$food: \$$f_price \n";
}
}
В результате получим:
onion: $0.50
potato: $1.00
apple: $2.50
orange: $2.00
bacon: $3.50
ham: $5.00
Рассмотрим поэтапно, как интерпретируется использование выражения f oreach.
1. Обрабатывается первая пара индекс-значение массива $ f oodPrices, и значение элем« нта
записывается в переменную $category (которая сама по себе является массивом).
2. Обрабатывается первый элемент массива $category: его индекс сохраняется в ш ременной
$f ood, а значение — в $price.
3. Значение переменной $ p r i c e преобразуется в денежный формат.
4. Выводятся в одну строку наименование продукта и его цена.
5. Обрабатывается следующий элемент массива $category.
6. Формат переменной $price преобразуется в денежный, и выводится последующая
строка с наименованием продукта и его цены.
106 Часть II. Переменные и данные
7. По достижении конца массива $ c a t e g o r y заканчивается внутренний цикл выражения
f oreach.
8. Обрабатывается следующий элемент массива $foodPrices во внешнем цикле
f oreach, в котором значение присваивается переменной $category.
9. Шаги 1-8 повторяются до тех пор, пока не будет достигнут конец массива
$category. Таким образом, будут завершены внутренние и внешние циклы выражения
f oreach.
Другими словами, внешний цикл f oreach начинается с первого элемента с индексом
vegetable и значением-массивом, которое присваивается переменной $category. В свою
очередь, внутренний цикл f oreach предназначен для прохода по всем элементам массива
$category и заканчивается по достижении последнего элемента. Затем осуществляется переход
во внешний цикл f oreach, где обрабатывается вторая пара индекс-значение массива
$f oodPrices, и т.д. до конца.
Массивы, вспоенные в PHJ*
В языке РНР имеется несколько встроенных массивов, которые можно использовать при
написании сценариев. При этом в них содержится различная полезная информация. Например,
данные об используемом сервере (заголовках, настраиваемых путях и размещении сценариев)
сохраняются в массиве $_SERVER. Так, информация об имени текущего запущенного
сценария содержится в переменной $_SERVER [' PHP_SELF' ].
Использование суперглобальных массивов
На данный момент два набора встроенных массивов содержат одну и ту же информацию.
Одни из них были включены в РНР 4.1.0 и назывались суперглобальными (superglobal)
или автоглобальными (autoglobals), поскольку могли использоваться в любом фрагменте
кода, даже внутри функций. (Функции и использование переменных внутри них описываются
в главе 8.) Более ранние версии массивов с длинными именами, такими как
$HTTP_SERVER_VARS, предварительно необходимо было объявить глобальными, чтобы
иметь возможность использовать их в функциях (подробнее об этом — в главе 8). В общем
случае рекомендуется использовать новые версии массивов, имена которых начинаются
с символа подчеркивания (_). К старым версиям необходимо прибегать только в тех случаях,
когда использование версий РНР ниже 4.1.0 неизбежно.
Обновленный конфигурационный файл php. i n i , используемый в РНР 5, позволяет предотвратить
автоматическое создание старых массивов с длинными именами. Вряд ли есть необходимость
их использования, однако некоторые старые сценарии все еще могут их использовать.
Следующая строка в файле php. i n i позволяет управлять этими установками:
register_long_arrays = On
На данный момент по умолчанию это значение равно On. Если старые сценарии не используются,
это значение стоит изменить на Of f.
И хотя в данный момент это значение по умолчанию равно On, в будущем ситуация может
измениться, и это значение станет равным Off. Если, например, запускается сценарий и выдается
ошибка в строке кода, содержащей переменную типа $HTTP_GET_VARS, то следует
проверить настройки в файле php. i n i , чтобы иметь возможность использовать массивы
с длинными именами. Если это значение равно Off, значит, данные массивы не были созданы
вообще и их использование запрещено.
Глава 6. Объединение данных с помощью массивов 107
Список встроенных массивов и их краткое описание представлены в табл. 6.2. Детальное
описание возможностей специальных массивов приведено в соответствующих главах данной
книги. Например, встроенные массивы, содержащие информацию о данных формы, описываются
в главе 10.
Таблица 6.2. Встроенные массивы
Массив Описание
$GLOBALS
$_POST
$HTTP_POST_VARS
$_GET
$HTTP_GET_VARS
$_COOKIE
$HTTP_COOKIE_VARS
$_SESSION
$HTTP_SESSION_VARS
$_REQUEST
$_FILES
$HTTP_FILES_VARS
$_SERVER
$HTTP_SERVER_VARS
$_ENV
$HTTP_ENV_VARS
Содержит все глобальные переменные. Например, если переменной
$ t e s t v a r присваивается значение 1, к ней можно получить доступ
следующим образом: $ G L O B A L S [ ' t e s t v a r ' ]
Содержит все переменные формы, переданные с помощью метода POS,V
method = "post"
То же, что и $_POST
Содержит все переменные, переданные с предыдущей страницы как час i
URL-адреса, а также переменные формы, переданные с помощью метод;.
GET: method = "get"
То же, что и $_GET
Содержит все переменные cookie
То же, что и $_COOKIE
Содержит все переменные сеанса
То же, что и $_SESSION
Содержит все переменные, которые содержатся в массивах $_POST,
$_GETH$SESSION ^
Содержит имена всех загруженных файлов
То же, что и $_FILES
Содержит информацию об используемом сервере. Поскольку Web-серве зы
бывают разные, то и информация может быть различной
ТО же, ЧТО И $_SERVER
Содержит информацию об операционной системе: имя, системный диск,
путь к временному каталогу. Очевидно, что эта информация зависит от
используемой операционной системы
То же, что и $_ENV
Использование массивов $_SERVER И $_ENV
Массивы $_SERVER и $_ENV позволяют получить информацию об используемом серв гре
и операционной системе. Для вывода данных, которые содержатся с этих массивах, можно
воспользоваться следующим фрагментом
foreach($_SERVER as $key => $value)
{
echo "Ключ = $key, Значение = $value\n";
}
В результате получим:
Kni04=DOCTJMENT_ROOT, Значение=с:/program files/apache
group/apache/htdocs
Knio4=PHP_SELF, 3Ha4eHHe=/test .php
108 Часть II. Переменные и данные
Элемент с ключом DOCUMENT_ROOT содержит путь к каталогу, в котором Web-сервер
Apache ищет требуемые Web-страницы. Элемент с индексом PHP_SELF содержит имя сценария,
который выполняется в данный момент.
Для просмотра информации в массиве $_ENV можно также воспользоваться функцией
phpinf о () с аргументом 16:
phpinfо(16);
Встроенные массивы можно использовать только тогда, когда включен режим
t r a c k - v a r s . По умолчанию он включен начиная с версии РНР 4.0.3, кроме тех
случаев, когда администратор намеренно не выключает его при установке РНР.
Однако это происходит редко. Но если есть подозрение, что режим t r a c k - v a rs
отключен, это следует проверить с помощью функции phpinf о (). И, если это
так, необходимо переустановить модуль РНР.
Использование переменных $argv и $argc
Иногда информацию для сценария необходимо передать извне. Одним из возможных способов
является передача данных посредством командной строки при запуске сценария. Однако для
Web такой метод используется редко, в отличие от запуска РНР CLI из командной строки.
Пусть, например, необходимо написать программу, суммирующую два числа, значения которых
нужно передать при запуске сценария. Это можно осуществить с помощью следующей команды:
php add.php 2 3
В этом выражении add. php — имя сценария, а 2 и 3 — числа, которые необходимо
сложить. Эти значения можно получить в сценарии, используя массив $argv. В нем содержится
следующая информация:
$argv[0] = add.php
$argv[l] = 2
$argv[2] = 3
Таким образом, массив $argv содержит по крайней мере одно значение — имя сценария,
Затем в сценарии можно воспользоваться операцией суммирования двух чисел:
$sum = $argv[l]+$argv[2];
echo $sum;
В результате получим значение
5
Можно воспользоваться также и переменной $argc. Она используется для подсчета количества
элементов в массиве $argv. Минимальное значение переменной $argc — 1, которое
соответствует имени сценария. В предыдущем примере ее значение равно 3.
Глава 6. Объединение данных с помощью массивов 109
Часть III
Основы программирования
на PHP
ЛЯ не могц о&ъя^нимь 9Ыом С^АШ, НО КЛЖ^МИ рлз
коглА я ЬАКЦ<ЖЙЮ игрц 6 голь^, небольшой
3 э/пой чаапи
! этой части рассказывается о том, как написать полноценный сцена
языке РНР и объединить разные операторы в окончательный код сцен
Речь пойдет о сложных операторах, направленных на решение сложных
задач. Эта часть также будет посвящена вопросам, связанным с повторным
использованием кода РНР. После ее изучения вы будете иметь все навыки,
одимые для написания полезных и сложных РНР-сценариев.
Глава 7
Управление ходом выполнения сценария
3 этой главе...
> Изменение порядка выполнения операторов в сценарии
> Проверка условий
> Создание сложных условий путем объединения простых
> Использование условий в условных выражениях и циклах
> Использование конструкции i f
> Создание и использование циклов
> Прерывание циклов
HP-сценарий представляет собой набор инструкций в файле. Выполнение инструкций
осуществляется в порядке их следования в файле, начиная с самого начала. Однако
в большинстве случаев необходимо создавать более сложные сценарии. Например, нужно
разработать сценарий, который будет отображать одну страницу для новых покупателей
и совсем другую для уже существующих, или необходимо вывести на экран список телефонных
номеров с помощью повторного использования одной и той же функции echo. В этой
главе вы узнаете, как изменять порядок выполнения простых операторов с помощью более
сложных инструкций, таких как условные операторы и циклы.
изменение по/ьяс/ка выполнения,
опе/га&ормв в сценарии
Простые операторы РНР выполняются по очереди, один за другим, с начала и до конца.
Рассмотрим следующий фрагмент кода:
$а = "Доброе утро";
echo $а;
$а = "Добрый день";
echo $a; ,
Для того чтобы изменить порядок выполнения операторов, необходимо изменить порядок
их следования в файле, например:
$а = "Добрый день";
echo $a;
$а • "Доброе утро";
echo $a;
Предположим, что нужно вывести приветственное сообщение в зависимости от времени
суток, т.е. до полудня необходимо отображать Доброе утро, а после полудня — Добрый
день. Другими словами, нужно сделать следующее:
i f (время до полудня)
{
$а = Доброе утро;
?
echo $a;
}
or else if (время после полудня)
{
$a = Добрый день;
echo $a,-
}
Таким образом, для вывода соответствующего приветственного сообщения следует воспользоваться
сложным оператором, в котором проверяется время суток. Язык РНР предоставляет
два возможных способа, которые позволяют выполнять такие сложные действия.
S Условные операторы. В некоторых случаях необходимо выполнять операторы
или какие-либо действия только при выполнении определенных уело шй.
Например, каталог с продукцией необходимо показывать только покупателям,
которые оплатили свои счета, и не делать этого для тех, кто имеет задолхен-
ность. Такие операторы называются условными (conditional statement). В .'HP
существуют условные операторы i f и switch.
•S Циклы. Часто требуется выполнить некоторый блок кода несколько раз под эяд.
Например, нужно передать сообщения по электронной почте всем покупатсим.
Чтобы осуществить это, необходимо выполнить две операции: первая из ню будет
извлекать информацию об электронных адресах покупателей из базы даш пых,
а вторая — отправлять соответствующие сообщения. Причем эти действия ну кно
осуществить для всех покупателей из базы данных. Операция, которая позво.[яет
выполнять операторы несколько раз подряд, называется циклом (loop). В РНР
циклы реализуются с помощью операторов for, while и do. . while.
Оба рассмотренных типа сложных операторов выполняют некий фрагмент кода в зав» :си-
мости от условий, т.е. если условие верно, то оператор выполняется. Причем в условных операторах
код выполняется один раз. Например, если текущее время является послеобеденн >ш,
то будет выведена строка Добрый день. В циклах блок кода выполняется несколько ра: до
тех пор, пока условие не станет ложным. Например, если какой-то покупатель еще не получил
электронное сообщение, то его необходимо отправить. И этот цикл повторяется до тех
пор, пока сообщения не будут отправлены всем покупателям.
Jlfioeefitca условий
Условия (condition) — это выражения, которые могут принимать два значения: истина пли
ложь. Условия применяются в сложных операторах для того, чтобы определить, выполнять
последующий блок кода или нет. Для проверки условий необходимо сравнить некоторые значения.
При этом возможны следующие варианты вопросов.
•S Равны ли два значения? Имеет ли Бобби ту же фамилию, что и Салли? Достиг
ли Ник 15-летнего возраста?
S Больше или меньше одно значение другого? Младше ли Ник, чем Боб(>и?
Стоит ли дом Салли больше одного миллиона долларов?
S Соответствует ли строка шаблону? Начинается ли имя Бобби с буквы С?
Состоит ли почтовый индекс из пяти цифр?
Можно проверять условия, состоящие из нескольких вопросов. Рассмотрим такие примеры.
Верно ли, что Ник старше Бобби и младше Салли? Верно ли, что сегодня воскресенье
и солнечный день? Верно ли, что сегодня воскресенье или понедельник?
114 Часть III. Основы программирования на P\
Использование операций сравнения
В РНР имеется набор операций, предназначенных для сравнения значений (табл. 7.1).
Таблица 7.1. Операции сравнения
Операция Описание
== Равнозначны ли значения двух переменных?
=== Одинаковы ли как значения, так и типы двух переменных?
> Больше ли первое значение, чем второе?
>= Верно ли, что первое значение не меньше второго?
< Меньше ли первое значение, чем второе?
<= Верно ли, что первое значение не больше второго?
! =, <> Не равны ли значения двух переменных?
! == Не одинаковы ли значения или типы данных двух переменных?
Сравнивать можно как числовые значения, так и строковые. Текстовые строки ранжируются
в алфавитном порядке, причем строки, которые начинаются с прописных букв, предшествуют
строкам, начинающимся со строчных, например SS идет перед Sa. Символы пунктуации также
имеют свой порядок следования, и можно говорить о том, что один символ "больше" другого.
Однако такое сравнение, например запятой и точки, не имеет большого практического значения.
Текстовые строки можно сравнивать на основе ASCII-кодов. Каждый символ
имеет свой ASCII-код, который соответствует целому числу от 0 до 127. И соответственно
сравнение текстовых строк осуществляется на основе этого кода. Например,
код, соответствующий запятой, равен 44, а точке — 46. Таким образом,
можно сказать, что точка "больше" запятой.
Рассмотрим несколько примеров правильных выражений проверки на истинность в РНР.
• $а == $Ь
V $аде != 21
/ $ageNick < $ageBobby
•f $house_price >= 1000000
Операция сравнения, проверяющая равенство двух значений, состоит из двух символов
равенства (==). Одной из наиболее частых ошибок является использование
для сравнения одного знака равенства (=). В этом случае происходит присваивание
значения переменной. Так, в выражении i f ($weather = "дождливая") значение
переменной $weather станет равным "дождливая", сравнение производиться
не будет, и результат этого оператора всегда будет истинным.
РНР проверяет условие и возвращает булево значение: TRUE (истина) или FALSE (ложь).
Рассмотрим следующее выражение:
$а == $Ъ
Если, например, $а = 1 и $Ь = 1, то это выражение будет истинным, а в случае $а =
1 и $Ь = 2 — ложным.
Для отрицания при сравнении используется операция восклицания (!). Рассмотрим следующий
фрагмент кода:
$аде ! = 21
Глава 7. Управление ходом выполнения сценария 115
В этом выражении проверяется, не равно ли значение переменной $аде числу 21. Е<:ли,
например, $аде = 20, это условие истинно.
Проверка содержимого переменной
Иногда необходимо проверить, существует ли переменная или какое она имеет значе! ме.
Ниже приведены функции, позволяющие выполнить такие действия.
isset($имя_переменной) #Истина, если переменная
#объявлена даже без присваивания значения.
empty($имя_переменной) #Истина, если значение переменной
#равно нулю или пустой строке,
#либо переменная не объявлена.
РНР также позволяет проверить тип переменной. Например, для того чтобы проверить,
является ли переменная целочисленной, следует воспользоваться функцией
is_int($number)
Результатом выполнения этой функции является TRUE, если переменная $number имеет
тип i n t e g e r . Рассмотрим подобные функции.
S i s _ a r r a y ($var2) проверяет, является ли переменная $var2 массивом.
S is_f l o a t ($number) проверяет, является ли переменная $number числом
с плавающей точкой.
S is_null ($varl) проверяет, равно ли значение переменной $varl нулю
S is_numeric($string) проверяет, является ли переменная $ s t r i n g ш-
словой строкой.
S i s _ s t r i n g ($string) проверяет, является ли переменная $ s t r i n g строи й.
Для проверки обратных условий следует воспользоваться символом восклицания (!). Например,
при обработке следующего выражения будет получено значение TRUE, если переменная
не объявлена:
! isset($имя_переменной)
Использование регулярных выражений
Зачастую необходимо проверить, обладает ли текстовая строка определенными характеристиками,
а не просто совпадает с конкретным значением. Например, нужно найти строки,
начинающиеся с символа S или содержащие числа. В этом случае строки сравниваются с неким
шаблоном. Такие выражения называются регулярными (regular expression).
Возможно, вам уже приходилось использовать регулярные выражения. Например, при поиске
файлов символ звездочки (*) часто используется для обозначения любого символа или нескольких
символов (dir ex* . doc или I s ex* . txt). В этом случае ex* . t x t является шаблоном,
которому соответствуют такие строки, как exam, t x t , ехЗЗ. t x t и ехЗх4. t x t . Проверка регулярных
выражений, конечно же, посложнее, чем просто использование символа звездочки.
Одним из наиболее частых применений регулярных выражений является проверка данных,
введенных пользователями с помощью форм. Если информация не удовлетворяет определенному
формату (шаблону), ее не следует сохранять в базе данных. Например, если пользователь
вводит почтовый индекс, он должен состоять либо из пяти цифр, либо еще включать
четыре дополнительные цифры через дефис. Другими словами, с помощью регулярных выражений
можно проверить, соответствует ли введенная информация нужному шаблону. Если
нет — необходимо заставить пользователя ввести ее заново, в корректной форме.
116 Часть III. Основы программирования на Рг ]Р
Использование в шаблоне специальных символов
Обычно шаблоны состоят из буквенных (литеральных) и специальных символов. Буквенные
символы не имеют какого-то специального назначения. Например, символ е определяет
букву е как одну из 26 букв алфавита. В то же время специальные символы имеют в шаблонах
свое функциональное назначение. Например, символ звездочки заменяет любой другой
символ или несколько вхождений этого символа. В табл. 7.2 приведен список и краткое описание
специальных символов, использующихся в шаблонах.
Таблица 7.2. Специальные символы, используемые в шаблонах
Символ
Л
$
?
( )
[ ]
[ Л ]
-
Назначение
Начало строки
Конец строки
Любой одиночный символ
Предшествующий символ является
не обязательным
Группирует буквенные символы в
последовательность, которую в
точности должна содержать строка
Включает набор необязательных
символов
Определяет все символы, кроме
указанных
Включает диапазон всех символов,
Пример
"э
н$
ger?m
g ( e r )m
g [ e r ]m
g [ A e r ]m
g [ a - c ]m
Соответствует шаблону
экзамен
экзамен
до, от
Более длинные слова
также соответствуют
этому шаблону, поскольку
включают текстовую
строку из двух символов
germ, gem
germ
gem, grm
gym, gum
gam, gbm, gem
He соответствует
шаблону
математический
экзамен
экзамены
а, 2
geam
Gem, grem
germ, g e l
gem, grem, germ
gdm, gxm, g a l
{Л}
заключенных между двумя (ряд
возможных символов)
Один или несколько наборов
предшествующих символов
Один, ни одного или несколько
вхождений предшествующего
символа
Повторение п раз
bldg[l- bldglll, bldgl32 bldg, bldg555
3] +
in1,n2) Определяет диапазон повторений
символа (символов)
\ Определяет буквенный символ
( | I ) Набор альтернативных строк
ge*m
ge{5}m
а { 2 , 5}
g\*m
(Сэм|Салли)
gm, geeem
geeeeem
aa, aaa, aaaa,
145aaaaa
g*m
Салли
germ, grm
geeeem,
geeeeeem
1, a3
gem, germ
Сара,Салмон
Некоторые примеры шаблонов
Для создания достаточно сложных шаблонов используются различные комбинации буквенных
и специальных символов. Текстовая строка сравнивается с созданным шаблоном, и в случае
их взаимного соответствия возвращается истинное значение (TRUE). Рассмотрим различные
примеры шаблонов, а также соответствующих и несоответствующих им текстовых строк.
Глава 7. Управление ходом выполнения сценария 117
Пример 1
А[А-Яа-я] .*
Этот шаблон определяет строки, начинающиеся с букв, и состоит из двух частей.
S Л [А-Яа-я]. Первая часть определяет, что строки должны начинаться с Оукв
(как верхнего, так нижнего регистра).
S .*. Вторая часть указывает на то, что строка должна состоять из одного или
нескольких символов.
Этому шаблону удовлетворяют следующие текстовые строки: играй в футбол, Сэм и Я.
Такие строки, как 123 и ?, ему не соответствуют.
Пример 2
Уважаемый (Ким|Рикки)
Этот шаблон определяет две различные строки и состоит из двух частей.
S Уважаемый. Первая часть соответствует простому набору букв.
•S (Ким | Рикки). Вторая часть соответствует либо значению Ким, либо Рикки.
Шаблону Уважаемый (Ким| Рикки) соответствуют текстовые строки Уважаемый
Ким и Уважаемый Рикки.
Такие выражения, как Уважаемый Боб и Ким, не удовлетворяют этому шаблону.
Пример 3
Л[0-9]{5}(\-[0-9]{4))?$
Этот шаблон определяет общий формат почтового индекса и состоит из нескольких частей.
•S Л [ 0 - 9 ] {5}. Первая часть определяет строку, состоящую из пяти цифр.
•S \~. Символ обратной косой черты (\) указывает на то, что дефис (-) в данном
случае используется в качестве буквенного, а не специального символа.
S [ 0 - 9 ] {4}. Эта часть шаблона определяет строку, состоящую из четырех ци< [>р.
•/ ( ) ?. Этот набор символов включает в себя последние две части шаблэна
и указывает на то, что они являются необязательными.
S $. Символ доллара ($) является символом конца строки (т.е. после шаблонг не
должны стоять никакие другие символы).
Этому шаблону удовлетворяют текстовые строки 90001 и90002-4323.
Такие строки, как 9001 и 12-4321, ему не соответствуют.
Пример 4
л . + @ . + \ . с о т$
ЭТОТ шаблон определяет любую строку, содержащую символ В и имеющую окончание
.com. Другими словами, он задает адрес электронной почты. Этот шаблон состоит из сне-
дующих частей.
•S л . +. Первая часть определяет строку, которая начинается с любого символа
и предшествует символу @.
S @. Этот символ является буквенным, а не специальным, поэтому нет необходимости
ставить перед ним символ обратной косой черты (\).
•S .+. Этот набор специальных символов определяет строку, состоящую из одного
или нескольких символов.
118 Часть III. Основы программирования на PriP
•S \ .. Символ \ указывает на то, что символы точки (.) должны интерпретироваться
как буквенные символы.
S com$. Эта часть шаблона определяет, что строка должна обязательно заканчиваться
символами com.
Такому шаблону удовлетворяют текстовые строки you@yourcompany.com и
j ohndoeSsomedomain.com.
Такие строки, как you@yourcompany. net, you@. com и @you. com, ему не соответствуют.
Сравнение строк с шаблоном
Для сравнения строк с шаблоном можно воспользоваться функцией e r e g (). Ее синтаксис
имеет следующий вид:
ereg("шаблон", значение);
Например, для того чтобы проверить правильность имени, введенного пользователем
в форме, необходимо сравнить переменную $name (в которой оно хранится) с шаблоном:
ereg("Л[А-Яа-я1 -]+$", $name)
Данный шаблон интерпретируется следующим образом.
•/ Символы Л и $ определяют начало и конец текстовой строки соответственно. Это
означает, что строка должна полностью соответствовать созданному шаблону.
S Все разрешенные буквенные символы строки заключаются в квадратные
скобки. К ним относятся буквы верхнего и нижнего регистров, апостроф,
пробел и дефис.
В пределах квадратных скобок можно задавать область изменения символов
(например, А-Я). При этом дефис интерпретируется не как буквенный, а как
специальный символ. Для того чтобы изменить это правило, необходимо,
чтобы дефис не был заключен между двумя символами, т.е. его следует разместить
в конце, после набора букв.
•S После квадратных скобок следует символ "плюс". Он указывает на то, что
строка может содержать любое количество символов, заданных в квадратных
скобках, но не меньше одного.
Объединение условий
Часто бывает необходимо проверить несколько условий одновременно. Предположим,
например, что компания имеет каталог продуктов на различных языках. Необходимо определить,
описаниями каких продуктов интересуется покупатель и на каком языке. Для этого следует
объединить несколько условий. Общий синтаксис имеет следующий вид:
условие1 and|or|хог условие2 and|or|хог условиеЗ and|or|хог . ..
Условия можно объединять с помощью следующих трех выражений (логических операторов).
S and (логическое И). Результирующее условие истинно, если истинны оба условия.
S or (логическое ИЛИ). Результирующее условие истинно, если хотя бы одно
из условий истинно.
*/ хог (логическое исключающее ИЛИ). Результирующее условие истинно, если
истинно одно из условий, но не оба одновременно.
Глава 7. Управление ходом выполнения сценария 119
В табл. 7.3 приведены примеры сложных условий, состоящих из более простых.
Таблица 7.3. Сложные условия
Условие Истина, если...
$ageBobby == 21 or $ageBobby == 22 Бобби 21 ИЛИ 22 ГОДЭ
$agesaily > 29 and $ s t a t e == "OR" Салли больше 29 лет, и она живет штате Орегон
$ageSally > 29 or $ s t a t e == "OR" Салли больше 29 лет или она живет штате Орегон
$ c i t y == "Рено" xor $ s t a t e == "OR" Значение переменной $ c i t y равно Рено или
значение переменной $ s t a t e —OR, НО не
одновременно
$паше !« "Сэм" and $age < 13 Любое ИМЯ, кроме Сэм, И возраст не старше 13 лег
Можно объединить любое количество условий. При этом порядок проверки условий следующий:
наибольший приоритет имеют выражения, содержащие and, затем хог и or. Рассмотрим
следующее составное условие, состоящее из трех простых:
$resCity == "Рено" or $resState == "NV" and $name == "Салли"
Если имя покупателя Салли и она живет в штате Невада (NV), то результирующее выражение
истинно. Тот же результат будет получен и в том случае, если покупатель живет в городе
Рено, независимо от его имени. Это условие ложно, если покупатель обитает в Невгде,
но его именем является не Салли. Все эти результаты получаются в результате следующего
порядка проверки условий.
1. Обрабатывается выражение, содержащее логическое И (and). Интерпретатор РНР
проверяет, равны ли значения переменных $ r e s S t a t e и $name соответственно NV
и Салли. Если оба значения совпадают, то условие верно и нет необходимости про зе-
рять условие, содержащее or. В противном случае РНР переходит к обработке следующего
(по приоритету) выражения.
2. Обрабатывается выражение, содержащее логическое ИЛИ (or). Интерпретатор РАР
проверяет значение переменной $resCity. Если оно равно Рено, то условие истинно,
иначе — ложно.
Для того чтобы изменить порядок обработки логических операторов, следует воспользоваться
скобками (()). Тогда условия, заключенные в скобки, будут иметь больший приор и-
тет. Например, предыдущий пример можно переписать следующим образом:
($resCity == "Рено" or $resState == "NV") and $name == "Салли"
В этом случае скобки позволяют изменить порядок проверки условий, т.е. сначала будет с б-
рабатываться выражение, содержащее логическое ИЛИ (or). Результирующее условие будет *с-
тинным в том случае, если имя покупателя Салли и она живет либо в городе Рено либо в штате
Невада (NV). Этот результат получен благодаря следующему порядку проверки условий.
1. Обрабатывается выражение, содержащее логическое ИЛИ (or). Интерпретатор РНР
проверяет, равны ли значения переменных $resCity и $ r e s S t a t e соответственно
Рено и NV. Если обе эти переменные имеют другие значения, то результирующее условие
ложно и проверка прекращается. В противном случае РНР переходит к обработке
следующего (по приоритету) выражения.
2. Обрабатывается выражение, содержащее логическое И (and). PHP проверяет значение
переменной $name. И если оно равно Салли, то результирующее условие истиннэ,
иначе — ложно.
120 Часть III. Основы программирования на РНР
Скобки стоит использовать даже в тех случаях, когда вы уверены в порядке обработки
условий. Лишние скобки не помешают. В противном случае результат проверки
условий может оказаться самым неожиданным.
Если вы знакомы с другими языками программирования, например С, то вам, наверное,
приходилось использовать такие операторы, как | | (в качестве логического ИЛИ
or) и && (в качестве логического И and). Эти операторы можно применять и в языке
РНР. Например, выражение $а < $Ь && $с > $Ь эквивалентно $а < $b and
$с > $Ь. При этом оператор | | проверяется перед or, а && — перед and.
использование условных onefiounofioe
Условный оператор (conditional statement) выполняет фрагмент кода только при соблюдении
определенного условия. Рассмотрим два наиболее полезных вида условных операторов.
•S Оператор if. Проверяет условие и, если оно истинно, выполняет соответствующий
фрагмент кода.
•S Оператор switch. Проверяет набор альтернативных условий и, если одно из
условий истинно, выполняет соответствующий фрагмент кода.
Использование оператора i f
Оператор i f предполагает проверку некоторого условия и, если оно истинно, выполнение
соответствующего блока инструкций. Общий синтаксис оператора i f имеет следующий вид:
i f (условие)
фрагмент кода
elseif {условие)
фрагмент кода
else
фрагмент кода
Оператор i f состоит из следующих элементов.
J if. Обязательная часть, проверяющая условие.
• Если условие истинно, выполняется первый фрагмент кода. После выполнения
операторов этого блока интерпретатор РНР переходит к обработке
следующего за i f оператора. Если условный оператор содержит также
блок e l s e i f или e l s e , они пропускаются.
• Если условие ложно, первый фрагмент кода не выполняется и интерпретатор
РНР переходит к обработке следующей за этим фрагментом инструкции,
которой может оказаться блок e l s e i f , e l s e или любой другой
оператор, следующий за i f.
«йЙЭйь
ч•«Я"ОБЙНО' ^
Глава 7. Управление ходом выполнения сценария 121
•/ e l s e i f . Необязательный раздел оператора i f . При желании можно испэль-
зовать несколько разделов e l s e i f . В этих разделах тоже проверяется истинность
некоторого условия.
• Если условие истинно, выполняется соответствующий фрагмент кэда.
После выполнения всех операторов этого фрагмента РНР переходит к обработке
следующего за i f оператора. Если условный оператор содержит
несколько блоков e l s e i f и e l s e , они игнорируются.
• Если условие ложно, соответствующий фрагмент кода не выполняется
и РНР переходит к обработке следующего блока оператора i f (т.е. бюка
e l s e i f или else), а при его отсутствии — к следующему за i f оператору.
•S e l s e . Этот раздел тоже является необязательным. При этом в рамках одного
оператора i f блок e l s e можно использовать только один раз. В блоке e.'.se
условие не проверяется, а выполняется фрагмент кода, если все условия, содержащиеся
в предыдущих блоках оператора if, ложны.
Рассмотрим пример использования оператора if. Представьте, что вы— учитель. Следующий
оператор передает студенту оценку и небольшое текстовое сообщение, в зависи tio-
сти от количества баллов, набранных при выполнении теста:
i f ($score > 92)
$grade = "А";
$message = "Отлично";
lseif ($score <= 92 and $score > 83)
$grade = "B";
$message = "Хорошо";
elseif ($score <= 83 and $score > 74)
$grade = "C";
$message = "Удовлетворительно";
elseif ($score <= 74 and $score > 62)
$grade = "D";
$message = "Неудовлетворительно";
lse
$grade = "F";
$message = "Хуже некуда!";
echo $message. "\n";
echo "Ваша оценка $grade\n";
Оператор i f обрабатывается следующим образом.
1. Значение переменной $score сравнивается с 92.
Если оно больше этого числа, переменной $grade присваивается А, а переменней
$message — значение Отлично, и интерпретатор РНР переходит к строкам, в которых
информация выводится с использованием функции echo. Если $score меньше
122 Часть III. Основы программирования на РНР
или равно 92, переменные $grade и $message не инициализируются и интерпретатор
РНР переходит к инструкции e l s e i f.
2. Значение переменной $score сравнивается с числами 92 и 83.
Если оно меньше или равно 92 и больше 83, выполняется инициализация переменных
$ grade и $message, и интерпретатор РНР переходит к строкам, в которых информация
выводится с использованием функции echo. Если $ s c o r e меньше или равно
83, переменные $grade и $message не инициализируются и интерпретатор РНР переходит
ко второй инструкции e l s e i f .
3. Значение переменной $score сравнивается с 83 и 74.
Если оно меньше или равно 83 и больше 74, выполняется инициализация переменных
$grade и $message и интерпретатор РНР переходит к строкам, в которых информация
выводится с использованием функции echo. Если $ s c o r e меньше или равно 74,
переменные $grade и $message не инициализируются и интерпретатор РНР переходит
к следующей инструкции e l s e i f.
4. Значение переменной $score сравнивается с 74 и 62.
Если оно меньше или равно 74 и больше 62, осуществляется инициализация переменных
$grade и $message и интерпретатор РНР переходит к выводу данных с использованием
функции echo. Если $score меньше или равно 62, переменные $grade
и $message не инициализируются и интерпретатор РНР переходит к инструкции e l s e .
5. Переменной $grade присваивается значение F, a $message — "Хуже некуда!", и интерпретатор
РНР переходит к выводу информации с использованием функции echo.
Если фрагмент кода, выполняемый после проверки условия, состоит из одного
выражения, фигурные скобки можно опустить. Допустим, в предыдущем примере
инициализировалась только одна переменная $grade, т.е.
i f ($grade > 92)
{
$grade = "А";
}
Теперь это выражение можно переписать следующим образом:
if ($grade > 92)
$grade = "А";
Такая сокращенная запись позволяет избежать написания лишнего кода. Однако,
если имеется несколько выражений, это может привести к путанице.
Отрицание в операторе if
Если необходимо, чтобы блок операторов выполнялся в случае невыполнения некоторого
условия, перед этим условием следует поставить восклицательный знак (!). Рассмотрим для
примера следующее выражение:
if (егед("ЛС[а-я]*", $string))
{
$list[] = $string. "\n",-
}
Этот условный оператор проверяет, начинается ли строка $ s t r i n g с символа С. Другими
словами, если строка $ s t r i n g соответствует шаблону, определяющему строки, которые начинаются
с символа С, за которым следуют буквы нижнего регистра, — блок операторов выполняется.
Если перед условием поставить восклицательный знак, ситуация кардинально изменится:
Глава 7. Управление ходом выполнения сценария 123
i f (!едгед("лС[а-я]*", $string)
{
$ l i s t [ ] = $string."\n";
}
В этом случае из-за наличия восклицательного знака (!) перед условным выражением
массив $ l i s t будет содержать все строки, кроме тех, которые начинаются с символа С, т.е.
условие истинно, если строка $ s t r i n g не начинается с символа С.
Вложенные операторы if
Условный оператор i f можно использовать в другом условном операторе. Такое действие
называется вложением (nesting). Пусть, например, необходимо связаться со всеми клиентами,
которые живут в штате Айдахо (Idaho, ID). При этом клиентам, имеющим адрес электронной
почты, нужно отправить электронное сообщение, а тем, кто его не имеет, — пис ;,мо
по обычной почте. Это можно сделать с помощью вложенного оператора if:
i f ($custState == "ID")
{
if ($EmailAdd = "")
{
$contactMethod = "по обычной почте";
}
else
{
$contactMethod = "по электронной почте";
}
}
else
{
$contactMethod = "нет необходимости";
}
Первое условие позволяет узнать, проживает ли клиент в штате Айдахо. Если это так,
сценарий РНР проверит наличие адреса электронной почты. Если у клиента его нет, переменной
$contactMethod (которая определяет вид связи) присваивается значение по
обычной почте, иначе — по электронной почте. Если же клиент проживает не в штате
Айдахо, ему ничего не отправляется.
Оператор switch
Во многих ситуациях оператор i f работает отлично. Однако иногда имеется список условий,
для каждого из которых необходимо выполнить свой набор операторов. Например,
нужно написать сценарий, который будет вычислять налог с оборота. Как в этом случае
учесть разную налоговую ставку для различных штатов? Именно для таких ситуащй
и предназначен оператор switch.
Оператор switch проверяет значение некоторой переменной, и если оно совпадает
с имеющимся в перечне, выполняются соответствующие операторы. Общий синтаксис инструкции
switch имеет следующий вид:
switch ($имя_переменной)
{
case значение:
фрагмент кода;
break;
case значение:
фрагмент кода;
124 Часть III. Основы программирования на PhP
break;
default:
фрагмент кода;
break;
}
При выполнении оператора switch интерпретатор PHP пытается найти строку case, содержащую
значение, равное значению переменной $имя_переменной. Если такая строка
обнаружена, выполняется соответствующий фрагмент кода до оператора break. Если же найти
такую строку не удалось, выполняется фрагмент кода, следующий после ключевого слова
default. В операторе switch можно задавать любое количество вариантов. При этом использование
ключевого слова d e f a u l t не обязательно, но при его наличии строку d e f a u l t обычно
ставят в конце оператора switch. Однако для интерпретатора РНР это не имеет значения.
Рассмотрим следующий пример, учитывающий различные ставки на налог с оборота для
различных штатов:
switch ($custState)
{
case "OR":
$salestaxrate = 0;
break;
case "CA":
$salestaxrate = 1.0;
break;
default:
$salestaxrate = .5;
break;
}
$salestax = $orderTotalCost*$salestaxrate;
В этом примере налог с оборота в штате Орегон равен 0%, в Калифорнии— 100%, а для
всех остальных штатов — 50%. При выполнении оператора switch интерпретатор РНР пытается
найти строку case, содержащую значение, равное значению переменной
$custState. Если такая строка обнаружена, переменной $ s a l e s t a x r a t e присваивается
определенное значение. Например, если $ c u s t S t a t e равно ТХ (штат Техас), осуществляется
переход к строке с ключевым словом d e f a u l t и переменной $ s a l e s t a x r a t e присваивается
значение . 5. После выполнения оператора switch значение переменной $ s a l e s t ax
будет равно половине (. 5) от суммы заказа ($orderTotalCost).
Необходимо обратить внимание на операторы break, расположенные в конце каждого
блока case. Если бы не они, интерпретатор РНР продолжал бы выполнять операторы либо
до следующего оператора break, либо до конца инструкции switch. Это касается всех блоков
case, кроме последнего.
Последний блок case оператора switch не требует оператора break. Однако
его стоит использовать для большей ясности и согласованности кода.
fljoefnofienue qeuctntfuu с помощью циклов
Циклы очень часто используются в сценариях для многократного выполнения некоторых
действий. При этом операции цикла повторяются либо некоторое наперед заданное количество
раз, либо до выполнения определенных условий. Например, цикл, который выводит со-
Глава 7. Управление ходом выполнения сценария 125
кращенные названия штатов с помощью функции echo, необходимо повторить 50 раз,
а цикл, который выводит имена файлов в каталоге, — пока не будут обработаны все фа }лы
(независимо от их количества). В языке РНР существуют три типа циклов.
•/ for. Проверяет значение счетчика цикла и повторяет действия до тех пор,
пока счетчик цикла не достигнет определенного значения.
•S whi 1е. Проверяет условие и выполняет действия, пока условие не станет ложн >гм.
•/ do. .while. Выполняет действия и только потом проверяет условие. Е:ли
оно истинно— операторы цикла повторяются, в противном случае щкл
прекращается.
В следующих разделах эти виды циклов рассматриваются более подробно.
Цикл for
Традиционный цикл for основан на счетчике. Сначала осуществляется инициализация
переменной-счетчика, потом указывается ее конечное значение и определяется способ изменения
состояния счетчика после выполнения набора действий. Общий синтаксис цикла for
имеет следующий вид:
for (начальное_значение; конечное_условие; инкремент)
{
фрагмент кода;
}
Цикл for имеет следующие параметры.
•S начальное_значение. Это выражение определяет переменную-счетчик
цикла и инициализирует ее начальным значением. Например, выражение
$i=l указывает, что в качестве счетчика будет использоваться переменная
$i, а ее начальное значение равно 1. Обычно счетчик начинается с 0 или 1.
При этом в качестве начального значения можно использовать число, чист о-
вое выражение (например, 2+2) или значение переменной.
•S конечное_условие. Это выражение определяет конечное значение счетчика.
Цикл выполняется до тех пор, пока счетчик не достигнет этого значет я.
Рассмотрим, например, выражение $i<10, которое устанавливает конечное
значение, равное 10. При достижении переменной $i этого значения ци.сл
прекращается, поскольку условие $i<10 уже не будет выполняться. Выражение
конечное_условие может также иметь вид $i<$size;.
•S инкремент. Выражение, которое определяет, на какую величину будет изменяться
счетчик. Например, выражение $i++; будет увеличивать значение переменной
$i на единицу после выполнения каждой итерации (блока цикл*)-
Можно также использовать такие выражения, как $i=+l; или $ i — ; ,
В цикле for в качестве счетчика используется некая переменная, скажем $i, значение
которой изменяется в процессе выполнения цикла. При этом переменную-счетчик $ i мож* о
также использовать внутри цикла. Рассмотрим пример, в котором строка Здравствуй,
мир! выводится три раза:
for ($i=l; $i<=3; $i++)
{
echo "$i. Здравствуй, мир!<Ьг>";
}
126 Часть III. Основы программирования на РНР
Операторы тела цикла необязательно вводить с отступом. Для интерпретатора
РНР это не имеет значения. Отступ используется для лучшего понимания
кода сценария.
В результате получим следующее:
1. Здравствуй, мир!
2. Здравствуй, мир!
3. Здравствуй, мир!
Вложенные циклы for
Один цикл for можно использовать внутри другого. Пусть, например, необходимо вывести
таблицу умножения чисел от 1 до 9. Это можно сделать, используя следующий фрагмент
кода:
for ($i=l; $i<=9; $i++)
{
echo "\пУмножение на $i \n" ;
for($j=l; $j<=9; $j++)
{
$result = $i * $ j;
echo "$i x $j = $result\n";
}
}
В результате получим следующий результат:
Умножение на 1
1 x 1 = 1
1 x 2 = 2
1 x 8 = 8
1 x 9 = 9
(
Умножение на 2
2 x 1 = 2
2 x 2 = 4
2 х 8 = 16
2 х 9 = 18
Умножение на 3
3 x 1 = 3
и так далее.
Усложненные циклы for
Структура циклов for является достаточно гибкой и позволяет создавать циклы для самых
разнообразных целей. Общий синтаксис цикла for можно представить в следующем виде:
for (начальное выражение; условное выражение; заключительное
выражение)
{
фрагмент кода;
}
Параметры рассмотренного цикла f o r имеют следующее назначение.
Глава 7. Управление ходом выполнения сценария 127
•S Начальное выражение выполняется безусловно, один раз, до начала цикла.
Оно может включать присваивание начального значения или любое другое
выражение, которое требуется выполнять перед началом цикла.
S Условное выражение проверяется на истинность перед началом каждой 1те-
рации цикла.
S В конце каждой итерации цикла выполняется заключительное выражение.
Оно может включать инкремент счетчика цикла или любое другое дейст ше,
которое выполняется после каждой итерации цикла.
Рассмотренные выше выражения разделяются точкой с запятой (;). В свою очередь, каждое
из них может состоять из нескольких выражений, разделенных запятой (,), или быть пусты) л.
Рассмотрим следующий пример:
$t = 0;
for ($i=0, $j=l; $t<=4; $i++, $j+ + )
{
$t = $i + $ j;
echo "$t<br>";
}
В качестве начального выражения используется $i=0, $j=l, в качестве условной: —
$t<=4, заключительного—$i++, $j++.
Результат выполнения приведенного фрагмента будет иметь следующий вид:
1
3
5
Теперь рассмотрим более подробно процесс выполнения этого цикла.
1. Выполняется начальное выражение. При этом переменной $ i присваивается значи :ие
0, а переменной $ j — 1.
2. Проверяется условное выражение. Не превышает ли значение переменной $t числа 4?
Поскольку это так, то условие истинно и цикл продолжает выполняться.
3. Выполняются действия внутри тела цикла. Значение переменной $t вычисляется как
сумма $i и $ j (0+1 равно 1) и с помощью функции echo выводится на экран.
4. В конце данной итерации выполняется заключительное выражение: $i++ и $j-i+.
Значения переменных $i и $ j увеличиваются на единицу и становятся равными 1 и 2.
5. В начале следующей итерации проверяется условное выражение. Не превышает т
значение переменной $t числа 4? Поскольку текущее значение $t равно 1, то условие
истинно и цикл продолжает выполняться.
6. Выполняются действия внутри цикла. Значение переменной $t вычисляется как сумма
$i и $ j (1+2 равно 3) и с помощью функции echo выводится на экран.
7. В конце данной итерации выполняется заключительное выражение: $i++ и $j++.
Значения переменных $i и $ j увеличиваются на единицу и становятся равными 2 и 3.
8. В начале следующей итерации проверяется условное выражение. Не превышает ли
значение переменной $t числа 4? Поскольку текущее значение $t равно 3, то условие
верно и цикл продолжает выполняться.
9. Выполняются действия внутри тела цикла. Значение переменной $t вычисляется как
сумма $i и $ j (2+3 равно 5) и с помощью функции echo выводится на экран.
10. В конце данной итерации выполняется заключительное выражение: $i++ и $j++.
Значения переменных $i и $ j увеличиваются на единицу и становятся равными 3 и 4.
128 Часть III. Основы программирования на РНР
11. В начале следующей итерации проверяется условное выражение. Не превышает ли
значение переменной $ t числа 4? Поскольку текущее значение $ t равно 5, то условие
ложно и цикл завершается.
Цикл while
Цикл w h i l e выполняет заданные действия до тех пор, пока истинно определенное условие.
Этот вид цикла работает следующим образом.
1. Задается условие.
2. Это условие проверяется перед началом каждой итерации.
3. Если условие истинно, цикл продолжает выполняться, в противном случае — завершается.
Общий синтаксис цикла w h i l e имеет следующий вид:
while ( условие )
{
фрагмент кода;
}
В следующем примере цикл w h i l e используется для нахождения в массиве $ ? r u i t значения
яблоко:
$ f r u i t = a r r a y ( " а п е л ь с и н " , "яблоко", "виноград");
$ t e s t v a r = "нет";
$к = 0;
while ( $testvar != "да" )
{
i f ( $ f r u i t [ $ k ] == "яблоко" )
{
$ t e s t v a r = "да";
echo "яблоко\п";
}
e l s e
{
echo "$fruit[$k] - это не яблоко\п";
}
$k++;
}
В результате будет выведено следующее:
апельсин — э то не яблоко
яблоко
Рассмотрим процесс выполнения этого цикла более подробно.
1. Перед началом цикла инициализируются необходимые переменные. Создается массив
$ f r u i t с тремя элементами, тестовая переменная $ t e s t v a r со значением нет
и счетчик $к, принимающий значение 0.
2. Цикл начинается с проверки на истинность условия $ t e s t v a r != " д а " . Поскольку
переменной $ t e s t v a r было присвоено значение нет, условие верно и цикл не завершается.
3. Проверяется условие в выражении if. Верно ли, что $ f r u i t [$k] == "яблоко"?
Текущее значение $к равно 0, и интерпретатор РНР проверяет на равенство первый
элемент массива $ f r u i t [ 0 ] . Поскольку в нем содержится значение апельсин, то
рассматриваемое условие ложно, т.е. фрагмент кода, содержащийся после if, не выполняется
и интерпретатор РНР переходит к обработке инструкции e l s e .
Глава 7. Управление ходом выполнения сценария 129
4. Выполняется фрагмент кода, содержащийся после e l s e . Он выводит первую стрску
апельсин — это не яблоко.
5. Значение переменной $к увеличивается на единицу и становится равным 1.
6. Достигается конец цикла и интерпретатор РНР переходит к его началу.
7. Снова проверяется на истинность условие $ t e s t v a r != "да". Поскольку значение переменной
$ t e s t v a r не изменилось и равно нет, условие истинно и цикл не прекращает ;я.
8. Опять проверяется условие в выражении if. Верно ли, что $fruit[$k] ==
"яблоко"? Теперь текущее значение $к равно 1 и интерпретатор РНР проверяет второй
элемент массива $ f r u i t [ l ] . Поскольку в нем содержится значение яблоко, го
рассматриваемое условие истинно, т.е. выполняется фрагмент кода, который следует за i :.
9. Выполняется фрагмент кода после оператора if. В нем переменной $ t e s t v a r присваивается
значение да и выводится вторая строка яблоко.
10. Значение переменной $к снова увеличивается на единицу и становится равным 2.
11. Достигается конец цикла, и интерпретатор РНР снова переходит к его началу.
12. Последний раз проверяется истинность условия $ t e s t v a r != "да". Поскольку
значение переменной $ t e s t v a r изменилось и стало равным да, условие ложно
и цикл завершается.
Вполне возможно создать цикл while, который будет бесконечным, т.е. будет выполняться
неограниченное количество раз. Это может произойти из-за того, что > с-
ловие всегда будет оставаться истинным, т.е. если условие никогда не станет ложны м,
цикл никогда не завершится. Более подробно этот вопрос рассматривается ниже.
Цикл do. .while
Цикл do. .while очень схож с циклом while и выполняется до тех пор, пока истинны
определенные условия. Однако в цикле do. .while условие проверяется не перед началом
каждой итерации, а после ее завершения.
Общий синтаксис цикла do. . while имеет следующий вид:
do
{
фрагмент кода;
}while ( условие );
Перепишем предыдущий пример цикла while с использованием цикла do. .while. При
этом результат выполнения будет один и тот же:
$fruit = array ("апельсин", "яблоко", "виноград");
$testvar = "нет";
$к = 0;
do
{
if ($fruit[$k] == "яблоко"))
{
$testvar = "да";
echo "яблоко\п";
}
else
{
echo "$fruit [$k] — это не яблоко\п";
<Д*Ш*
130 Часть III. Основы программирования на РНР
}
$к++;
}while ($testvar != "да"));
В результате на экране отобразятся следующие строки:
апельсин — это не яблоко
яблоко
т.е. будет получен тот же результат, что и в предыдущем примере с использованием цикла
while. Различие между циклами while и do. .while заключается во времени проверки условия.
В цикле while условие проверяется перед началом каждой итерации, т.е. если оно всегда
ложно, фрагмент кода никогда не выполнится. В цикле do. .while условие проверяется
после завершения итерации. Поэтому фрагмент кода всегда выполнится хотя бы один раз.
Изменим, например, в предыдущих двух циклах, while и do. .while, начальное значение
переменной $ t e s t v a r на да:
$testvar = "да";
В первом из них сначала проверяется условие, которое всегда ложно. Следовательно,
цикл while никогда не будет выполнен. Во втором цикле do. .while итерация выполнится
хотя бы один раз, и будет выведена одна строка:
апельсин — это не яблоко
Таким образом, в результате выполнения цикла do. .while перед проверкой условия
будет выведена одна строка. Поскольку оно всегда ложно, последующие действия выполняться
не будут.
Избегайте бесконечных циклов
Нетрудно создать цикл, который будет выполнятся неограниченное количество раз. Такие
циклы называются бесконечными (infinite loop). Однако вряд ли кто-то создает их намеренно.
Чаще всего — это ошибка в написании кода. Например, небольшое изменение фрагмента кода
в примере с циклом while может привести к бесконечному циклу.
Модифицируем код сценария, который использовался ранее в этой главе:
$fruit = array("апельсин", "яблоко", "виноград");
$testvar = "нет";
while ( $testvar != "да" )
{
$k = 0;
if ($fruit[$k] == "яблоко" )
{
$testvar = "да";
echo "яблоко\п";
}
else
{
echo "$fruit[$k] — это не яблоко\п";
}
$k++;
}
Небольшое изменение касается выражения $к = 0;, которое было внесено в цикл
while извне. Эта модификация делает цикл бесконечным. В результате получим:
апельсин — это не яблоко
апельсин — это не яблоко
апельсин — это не яблоко
апельсин — это не яблоко
Глава 7. Управление ходом выполнения сценария 131
и так до бесконечности. При каждой новой итерации переменной $к присваивается значе те
О (несмотря на инкремент в конце цикла), и каждый раз проверяется первый элемент масс *ва
$ f r u i t [ 0 ] , содержащий значение апельсин, т.е. второй элемент массива (со значением
яблоко) никогда не будет обработан, и значение переменной $ t e s t v a r никогда не ста1ет
равным да. Таким образом, в результате получим бесконечный цикл.
Не смущайтесь, если напишете бесконечный цикл. Даже самые известные программю ты
в мире создавали их в большом количестве. Если при тестировании сценария вы обнаружили,
что некоторое действие повторяется бесконечно, не делайте из этого трагедию, а выполните
одно из следующих действий.
•S При использовании РНР для создания Web-страниц. Подождите, пока
сценарий сам не остановится через короткое время. По умолчанию оно pai но
30 секундам, но может быть изменено администратором. Или щелкните на
кнопке Стоп (Stop) в браузере, чтобы остановить выполнение сценария.
•S При использовании PHP CLI. Нажмите комбинацию клавиш <Ctrl+C>. GTO
поможет остановить выполнение сценария. Хотя некоторое время он еще может
поработать, но остановится обязательно.
Затем найдите строку кода, генерирующую бесконечный цикл, и исправьте ее.
Наиболее типичной ошибкой при написании циклов является использование при
проверке условий одного знака равенства (=) вместо двух (==). Один знак равенства
предназначен для присваивания значений переменным, а два знака— дня
проверки условий. Соответственно следующее выражение всегда истинно:
while ($testvar = "да")
В нем переменной $ t e s t v a r присваивается значение да. Это выражение никогда ie
станет ложным. Здесь, наверное, подразумевалось следующее:
while ($testvar == "да")
В отличие от предыдущего выражения здесь значение переменной $ t e s t v a r сравнивается
на равенство со значением да. При этом может быть получена как истина, так и ложь.
Еще одной ошибкой является отсутствие выражения, которое изменяет значение перг-
менной-счетчика. Например, если в предыдущем примере кода удалить инкремент счетчюи
$к++;, то значение переменной $к будет неизменным и равным 0 и в результате получится
бесконечный цикл.
Прерывание циклов
Иногда необходимо прервать выполнение цикла. В языке РНР это можно сделать дву\я
способами.
Оператор break полностью прерывает выполнение цикла.
Оператор continue прерывает выполнение текущей итерации и переходит
к следующей, если соответствующее условие выполнено.
Операторы break и continue обычно применяются в условных операторах. В частне-
сти, инструкция break чаще всего используется в конструкции switch. В следующих примерах
показано различие в использовании операторов break и continue.
Приведем пример использования оператора break:
$counter = 0;
while ( $counter <5 )
•"
V
132 Часть III. Основы программирования на РНР
$counter++;
if ( $counter ==3,)
{
echo "break\n";
break;
}
echo "Последняя строка цикла: счетчик=$соипЪег\п";
}
echo "Первая строка после цикла\п\п";
Получим следующий результат:
Последняя строка цикла: счетчик=1
Последняя строка цикла: счетчик=2
break
Первая строка после цикла
Следует заметить, что цикл останавливается сразу по достижения строки, содержащей
оператор break, и переходит к выполнению команд после цикла while. Оператор
continue действует по-другому.
Ниже приведен пример использования оператора continue.
$counter • 0;
while ( $counter <5 )
{
$counter++;
if ($counter == 3 )
{
echo "continue\n";
continue;
} echo "Последняя строка цикла: счетчик=$соипЬег\п";
}
echo "Первая строка после цикла\п";
Получим следующий результат.
Последняя строка цикла: счетчик=1
Последняя строка цикла: счетчик=2
continue
Последняя строка цикла: счетчик=4
Последняя строка цикла: счетчик=5
Первая строка после цикла
В отличие от примера с использованием оператора break при достижении оператора
continue цикл не завершается. Просто выполнение третьей итерации прерывается и происходит
переход к следующей. Цикл завершается тогда, когда условие становится ложным
(т.е. когда значение переменной $counter станет больше 5).
Оператор break также часто используется для предотвращения бесконечных циклов.
Следующее выражение внутри цикла сможет предотвратить неограниченное количество
повторений:
$test4infinity++;
if ($test4infinity >100 )
{
break;
}
Если известно, что цикл не должен повторяться больше 100 раз, приведенный фрагмент
кода поможет избежать создания бесконечного цикла.
Глава 7. Управление ходом выполнения сценария 133
Глава 8
Повторное использование кода
в сценариях РНР
3 э/Яой главе...
> Включение файлов в сценарии
> Вопросы безопасности, связанные с включением файлов
> Создание функций
> Использование функций
^ ачастую одни и те же действия необходимо выполнить в разных частях сценария. Н а-
KS пример, нужно несколько раз получить информацию из базы данных. Или можно
представить себе ситуацию, когда один и тот же код используется в разных файлах. Если
окажется, что время от времени вы набираете одни и те же десять строк кода (постоянно выделяя
и копируя их), то лучше поместить их в отдельный файл и использовать, когда того п з-
требует ситуация. Можно выделить следующие преимущества такого подхода.
» Меньше работы — это всегда стимулирует.
S Отладка осуществляется один раз. Можно написать код один раз, проворить
его работоспособность, а затем использовать столько, сколько потребуется.
Редко удается сразу переписать код без каких-либо опечаток, не говор я
уже о том, чтобы написать новый. Его всегда нужно проверять. Поэтому использование
готового проверенного кода позволяет сэкономить много времени
*/ Простота понимания. Чем меньше кода, тем более простым и читаемым яи-
ляется сценарий. Например, одну строку кода, содержащую функцию get -
Data (), проще понять, чем, скажем, десять срок, которые реально используются
для получения данных.
Простота поддержки. Если необходимо внести какие-то изменения в сценарий,
то при повторном использовании кода их нужно будет внести всего оди \
раз во внешнем файле. В противном случае пришлось бы искать нужны!
фрагмент кода везде, где он используется, и изменять его соответствующим
образом. Например, если поменяется имя базы данных, то куда практичней
будет внести изменения один раз в одном файле, чем во всех частях, где используется
ее имя.
В языке РНР существуют два варианта повторного использования кода: с помощью вклю •
чения файла в сценарий или путем использования функций. В данной главе будут рассмотре •
ны оба этих подхода.
• /
включение косца в сценарий
Можно создать отдельный файл, состоящий из нужного количества строк кода, и включить его
в исходный сценарий там, где это нужно. Для этого в РНР предназначена функция include.
Включение файлов
Предположим, что вы создаете интерактивный каталог товаров и что ваше приложение
содержит большое количество страниц, отражающих его содержимое. Размеры изображений
(ширина и высота) можно задать как константы, а затем использовать их в дескрипторах
HTML для вывода изображений. Таким образом, все картинки будут одинакового размера.
Впоследствии можно изменять размеры изображений путем простой замены значений констант.
При этом отпадает необходимость вносить изменения в каждый дескриптор <img>
сценария. Создать константы можно следующим образом:
define("HEIGHT", 60);
define("WIDTH", 60);
Затем их можно использовать в HTML-дескрипторах:
<img src="mypic.jpg" height="<?php echo HEIGHT?>"
width="<?php echo WIDTH?>" />;
Если изображения товаров выводятся в разных файлах сценария, нет необходимости
в каждом из них размещать определения констант. Константы можно объявить в одном файле,
например s i z e , inc (это расширение обычно используется для файлов включения), а затем
включать его в сценарий там, где это будет нужно:
<?php
define("HEIGHT", 60);
define("WIDTH", 60);
?>
Теперь для включения файла следует воспользоваться выражением
i n c l u d e ( " s i z e . i n c " ) ;
При обработке этого фрагмента кода интерпретатор РНР считывает команды данного файла
и вставляет его в исходный файл вместо инструкции include, т.е. HTML-дескрипторы, содержащие
константы HEIGHT и WIDTH, будут отображаться следующим образом:
<img src="mypic.jpg" height="60" width="60" />
Таким образом, на Web-странице будет выведена картинка. Если необходимо автоматически
изменить размеры всех изображений, следует один раз поменять значения констант HEIGHT
и WIDTH. Поскольку дескриптор <img> является достаточно сложным и содержит большой набор
параметров, его можно поместить в отдельный файл, скажем displayPix. inc, и включать при
выводе изображений. При этом сам <1тд>-дескриптор можно поместить в файл displayPix. inc,
константы — в файл s i z e . i n c , а затем оба файла включить в результирующий сценарий
либо включить файл s i z e , inc в d i s p l a y P i x . inc, а затем использовать только
d i s p l a y P i x . i n c .
Зачастую разработчики забывают использовать дескрипторы РНР. Это одна из
наиболее частых ошибок, которая связана с вопросом безопасности, поскольку
без PHP-дескрипторов содержимое страницы будет без обработки выведено на
экран. Безусловно, если пользователь знает размеры изображений, это не создаст
проблем. Но, если в файле будет содержаться, например, пароль для доступа
к базе данных, это может иметь нежелательные последствия.
Глава 8. Повторное использование кода в сценариях РНР 135
Вместо функции include () можно использовать выражение
include_once("имя_файла") ;
Эта функция позволяет избежать повторного переопределения одинаковых переменных,
содержащихся во включаемых файлах. Например, функцию include_once () можно использовать
для включения определения функций (этот вопрос рассматривается далее в этой
главе) с тем, чтобы они не повторялись.
В языке РНР имеются также функции r e q u i r e () и require_once (), которые
подобны include (), но отличаются способом обработки ошибок. Это различие
проявляется, например, при обращении к файлу, которого не существует. В этэм
случае функция r e q u i r e () выдаст ошибку и сценарий остановится. При использовании
include () будет выведено только сообщение об ошибке, но сценарий
продолжит выполняться.
В качестве имен файлов также можно использовать значения переменных:
include("$filename");
Например, необходимо вывести различные сообщения в зависимости от дня недели. Пэи
этом сообщения находятся в файлах, имена которых соответствуют различным дням. Например,
файл с именем Sun. i n c может содержать следующее:
echo "Думайте о будущем. Отсыпайтесь. Сегодня - никакой работы.";
И другие файлы в том же духе. Следующий фрагмент кода позволяет корректно вывес ги
нужное сообщение в зависимости от дня недели:
$today = dateC'D") ;
include("$today"."inc") ;
В результате выполнения функции d a t e () (см. главу 5) переменной $ today будет присвоено
сокращенное название дня недели. Вторая строка позволяет подключить необходимый
файл. Например, если $today равно Sun (воскресенье), то будет выведено сообщение,
содержащееся в файле Sun. inc.
Размещение файлов включения
Размещение файлов включения при разработке Web-страниц является важным вопросом, ос >
бенно с точки зрения обеспечения безопасности. Если файл никоим образом не защищен, его см з-
жет загрузить любой пользователь. Теоретически это можно сделать, используя следующий адрес:
http://yourdomain.com/secretpasswords.inc
Предположим, что в Web-окружении имеется файл secretpassword. inc, который содержит
следующую информацию:
<?php
$mysecretaccount="account487 56";
$mypassword="secret" ;
?>
В большинстве случаев Web-серверы не настроены на обработку PHP-кода в файлах с
расширениями, отличными от .рнр, т.е. интерпретатор РНР не обрабатывает файл s e cretpassword.
inc, и его содержимое будет отображено пользователю как HTML-код.
что явно не желательно. Для защиты от подобных случаев можно предпринять одно из
следующих действий.
S Переименовать файл включения с расширением .php. В таком случае
Web-сервер будет обрабатывать файл включения так же, как и обычный сценарий
РНР. Но тогда следует хорошенько подумать о его содержимом. Делэ
136 Часть III. Основы программирования на РНС-
в том, что независимая обработка отдельных файлов включения крайне нежелательна.
Предположим, например, что файл включения предназначен для
удаления записи в базе данных (что, правда, маловероятно). Тогда независимая
обработка такого файла (отдельно от файла сценария) может иметь негативные
последствия. Еще одним фактором является то, что расширение файла
. i n c явно указывает, что он вспомогательный и предназначен для включения,
а не для отдельной обработки.
S Настроить Web-сервер на обработку кода РНР не только в файлах с расширением
.php, но и в других файлах, например с расширением .inc.
Этот подход позволит отличить файлы по их функциональному назначению.
Однако все равно остается проблема, связанная с независимой обработкой
файлов включения.
S Разместить файл в месте, недоступном извне. Это решение является наиболее
предпочтительным. Хотя оно не всегда реализуемо, например при использовании
услуга Web-хостинговой компании.
Наилучшим вариантом является размещение файлов в каталогах, недоступных извне.
Другими словами, необходимо создать каталоги для файлов включения, к которым невозможно
будет получить доступ из Web-окружения. Например, Web-сервер Apache по умолчанию
сохраняет файлы для Web в каталоге apache / h t d o c s (хотя этот путь можно изменить
в конфигурационном файле h t t p d . conf). Поэтому для защиты файлов включения от внешнего
доступа их можно разместить, например, в каталоге d: \ include.
Установка путей для файлов включения
Модуль РНР позволяет задать специальные пути, которые будут использоваться для загрузки
файлов включения. Если вы являетесь администратором этого модуля, это можно
очень просто сделать в файле конфигурации php. i n i (этот файл размещается в системном
каталоге, как описано в приложении А). Для этого необходимо найти строку, содержащую
директиву include_path, и изменить указанное в ней значение. Если в начале этой строки
находится точка с запятой, ее необходимо удалить. Рассмотрим следующие примеры:
include path=".;d:\ i n c l u d e " ; # для Windows
i n c l u d e _ p a t h = " . : / u s e r / l o c a l / i n c l u d e " ; # для Unix/Linux/Mac
Обе эти строки определяют каталоги, в которых интерпретатор РНР будет искать файлы
включения. Первое значение (символ точки) соответствует текущему каталогу, за которым
следует имя второго каталога. РНР позволяет определить столько каталогов, сколько требуется.
При этом порядок проверки каталогов на наличие файлов включения соответствует порядку
значений, указанному в директиве include_path. Разделителем этих значений для
операционных систем Windows является точка с запятой и двоеточие — для Unix/Linux.
Если же вы не имеете доступа к конфигурационному файлу php. i n i , этот путь можно
установить отдельно для каждого сценария следующим образом:
ini_set("include_path", "d:\hidden");
Это выражение присваивает переменной include_path определенное значение только
на время выполнения сценария. Оно не устанавливает его для всего Web-окружения.
Для доступа к файлу включения по установленному пути необходимо использовать его
имя. При этом полный путь указывать не обязательно:
include("secretpasswords.inc");
Глава 8. Повторное использование кода в сценариях РНР 137
Если необходимый файл не содержится по адресу, указанному в директиве include_pcith
или в том же каталоге, что и сам сценарий (например, в подкаталоге или каталоге, скрьгом
от Web-окружения), следует указать полный путь:
include ("d: /hidden/secretpasswords . inc") ;
В остальных случаях будет достаточно одного имени файла.
Создание пов^о/гно используемого кода
(функции)
Приложения обычно выполняют одни и те же действия в разных частях сценария. И здесь
приходят на помощь функции. Функция (function) представляет собой набор инструкций,
предназначенных для выполнения определенных действий.
Предположим, например, что к каждой Web-странице необходимо добавить следующую
информацию:
echo '<img src="greenrule.jpg" width="100%" height="7" />
<address>Mofl компания
<br />ул. Прекрасная 1234
<br />Сан Диего, СА 92126
< / a d d r e s s x / f o n t>
<р>или обращайтесь в
<а Ьге?="таИЬо:за1ез@сотрапу.сот">отдел продаж </а>
<img src="greenrule.jpg" width="100%" height="7" / > ';
Обычно в начало или в конец Web-страницы добавляют куда больше информации. Поэтому
гораздо эффективнее создать функцию, например с именем add_f o o t e r (), чем каждый
раз писать один и тот же код в конце страниц. Затем нужно добавить в код сценария имя
функции (т.е. вызвать ее), которая выведет нужную информацию:
add_footer()
Обратите внимание на наличие скобок после имени функции. Они являются
обязательными и указывают интерпретатору РНР на то, что выполняется вызов
функции.
Определение функций
Для создания функции необходимо наполнить тело функции (т.е. определить набор команд,
которые она должна выполнять). Общий синтаксис функции имеет вид
function иия_функции()
{
набор команд;
return;
}
Рассмотрим, например, функцию, которая добавляет специальную информацию в конец
Web-страницы (она уже упоминалась в предыдущем разделе):
function add_footer()
{
echo '<img src="greenrule.jpg" width="100%" height="7" />
<address>MoH компания
<br />ул. Прекрасная 1234
138 Часть III. Основы программирования на PHf
<br />Сан Диего, СА 92126
</addressx/font>
<р>или обращайтесь в
<а href="mailto:sales@company.com">отдел продаж </а>
<img src="greenrule.jpg" width="100%" height="7" />';
return;
}
Оператор r e t u r n останавливает выполнение тела функции и передает управление основному
коду сценария. (Инструкция r e t u r n не является обязательной в конце тела функции,
но ее использование позволяет легче объяснить принципы ее работы. Более подробно оператор
r e t u r n рассматривается ниже.)
Функции можно определять в любом месте сценария, но обычно их помещают либо в начало,
либо в конец сценария. Функции, которые предполагается использовать в нескольких
сценариях, следует размещать в отдельном файле и включать его там, где это необходимо.
Наверное, к этому моменту вы задались следующим вопросом: "Почему бы мне просто не
поместить информацию, которую необходимо выводить в конце каждой Web-страницы, в отдельный
файл, скажем f o o t e r . inc, и включать его в сценарии?" Хороший вопрос! В принципе
так можно поступить. И в данном случае следовало бы. Дело в том, что выражения, используемые
для создания необходимой информации, представляют собой набор простых
команд, которые выводят HTML-код. Его можно поместить в отдельный файл и включать
в конце каждой страницы. Для этого даже не понадобится использовать дескрипторы РНР.
Однако, предположим, что компания, для которой создается Web-узел, состоит из трех подразделений.
И в информации, которая выводится внизу каждой страницы, необходимо также
указать название подразделения и адрес электронной почты для переписки. Для этого можно
было бы создать три различных файла включения'и каждый раз использовать требуемый. Однако
в данном случае решение на основе функций представляется более гибким и быстрым.
Функции можно указать (т.е. передать ей значение (passing value)), информацию о каком
подразделении требуется вывести. Например:
function add_footer($division)
{
echo '<img src="greenrule.jpg" width="100%" height="7" />
<p>'.$division. '</p>
<address>Moa компания
<br />ул. Прекрасная 1234
<br />Сан Диего, СА 92126
</addressx/font>
<р>или обращайтесь в
<а href="mailto:'.$division.'©company.com">' .$division.'</a>
<img src="greenrule.jpg" width="100%" height="7" / > ';
r e t u r n ;
}
В этом случае функция считывает значение параметра, которое содержится в параметре
$division. Далее оно используется в теле функции для вывода нужной информации. При
использовании функции add_f o o t e r () в качестве входного аргумента ей необходимо передать
некоторое значение:
add_footer("Отдел продаж");
Для изменения информации о подразделении необходимо передать другой входной параметр:
add_footer("Бухгалтерия");
Глава 8. Повторное использование кода в сценариях РНР 139
Обратите внимание на синтаксис функции echo. Строка заключена в одинарьые
кавычки. В предыдущем примере, без переменных, одинарные кавычки использовались
только в начале и в конце выводимой строки. В данном случае, при испо :ь-
зовании переменной, строка заканчивается одинарной кавычкой перед перемен!: ой
$division и снова открывается после. Запомните, что значение переменкой
в строке с одинарными кавычками не выводится. Если $ d i v i s i o n поместить в такую
строку, то вместо строки Отдел продаж будет выведен текст $division.
Результатом выполнения функции также может быть некое возвращаемое значение
(returning value). Для этого используется оператор r e t u r n . Предположим, что в результате
выполнения функции add_f ooter () информацию необходимо сохранить в перемени ж
и не выводить на экран. Это можно осуществить следующим образом:
function add_footer($division)
{
$str='<img src="greenrule.jpg" width="100%" height="7" />
<p>'.$division. '</p>
<address>MoH компания
<br />ул. Прекрасная 1234
<br />Сан Диего, СА 92126
</address></font>
<р>или обращайтесь в
<а href="mailto:'.$division.'(Jcompany.com">1 .$division.'</a>
<img src="greenrule.jpg" width="100%" height="7" / > ';
r e t u r n $str;
}
И воспользоваться таким выражением:
$footer = add_footer("Отдел продаж");
echo $footer;
При выводе переменной $ f o o t e r отобразится вся информация, сгенерированная в функции
add_footer().
Далее в этой главе подробно рассматриваются вопросы, связанные с созданием и исгош -
зованием функций. Они позволяют быстро разработать выполняемый сценарий, который ли -
ко отлаживать и поддерживать. Именно поэтому высококлассные программисты всегда стг -
раются использовать функции.
Использование переменных в функциях
В функциях можно создавать и использовать переменные, которые называются локальными
(local). Эти переменные могут быть доступны только в теле функции. (Для того чтобы переменная
была доступна извне, ее необходимо объявить глобальной (global), используя ключе •
вое слово global.) Рассмотрим пример создания локальной переменной внутри функции:
function format_name($first_name, $last_name)
{
$name = $last_name. ", ".$first_name;
}
Функцию f ormat_name () можно вызвать, передав ей соответствующие значения, и попытаться
вывести переменную $name:
format_name("Джесс", "Джонс");
echo "$name";
Однако в результате ничего выведено не будет, поскольку в переменной $name не содержится
никакого значения. Эта переменная была создана внутри функции и не доступна из основного
кода сценария.
140 Часть III. Основы программирования на РНР
Для того чтобы изменить эту ситуацию, необходимо объявить переменную глобальной.
Рассмотрим измененный вариант предыдущего сценария:
function format_name($first_name, $last_name)
{
global $name;
$name = $last_name. ",".$first_name;
}
Теперь переменную $name можно использовать вне тела функции и вывести ее значение:
format_name("Джесс", "Джонс");
echo "$name";
В результате отобразится следующая информация:
Джонс, Джесс
Переменную обязательно необходимо объявить глобальной перед тем, как выполнять
с ней какие-либо действия. Например, если бы ключевое слово global
следовало после присваивания значения переменной $name, на экране ничего не
отобразилось бы, т.е. функция и сценарий работали бы не корректно.
Аналогичным образом, если переменная объявлена вне тела функции, а затем переменная
с тем же именем объявлена внутри функции, то внешняя переменная будет доступна внутри
функции только в том случае, если в функции она объявлена глобальной. Для примера рассмотрим
следующий фрагмент кода:
$first_name = "Джесс";
$last_name = "Джонс";
function format_name()
{
global $first_name, $last_name;
$name = $last_name. ", ",$first_name;
echo "$name";
}
format_name();
Если при объявлении переменных $last_name и $? irst_name в теле функции не использовать
ключевое слово global, созданные локальные переменные будут отличаться от
глобальных. В таком случае они не будут иметь значений, и в результате вывода переменной
$name получим запятую (,).
Для корректной работы функции format_name() необходимо использовать ключевое
слово global.
Передача значений в функцию
Для передачи значений в функцию их необходимо заключить в скобки после имени функции:
имя_функции(значение!, значение2, . . . );
Безусловно, переменные просто так ниоткуда не возьмутся, и их нужно предварительно
задать. Это делается при определении функции с помощью ключевого слова function:
function имя_функции(значение1, значение2, ...)
{
набор команд;
return;
}
Передача значений корректного типа
При передаче значений в качестве аргументов можно использовать переменные любого
типа, включая массивы или объекты (объекты рассматриваются в главе 9).
Глава 8. Повторное использование кода в сценариях РНР 141
f/ ^
Следующее выражение вызывает функцию s a l e s t a x f ) , которая вычисляет налог на
продажу. Для этого необходимо знать сумму покупки и название штата (поскольку в pa3f ых
штатах установлены разные ставки), чтобы корректно определить сумму налога, т.е. функции
s a l e s t a x t ) нужно передать два аргумента: числового (сумма покупки) и строкового
(название штата) типов. Рассмотрим некоторые примеры.
•/ compute_salestax(2000, "CA") ; Этой функции переданы два значения:
2000 и СА (штат Калифорния).
•S сотри t e _ s a l e s t ах (2*1000, "") ; ЭТОЙ функции переданы два 3Haie-
ния: 2000 и "" (пустая строка). Функция должна уметь обрабатывать различные
варианты входных данных, в том числе и пустую строку.
S compute_salestax(2000, "С". "А") ; Этой функции передано два значения:
2000 и "С". "А", что соответствует СА.
В качестве аргументов функции также можно передавать массивы. (Подробно о массивах
см. главу 6.) Рассмотрим следующий пример:
function add_numbers($numbers)
{
for($i=0;$i <sizeof($numbers);$i++)
{
@$sum = $sum + $numbers[$i];
r}e turn $sum;
}
Эта функция позволяет вычислить сумму элементов массива. Если же переданная переменная
не является массивом, интерпретатор РНР преобразует ее к нужному типу: числу ю и
строке. Однако при выполнении функции sizeof ($numbers) произойдет ошибка, поскольку
в качестве входного параметра она использует массив. Поэтому хорошо написаншл
функция должна проверять переданную ей информацию. Например, в предыдущее выражение
перед циклом f o r можно добавить следующее:
if(!is_array($numbers)
{
echo "Переданная переменная не является массивом";
e x i t ( ) ;
}
Точно так же эта функция должна проверить, что элементы массива являются числами,
используя функции, описанные в главе 5.
Рассмотрим пример использования созданной функции add_number ():
$arrayofnumbers = array(100,200);
$total = add_numbers($arrayofnumbers);
В результате переменная $ t o t a l станет равной 300.
Передача значений в корректном порядке
Функция получает значения в том порядке, в котором они ей передаются. Рассмотрим
следующий пример:
function functionx($x, $y, $z)
{
выполнение некоторых действий
>
Осуществим вызов этой функции:
functionx($varl, $var2, $var3);
При этом происходит следующее: переменной $х присваивается переданное значение
$varl; переменной $у — значение $var2 и переменной $z — $var3.
142 Часть III. Основы программирования на РНР
Если при вызове функции порядок переданных аргументов не соответствует тому, который
использовался при определении, — возникает ошибка. Рассмотрим, например, определение
функции, которая вычисляет налог на продажу:
function compute_salestax($orderCost, $custstate)
{
вычисление налога
)
Предположим, осуществляется ее вызов:
compute_salestax($custState, $orderCost);
В этом случае переданное название штата используется в качестве суммы покупки, и интерпретатор
РНР присваивает этой переменной нулевое значение (преобразует строку в число).
То же происходит и с переменной, соответствующей сумме покупки. В результате будет
получено значение 0.
Передача корректного количества переменных
При вызове функции ей необходимо передать определенное количество переменных. Если
одна из них пропущена, ей присваивается значение NULL. Если интерпретатор РНР настроен
на обработку ошибок, то будет выведено соответствующее сообщение. (Об уровнях ошибок
см. в главе 4.) Рассмотрим следующий пример вывода сообщения об ошибке:
Warning: Missing argument 2 for format_name() in testing.php on l i n e 9
(Предупреждение: Отсутствует аргумент 2 функции format_name() в файле
testing.php в строке 9)
Помните, что предупреждения (warning) не останавливают выполнение сценария. Предположим
теперь, что осуществляется вызов функции f ormat_name (), рассмотренной
в разделе "Использование переменных в функциях" выше в этой главе:
format_name("Джесс") ;
В результате получим:
Джесс,
Если функции передать слишком много аргументов, лишние из них будут проигнорированы.
Однако такая ситуация возникает редко.
Переменным, значения которых передаются в функцию, можно присвоить значения по
умолчанию (т.е. если аргумент не передан, используется значение по умолчанию). Они присваиваются
при определении функции:
function add_2_numbers($numl=l, $num2=l)
{
$ t o t a l = $numl + $num2;
r e t u r n $ t o t a l;
}
Однако если при вызове функции указано значение параметра, то именно оно используется
вместо значения по умолчанию. Рассмотрим различные примеры вызова функции
add_2_number():
add_2_numbers(2, 2) ;
add_2„numbers(2) ;
add_2„numbers();
Будут получены следующие результаты:
$total = 4
$total = 3
$total = 2
Глава 8. Повторное использование кода в сценариях РНР 143
Первый результат ($total=4) получен путем сложения двух переданных значений, равных
2. Второй ($total=3) — путем сложения числа 2 и значения по умолчанию 1, испогь-
зуемого для переменной $пшп2. Третий ($total=2)— путем сложения двух значений, ю
умолчанию равных 1, используемых для $numl и $num2.
Передача значений по ссылке
Если при определении функции используется передача значений, то такой подход называется
передачей аргументов по значению. Такой подход применяется чаще всего, как, напр »-
мер, в следующем выражении:
function add_l($numl)
{
$numl = $numl + 1;
}
При передаче аргументов по значению переданное значение копируется в локальную переменную,
которая и используется в теле функции. В данном случае таковой является $num:.,
к которой прибавляется 1. Однако значение переменной вне функции (т.е. переменной, которая
используется при вызове) не изменяется. Рассмотрим следующий пример:
$orig_num = 3;
add_l($orig_num);
echo $orig_num;
В результате вывода получим 3. При вызове функции add_l() значение переменно*
$orig_num будет скопировано в переменную $numl. При этом никакие действия на!
$orig_num осуществляться не будут. Для того чтобы изменить ее значение, необходимо добавить
в определение функции следующее выражение:
r e t u r n $numl;
Переменной $orig_num можно присвоить результат выполнения функции add_l ():
$orig_num • 3;
$orig_num = add_l($orig_num);
echo $orig_num;
Теперь результатом вывода будет 4.
Однако в некоторых случаях необходимо изменить значение переменной напрямую
Предположим, в предыдущем примере к переменной $orig_name нужно прибавить 1 бе:
создания локальной копии. В этом простом примере, безусловно, можно воспользоватьс*
глобальной переменной, но это также можно осуществить, используя передачу по ссылки
(passing by reference). Для этого при определении функции необходимо добавить знак амперсанта
(&) перед именем переменной:
function add_l(&$numl)
{
$numl = $numl + 1;
}
При вызове этой функции в качестве аргумента передается не значение, а адрес, по которому
хранится переменная (т.е. указатель контейнера с именем $orig_num, где содержится
значение 3). Переменная $numl становится псевдонимом $orig_num, так как если переменной
$numl присвоить некоторое значение, оно же будет присвоено и $orig_num. Эти
переменные указывают на один и тот же адрес памяти, где хранится значение. Если изменить
значение локальной переменной в теле функции, эти же изменения произойдут и с внешней
(по отношению к функции) переменной. Рассмотрим следующий пример вызова функции:
$orig_num = 3;
add_l (&$orig_num) ,-
echo $orig_num;
В результате вывода получим 4.
144 Часть III. Основы программирования на РНР
Следующее выражение, использующее передачу аргумента по ссылке, не имеет
Передача по ссылке главным образом используется для передачи больших сущностей, таких
как объекты или массивы, поскольку пи таком подходе требуется гораздо меньше памяти.
Возвращаемое значение функции
Для возвращения значения функции в языке РНР используется оператор return. Это
значение затем может обрабатываться различными способами.
Оператор r e t u r n возвращает некоторое значение и выполняет переход к основному коду
сценария. Общий синтаксис этого оператора имеет следующий вид:
r e t u r n значение;
Рассмотрим такой пример:
function add_2_numbers($numl, $num2)
{
$total = $numl + $num2;
r e t u r n $ t o t a l;
}
Эта функция возвращает сумму двух значений. Рассмотрим пример ее вызова:
$sum • add_2_numbers(5, б);
В этом примере значение локально созданной переменной $ t o t a l , равное 11, будет присвоено
переменной $sum. Фактически при определении функции можно использовать сокращенную
запись, например:
return $numl + $num2;
При этом возвращаемое значение функции можно использовать в различных выражениях.
Рассмотрим некоторые примеры:
$total_height = add_2_numbers($heightl, $height2);
$totalSize • $current_size + add_2_numbers($sizel, $size2);
if (add_2_numbers($costSocks, $costShoes) > 200.00 )
$echo "Дорого";
При этом следует заметить, что оператор r e t u r n позволяет возвращать только одно значение,
которым, однако, может быть и массив. Поэтому, в принципе, функция может возвращать
несколько значений.
Выражение r e t u r n также можно использовать в условных выражениях:
function find_value($array, $value)
{
for($i=l;$i<sizeof($array);$i++)
{
i f ( $ a r r a y [ $ i ] = $value)
{
echo "$i. $array[$i]<br>";
r e t u r n ;
}
}
}
Функция find_value() проверяет, содержит ли массив $аггау значение $value.
Рассмотрим пример вызова этой функции:
$names = array("Джо", "Сэм", "Хуан");
find_value($names, "Сэм");
Глава 8. Повторное использование кода в сценариях РНР 145
Функция ищет среди элементов массива значение Сэм. Если соответствующий элемент
найден, выводится его индекс и функция завершает свою работу:
1. Сэм
Очень часто функции возвращают булевы значения, как, например, в выражении
f u n c t i o n is_over_100($number)
{
if($number > 100)
{
r e t u r n TRUE;
}
e l s e {
r e t u r n FALSE;
}
}
Если значение переменной $number меньше или равно 100, возвращается значение
FALSE, в противном случае — TRUE.
Рассмотрим еще один пример создания функции, в котором она возвращает некоторое
значение в случае успешного выполнения и значение FALSE в противном случае:
f u n c t i o n f i n d _ v a l u e ( $ a r r a y , $value)
{
f o r ( $ i = l ; $ i < s i z e o f ( $ a r r a y ) ; $ i + + )
{
i f ( $ a r r a y [ $ i ] == $value)
{
r e t u r n $ i;
}
}
return FALSE;
}
Если нужное значение найдено в массиве, будет возвращен индекс элемента, в против ном
случае — значение FALSE.
Использование встроенных функций
В языке РНР имеется большой набор мощных и полезных встроенных функций, что я ткется
одной из причин его чрезвычайной популярности. Они используются наряду со стандартными
функциями и ничем не отличаются от пользовательских. В них воплощена раб эта,
которую разработчики РНР сделали за вас.
Специализированные встроенные функции описываются в соответствующих главах, в которых
рассказывается, чем они могут быть полезны многим разработчикам. В данном разделе они
бы выпадали из контекста. Например, в главе 7 рассматривались функции, которые использ>ют-
ся для проверки существования переменной или ее значения. Они имеют следующий вид:
isset($varname)
empty($varname)
В главе 5 описывались функции, предназначенные для форматирования и обработки числовых
и строковых выражений. И так на протяжении всей книги.
В приложении Б приведен обширный список полезных встроенных функций. При написании
сценариев лучше иметь этот список при себе, чтобы быстро найти нужную функцш.
При этом можно также создавать собственные функции, которые будут работать лучше, чем
встроенные. Безусловно, в приложении Б представлены не все функции — их тысячи. Одн IKO
там приведены наиболее полезные их них. Весь список встроенных функций можно на:1ти
в документации РНР на официальном Web-узле (www. p h p . n e t / d o c s . php).
146 Часть III. Основы программирования на РНР
OJfiadotfitca ouiurfoic
Как это ни печально, иногда функции работают некорректно. Как бы вы не старались
учесть все возможные варианты ошибок, что-то все-таки может не сработать. Например,
функция подключения к базе данных может функционировать неправильно, если база данных
в данный момент недоступна. Причем это не связано с тем, что в функции содержатся ошибки,
— так сложилась ситуация. Хорошо написанная функция должна предвидеть все возможные
ситуации и возвращать в таких случаях значение FALSE.
Сценарий должен предвидеть любые ошибки, связанные с работой функций, и соответствующим
образом обрабатывать их. Лучше вывести пользователю собственноручно созданное
сообщение, чем стандартное предупреждение, сгенерированное РНР. Для этого в РНР предусмотрена
функция d i e (). Ее общий синтаксис имеет следующий вид:
die("сообщение");
Функция d i e () позволяет прервать выполнение сценария и вывести соответствующее
сообщение. С функциями ее необходимо использовать следующим образом:
имя_функции() or die("сообщение");
Если в результате выполнения функции будет получено значение FALSE, функция d i e ()
прервет выполнение сценария и выведет сообщение.
Рассмотрим пример, в котором выполняется подключение к базе данных MySQL:
mysql_connect("host", "user", "password")
or die("База данных не доступна. Попробуйте подключиться позже.);
Необходимо помнить следующее. Если функция работает некорректно, интерпретатор
РНР сгенерирует сообщение об ошибке. Если вместо него необходимо
вывести свое сообщение, следует изменить уровень вывода ошибок или не выводить
их вообще (см. главу 4). Иначе будут выведены оба сообщения.
Функцию d i e () можно использовать с любой другой функцией. Однако ее не имеет
смысла применять в тех случаях, когда функция возвращает значение FALSE. Помните, что
d i e () полностью останавливает выполнение сценария.
Предотвратить некорректную работу функции можно, используя ее вызов в условном выражении.
К результату, полученному в предыдущем примере, можно прийти с помощью следующего
выражения:
if(!mysql_connect("host", "user", "password"))
{
echo "База данных недоступна. Попробуйте подключиться позже\п";
e x i t () ;
}
Обратите внимание на восклицательный знак перед вызовом функции mysql_connect ().
Он используется для следующего: если не удается подключиться к базе данных (т.е. будет
возвращено значение FALSE), условное выражение станет истинным (TRUE) и будет выведено
соответствующее сообщение.
При этом функция e x i t не выполняет те же действия, что и die. Помните, что любое из этих
выражений можно использовать в операторе if. Можно даже написать сценарий, который в случае
ошибки при подключении к базе данных будет отправлять письмо по электронной почте.
Глава 8. Повторное использование кода в сценариях РНР 147
Глава 9
Объектно-ориентированное
программирование на РНР
в э>ной главе...
> Что такое объектно-ориентированное программирование
> Идентификация объектов
> Создание классов
> Использование классов
И самого начала РНР рассматривался как простой язык написания сценариев. Позже, вачи-
\ ^ ная с версии 4, в нем появились объектно-ориентированные свойства. После пояшпкия
версии 5 возможности объектно-ориентированного программирования на языке РНР были существенно
расширены, а кроме того, повысилось быстродействие разрабатываемых программ. Однако
большинство из новых свойств остаются невидимыми. Эти изменения в основном касаются
ядра Zend 2, которое в РНР 5 стало гораздо эффективнее по сравнению с ядром РНР 4. Кгоме
повышения скорости обработки сценариев, в РНР 5 были добавлены новые возможности, кэто-
рые сделали этот язык программирования по-настоящему объектно-ориентированным.
/Звеаение в оЗъемйно-о^иешЯи/юванлое
программирование
Объектно-ориентированный подход к программированию предполагает использование объектов
и классов. Более подробно они рассматриваются в этой главе ниже. В настоящее время
объектно-ориентированный подход широко распространен, и многие университетские курсы по
программированию начинаются именно с его изучения. При объектно-ориентированном программировании
чаще всего используются языки программирования Java и C++.
Объектно-ориентированное программирование— это не просто использование друюго
синтаксиса, а во многом и другой подход к анализу и решению задач. Объектно-
ориентированная программа разрабатывается путем моделирования процессов в реалы ой
предметной области. Например, программист, разрабатывающий программу поддер;кки
функционирования отдела продаж некоторой компании, может рассматривать ее с точки : рения
взаимодействия покупателей, продавцов и кредитных политик, т.е. в терминах, которыми
оперируют специалисты самого отдела продаж.
В объектно-ориентированном программировании основными элементами программы являются
объекты (object). Они являются представлением реальных объектов, которые задействованы
при решении реальной проблемы. Например, если приложение относится к предметной
области продажи подержанных автомобилей, то, возможно, в качестве объектов
будут выбраны автомобили и покупатели. Если же решаемая задача связана с космосом, то
объекты будут представлять звезды и планеты.
Объектно-ориентированное программирование является новой концепцией, которая предоставляет
новую терминологию для описания рассматриваемых проблем. Понимание этой
терминологии — ключ к пониманию самого объектно-ориентированного подхода.
Объекты и классы
Основными элементами объектно-ориентированных программ являются объекты (object).
Лучше всего их представлять как физические объекты из реального мира. Например, автомобиль
является объектом с набором свойств (или атрибутов), таких как цвет, название модели,
двигатель и тип шин. Кроме того, автомобиль может также выполнять некоторые действия,
например перемещаться вперед и назад, парковаться, поворачивать и останавливаться.
В общем случае объекты соответствуют именам существительным. Человек является объектом,
так же как и животные, дома, офисы, покупатели, мусорные баки, пальто, облака, планеты
и кнопки. Однако объекты — это не просто физические объекты. Как и имена существительные,
зачастую объекты являются более концептуальными. Например, банковский счет
невозможно подержать в руках, но он тем не менее является объектом. То же самое можно
сказать и про компьютерную учетную запись, залог, файл, базу данных, заказы, сообщения
электронной почты, адреса, песни, телевизионные шоу, встречи, даты и т.д.
В свою очередь, класс (class) является шаблоном (каркасом), который можно использовать
для создания объектов. Класс определяет свойства и атрибуты объекта, а также действия, которые
он может выполнять. Например, рассмотрим класс, определяющий четырехколесный автомобиль
с двигателем, который может перемещаться вперед и парковаться. На его основе можно
создать новый объект (новый автомобиль). Однако в процессе использования этого объекта можно
обнаружить отсутствие некоторых важных деталей, таких как дверь, руль или задняя передача. Это
может произойти из-за того, что эти компоненты при создании класса не были учтены.
Разработчик, занимающийся созданием класса, знает все о его внутреннем устройстве.
Однако для тех, кто будет использовать этот класс, подобная информация вовсе необязательна.
Например, необязательно знать, как функционирует телефон, — позвонить можно и без
этой информации. Специалисту, сконструировавшему телефон, известно о его внутренней
архитектуре. Поэтому при появлении новых технологий он сможет вскрыть телефонный аппарат
и усовершенствовать его. Вместе с тем, до тех пор, пока не изменится внешний интерфейс
(клавишная панель и кнопки) телефона, на его использование ничто не повлияет.
Свойства
Объекты имеют свойства (property), также называемые атрибутами (attribute). Автомобиль
может быть красным, зеленым или быть покрашенным в горошек. Такие свойства автомобиля,
как цвет, размер или модель, являются внутренними характеристиками объекта. Обычно свойства
класса задаются в виде переменных. Например, атрибут цвета может храниться в объекте
в виде переменной с отличительным именем, например $color. Тогда в объекте "автомобиль"
может содержаться переменная $color со значением красный ($color = красный).
Значения переменных, являющихся свойствами объектов, могут присваиваться по умолчанию
или явно во время создания объектов. Они могут добавляться и изменяться и позже.
Например, первоначально автомобиль может быть красным, а затем стать бледно-зеленым.
Методы
Действия, которые могут выполнять объекты, иногда рассматриваются как его обязанности
(responsibility). Например, объект "автомобиль" может перемещаться вперед и назад, останавливаться
и парковаться. Каждое действие (обязанность), которое объект может выполнять,
реализуется в классе в виде метода (method).
Глава 9. Объектно-ориентированное программирование на РНР 149
В языке PHP метод имеет тот же синтаксис, что и функция. Разница заключается в том,
что методы находятся внутри класса. Они не могут быть вызваны независимо от класса —
интерпретатор РНР не позволит сделать это. Функции такого вида могут использоваться
только в контексте объекта.
Как правило, при создании методов им присваивают имена, соответствующие выпошяе-
мым действиям, например parkCar () или getColor (). Методы могут иметь любые допустимые
имена, однако в соответствии с общепринятыми соглашениями в их имена к используются
прописные символы.
Методы представляют собой интерфейс между объектом и остальным миром. Кажцому
действию (обязанности) объекта должен соответствовать свой метод. С объектом можно
взаимодействовать лишь через его интерфейс. Например, если ваш сосед хочет одолжить
у вас немного сахара, ему следует сначала постучать в вашу дверь и попросить об этой ; ^слуге.
Вряд ли вы будете довольны, если сосед залезет в вашу кухню через окно и возьмет его
сам. Чтобы этого не случилось, ваш дом (house) (как объект) должен иметь входную лверь
(front door). И только через нее сосед (neighbor) будет иметь возможность попасть
в дом. Другими словами, в объекте house должен содержаться метод открытьВходнуюДиерь
(openFrontDoor), который и необходимо использовать соседу. При этом другие вари»нты
проникновения в дом должны отсутствовать. Открытие входной двери front cloor
(действие объекта house) должно осуществляться с помощью метода openDoor (). При
создании объектов не оставляйте в них "открытых окон".
Хорошо спроектированный объект должен содержать все необходимое для выполнения
своих обязанностей, но при этом не иметь ничего лишнего. Он не должен выпол 1ять
обязанности других объектов. Например, объект "автомобиль" должен "уметь" пер вмещаться
и иметь все компоненты, необходимые для выполнения своих обязанностей, например
бензин, масло, шины, двигатель и т.д. Он не должен иметь соль и сковородку,
а также "уметь" готовить пищу. В свою очередь, объект для приготовления пищи не
должен обучать детей игре в футбол.
Наследование
Объекты должны содержать только необходимые свойства и методы. Одним из подходов
для разделения свойств и методов между классами является наследование (inheritance). П>сть,
например, имеются два объекта, один из которых соответствует розам белого цвета, а другой—
красного. Можно создать два класса: redRose (красная роза) и whiteRose (61 мая
роза). Однако большая часть информации будет одинаковой для обоих классов, поскольку
оба вида роз относятся к кустарникам, имеют колючки и цветут в июне. Наследование по ieo-
ляет избежать дублирования информации.
Сначала можно создать один класс Rose. Он может содержать общую информацию для
роз, такую как $plant = bush (вид растения — кустарник), $stem = thorns (стебел.—
с колючками), $blooms = June (цветет в июне). Затем можно создать два подкласса для
соответствующих видов роз. Тогда класс Rose будет являться главным классом (master chss),
win родительским классом (parent class). В свою очередь, классы redRose и whiteRose называются
подклассами (subclass), или наследниками (child class), или потомками (child), как
их ласково называет мой любимый профессор.
Классы-потомки наследуют все атрибуты и методы родительского класса. Однако они могут
иметь и свои собственные свойства, например белый цвет ($color = белый) для класса
whiteRose и красный цвет ($color = красный) — для класса redRose.
Методы, содержащиеся в классе-наследнике, могут иметь те же имена, что и методы родительского
класса. В этом случае метод класса-потомка имеет больший приоритет. При необходимости
можно воспользоваться любым из этих методов.
150 Часть III. Основы программирования на РНР
Что отсутствует в объектно-ориентированной парадигме РНР 5
Если вы знакомы с объектно-ориентированным программированием на других языках, то,
возможно, обнаружите, что некоторые из его характерных свойств в языке РНР отсутствуют.
Однако жизнь не стоит на месте, и многие возможности, которых не было в РНР 4, были добавлены
в РНР 5. Однако по-прежнему отсутствуют следующие механизмы.
•S Полиморфизм (polymorphism). В сценарии РНР в одном классе не может
быть двух методов с одинаковыми именами, даже конструкторов. Другими
словами, в РНР нельзя реализовать полиморфизм. В одном классе невозможно
иметь два метода с одним и тем же именем, но с разным набором параметров
(сигнатурами). Для реализации полиморфизма программисты иногда используют
операторы switch и другие механизмы.
•S Множественное наследование (multiple inheritance). В языке РНР отсутствует
механизм множественного наследования. Класс может быть наследником
только одного родительского класса.
nfioificuui
Объектно-ориентированные программы требуют тщательного анализа и планирования гораздо
больше, чем процедурные программы, в которых операторы обрабатываются от начала
до конца и не используются классы. Необходимо тщательно спланировать, какие свойства
и методы будут содержать объекты. При этом должны быть учтены все важные аспекты
функционирования предметной области. Однако обязанности классов не должны быть раздуты.
При реализации сложных проектов может понадобиться создать модель и выполнить тестирование.
Лишь после этого можно быть уверенным в том, что в состав программной системы
входят все необходимые объекты.
Выбор объектов
При разработке программы сначала нужно сформулировать перечень требуемых объектов.
Если приложение не очень большое, то выполнить это достаточно просто. Но если программная
система является большой и сложной, то список требуемых объектов может оказаться
гораздо менее очевидным. Например, если разрабатывается программное обеспечение для банка,
то можно выбрать такие объекты, как счет, кассир, деньги, чековая книжка, корзина для бумаги,
служба охраны, сейф, система безопасности, клиент, ссуда, кредитная ставка и т.д. Однако
все ли эти объекты действительно необходимы? Что программа должна делать с корзиной для
бумаги в холле или со службой охраны? Возможно, понадобится составлять график ее работы.
Один из возможных подходов к идентификации объектов заключается в следующем. Сначала
сформируйте перечень всех возможных объектов (т.е. имен существительных) из предметной
области. Для этого разработчики иногда могут воспользоваться проектной документацией.
Затем из сформированного списка следует вычеркнуть как можно больше объектов. Необходимо
исключить повторяющиеся объекты, объекты с повторяющимися обязанностями
или те из них, которые напрямую не относятся к исследуемой предметной области. Например,
если проект связан с конструированием автомобилей, в качестве объектов наверняка
пригодятся все его детали. С другой стороны, если проект связан с управлением движением
автомобилей, то их составные части окажутся гораздо менее важными.
Глава 9. Объектно-ориентированное программирование на РНР 151
Выбор свойств и методов для каждого объекта
После формирования списка объектов можно приступить к выбору свойств и методои для
каждого из них. Спросите себя, что вам нужно знать о каждом объекте. Например, в программе,
связанной с ремонтом автомобилей, пригодится информация о том, когда автэмо-
биль последний раз проходил технический осмотр и был в ремонте, каковы характеристики
его узлов и агрегатов, и т.д.
Объекты должны быть независимыми, для каждого из них необходимо определить обязанности
и методы, которые они будут выполнять. В качестве примера рассмотрим объект
"банковский счет". Сначала его нужно создать (т.е. открыть). Для этого подойдет метод
openBankAccount (). После этого с банковским счетом можно осуществлять различные
операции: класть деньги на счет, оплачивать счета, следить за балансом счета и выдгиать
о нем различную информацию.
Однако после некоторых размышлений и экспериментов может оказаться, что все-таки
что-то было упущено. Например, со счетом должны быть связаны данные о владельце его
имени и об адресе. Не забыли ли вы добавить метод обновления этой информации, если владелец
переедет на новое место жительства?
Создание и использование класса
После выявления объектов и их свойств можно приступать к их созданию и истолкованию.
Для создания и использования объекта нужно выполнить следующие действия.
1. Использовать ключевое слово c l a s s . Ключевое слово c l a s s является основным при
создании класса. С ним связывается блок инструкций со свойствами и методами класса.
2. Вставить выражение c l a s s в те места, где необходимо использовать соответствующий
объект. Класс можно разместить в самом сценарии. Однако чаще всего конструкцию
c l a s s размещают в отдельном файле, который включается в сценарий
с помощью директивы include.
3. Создать объект в сценарии. На основе описания класса можно создавать объекты,
т.е. выполнять инстанцирование (instantiation).
4. Использовать объект. После создания нового объекта можно приступать к егс использованию.
При этом можно использовать любые методы класса, определенные
в соответствующем блоке при его описании.
Оставшаяся часть этой главы будет посвящена более подробному описанию каждого из
этих этапов.
Onfieqejietiue класса
После выявления требуемых объектов, их свойств и методов можно приступать к определению
соответствующих классов. Класс является шаблоном (каркасом) для создания объектов.
Создание класса
Выражение c l a s s используется для определения свойств и методов класса и имеет следующий
синтаксис:
c l a s s имяКласса
{
Определение свойств класса
Определение методов класса
}
152 Часть III. Основы программирования на РНР
В качестве имени класса можно использовать любой корректный идентификатор РНР,
кроме s t d C l a s s — зарезервированного служебного имени РНР.
Описание свойств и методов класса заключается в фигурные скобки. Если необходимо, чтобы
класс наследовал свойства и методы другого класса, следует воспользоваться выражением
class whiteRose extends Rose
{
Определение свойств класса
Определение методов класса
}
Объект, созданный на основе этого класса, будет иметь доступ ко всем свойствам и методам
как класса whiteRose, так и Rose. Однако класс Rose не имеет доступа к свойствам
и методам класса-наследника.
Следующие несколько разделов посвящены вопросам, связанным с определением свойств
и методов класса. Более исчерпывающий пример создания класса приведен ниже, в разделе
"Собирая все вместе".
Определение свойств
При создании класса все его свойства следует объявить в начале соответствующего блока.
class Car
{
var vvaarr $$$tgcaiosrl;eosr ;;
Методы
}
В общем случае в РНР объявлять переменные необязательно. Во многих сценариях, приведенных
в этой книге, переменные не объявляются, они просто используются. То же самое касается
и классов, однако лучше этого не делать. Объявление переменных позволяет легче понять назначение
класса. Кроме того, отсутствие явных объявлений является плохим стилем программирования.
При объявлении переменных им можно присвоить значения по умолчанию. Такие значения
могут быть лишь самыми простыми и не должны содержать вычисляемых выражений.
Приведенные ниже примеры помогут лучше разобраться в этом.
•S Следующие выражения можно использовать в качестве значений по умолчанию:
var $color = "черный";
var $gas = 10; var $tires = 4;
•S Эти выражения нельзя использовать в качестве значений по умолчанию:
var $color = "синий"." черный"; var $gas = 10-3;
var $tires = 2*2;
В качестве переменных можно также использовать массивы, в которых содержатся простые
значения.
var $doors = array("передняя часть", "задняя часть");
Значения соответствующих переменных класса при создании объекта можно задавать или
изменять, используя конструктор (который описывается ниже, в разделе "Создание конструктора")
или любой другой метод, предназначенный для этих целей.
Глава 9. Объектно-ориентированное программирование на РНР 153
Использование переменной $ t h is
Внутри класса специальная переменная $ t h i s представляет собой ссылку на это" же
класс. При этом ее нельзя использовать вне класса. Эта переменная обеспечивает до:туп
к переменным и методам класса внутри самого класса.
Для использования переменной $ t h i s можно использовать следующий синтаксис:
$ t h i s->имя_переменной
Например, для доступа к атрибуту $gas класса Саг следует воспользоваться выражением
$this->gas
Таким образом, с помощью переменной $ t h i s можно манипулировать атрибутом $gas
внутри класса, как, например, в следующих примерах:
$this->gas = 20;
if($this->gas > 10)
$product[$this->size] = $price
Как видно в приведенных примерах, выражение $?Ь.1э->имя_переменной псполь:ует-
ся внутри класса точно так же, как и переменная $имя_переменной в сценарии.
Обратите внимание на то, что символ $ используется только перед именем t h i s , а не
gas. Если воспользоваться выражением $this->$gas, оно будет неправильно проиьтер-
претировано. При этом может возникнуть (а может, и нет) ошибка, однако в любом случае
это не будет иметь никакого отношения к ссылке на переменную $gas текущего класса.
Добавление методов
Методы определяют функциональность объектов и определяются точно так же, как и обычные
функции. Например, для класса "автомобиль" может понадобиться метод, который будет
обеспечивать заправку бензином его бака. В классе может содержаться переменная $gas, значение
которой будет соответствовать количеству бензина, содержащегося в баке в текущий момент.
Можно определить метод, который будет добавлять к этой переменной значение
$amount (количество заправленного бензина). Это можно осуществить следующим образом
class Car
{
var $gas = 0;
function addGas($amount)
{
$this->gas = $this->gas + $amount;
echo "в бак залито $amount галлонов бензина";
>
}
Функция addGas () выглядит как обычная функция, но поскольку она находится вн;три
класса, то является его методом.
В языке РНР определено несколько специальных методов, имена которых начинаются
с двух символов подчеркивания ( ). В этой главе рассматриваются три из них: construct,
d e s t r u c t и clone. Поэтому имена своих методов лучше не начинать с двух символов :юд-
черкивания, если только не переопределяется один из специальных методов.
Создание конструктора
Конструктор (constructor) — это специальный метод класса, который выполняется при
создании объекта. Конструктор использовать необязательно, если при создании объекта не
нужно присваивать значения атрибутам или выполнять какие-либо действия. В классе мсжет
содержаться только один конструктор.
154 Часть III. Основы программирования на РНР
Конструктор имеет специальное имя ( construct), поэтому интерпретатор РНР всегда
знает, какой метод нужно выполнять при создании объекта. Конструктор имеет примерно
следующий вид:
funct i on cons true t ()
{
$this->gas =10; # бак заполнен полностью
$this->openDoor();
}
Этот конструктор создает новый автомобиль (т.е. объект) с полным баком и открытой дверью.
d?P?~$tb_ До версии РНР 5 имя конструктора совпадало с именем класса. При этом классы, соз-
Mifexrj Л данные для более ранних версий интерпретатора, могут использоваться и в РНР 5.
Жл?ь.У ^Ри С03Дании объектов интерпретатор РНР 5 сначала пытается вызвать конструк-
°4»SS&P^ тор с именем construct (). Если такой метод отсутствует, вызывается метод
с именем, совпадающим с именем класса.
Собирая все вместе
Класс должен содержать столько атрибутов и методов, сколько необходимо. Эти методы
могут быть как простыми, так и сложными. Однако цель объектно-ориентированного программирования
заключается в том, чтобы сделать методы как можно более рациональными.
Лучше использовать несколько небольших функций и вызывать один метод внутри другого,
а не реализовывать все требуемые действия в одной функции. Рассмотрим следующий пример:
class MessageHandler
{
var $message = "Сообщения нет";
function construct($message)
{
$this->message = $message;
}
function displayMessage()
{
echo $this->message. "\n";
}
}
Класс MessageHandler имеет один атрибут $message, в котором хранится сообщение,
и один метод displayMessage, предназначенный для его вывода.
Предположим, необходимо добавить метод, который будет преобразовывать символы сообщения
в нижний регистр, а затем выводить их на экран. Это можно выполнить таким образом:
class MessageHandler
{
var $message = "Сообщения нет";
function construct($message)
$this->message = $message;
function displayMessage()
echo $this->message. "\n";
function lowerCaseMessage()
$this->message = strtolower($this->message);
$this->displayMessage() ;
}
Глава 9. Объектно-ориентированное программирование на РНР 155
Обратите внимание на метод lowerCaseMessage (). Поскольку класс уже содеркит
метод для вывода сообщения, в новом методе lowerCaseMessage () используется именно
этот метод. Если при создании нового метода оказалось, что часть его кода уже использс ва-
лась в другом методе, нужно выполнить их повторное проектирование. В одном и том же
классе не должно быть повторяющегося кода.
В листинге 9.1 приведен более сложный пример класса, который можно использовать для
создания HTML-форм. Для некоторого упрощения примера в форме содержатся только "ек-
стовые поля.
Листинг 9.1. Пример сценария, в котором содержится класс для создания форм
<?php
/* Имя класса: form
* Описание: класс, создающий простую HTML-форму с
* одним текстовым полем. Класс содержит 3 метода.
*/
class Form
t
var $fields=array(); # содержит имя поля var $processor; # имя программы обработки данных формы
var $submit = "Отправить данные"; # имя кнопки Submit
var $Nfields = 0 ; # количество полей формы
/* Конструктор: передается имя сценария обработки данных
* ($processor) и имя кнопки.
*/
function construct($processor, $submit)
{
$this->processor = $processor;
$this->submit = $submit;
}
/* Функция отображения формы.
*/
function displayForm()
{ echo "<form action='{$this->processor}' method='post'>";
echo "<table width='100%'>";
for($j=l;$j<=sizeof($this->fields);$j++)
{
echo "<trxtd align=\"right\">
{$this->fields[$j-l]['label']}: </td>\n";
echo "<td>
<input type='text'
name='{$this->fields[$j-l]['name']}'>
</tdx/tr>\n";
}
echo "<tr><td colspan=2 align='center'>
<input type='submit'
value= ' {$this->submit} ' ></tdx/tr>\n" ;
echo "</table>";
/* Функция для добавления поля формы. Ее параметрами
* являются имя и метка поля.
*/
function addField($name, $label)
$this->fields[$this->Nfields]['name'] = $name;
{
156 Часть III. Основы программирования на PHP
$this->fields[$this->Nfields] [ 'label' ] = $label,-
$this->Nfields = $this->Nfields + 1;
}
}
?>
В созданном классе Form содержатся четыре атрибута (свойства) и три метода. Ниже
приведен перечень атрибутов.
•S $f i e l d s . Массив, содержащий поля формы, заполняемые пользователем.
•f $ p r o c e s s o r . Имя сценария, который обрабатывает данные, введенные пользователем
в форме. Значение этой переменной используется в атрибуте
a c t i o n дескриптора form.
•S $ s u b m i t . Текст, который отображается на кнопке submit.
•S $Nf i e l d s . Количество полей, добавленных в форму в текущий момент.
В классе Form содержатся следующие методы.
•S construct (). Конструктор, который во время создания объекта присваивает
атрибутам $ p r o c e s s o r и $submit значения, переданные пользователем.
•f a d d F i e l d ( ) . Добавляет имя и метку поля в массив $f i e l d s . Например, если
пользователь добавил в форму поля для ввода имени и фамилии, то этот
массив будет иметь следующий вид:
$ f i e l d s [ l ] [ n a m e ] = f i r s t _ n a m e
$ f i e l d s [ l ] [ l a b e l ] = F i r s t Name
$ f i e l d s [ 2 ] [ n a m e ] = l a s t _ n a m e
$ f i e l d s [ 2 ] [ l a b e l ] = L a s t Name
и т . д.
S d i s p l a y F o r m ( ) . Используется для вывода формы на экран, т.е. дескрипторов
HTML, необходимых для создания формы. При этом используются имена
и метки полей, содержащиеся в атрибутах класса.
В следующем разделе описываются принципы использования классов в сценарии, в том
числе класса Form, приведенного в листинге 9.1.
использование класса
Класс, который используется в сценарии, должен быть в него каким-то образом добавлен.
Обычно он размещается в отдельном файле и с помощью функции i n c l u d e () подключается
к основному сценарию.
Для того чтобы использовать объект, его необходимо сначала создать. После этого объект
может выполнять любые методы, определенные в классе. Процесс создания объектов называется
инстанцированием (instantiation). Аналогично тому, как выкройка используется для шитья
большого количества похожей, но все же по-своему индивидуальной одежды, точно так же на
основе классов создаются объекты. Для создания объекта используется следующий синтаксис:
$имя_объекта = new имяКласса(значение, значение, . . . ) ;
$Joe = new Person("мужчина");
$car_Joe = new Car("красный");
$car_Sam = new Car("зеленый");
$customerl = new Customer("Смит", "Джо", $custID);
Глава 9. Объектно-ориентированное программирование на PHP 157
При создании объекта вызывается конструктор, в результате чего объект связывается
с переменной с заданным именем. После этого для вызова метода класса можно воспользоваться
следующими выражениями:
$Joe->goToWork();
$car_Joe->park("запрещено");
$car_Sam->paintCar("синий") ;
$name = $customerl->getName () ,-
Разные объекты, созданные на основе одного и того же класса, независимы друг от друга.
Например, если автомобиль Сэма перекрасить в голубой цвет, то автомобиль Джо никак не
изменит свой цвет и будет оставаться красным. Джо покупает талон для парковки, но этс никак
не повлияет на Сэма (и на его автомобиль).
В листинге 9.2 приведен пример использования класса Form, который был создан в предыдущем
разделе и представлен в листинге 9.1.
Листинг 9.2. Сценарий создания формы с помощью класса Form
< ?php
/* Имя сценария: buildForm
* Описание: использование класса Form для создания
* простой HTML-формы.
*/
require_on.ce (" form, inc") ;
echo "<htmlxheadxtitle>OopMa для добавления телефонного
HOMepa</titlex/head><body>" ;
$phone_form = new Form("process.php", "Отправить данные");
$phone_form->addField("first_name", "Имя");
$phone_form->addField("last_name", "Фамилия");
$phone_form->addField("phone", "Номер телефона");
echo "<ЬЗ>Пожалуйста, заполните поля данной формы:</h3>";
$phone_form->displayForm();
echo "</bodyx/html>" ;
?>
Сначала с помощью функции require_once() файл form, i n c с описанием класса
Form включается в сценарий. На его основе создается объект с именем $phone_f orm. 3aieM
в форму добавляются три поля, после чего форма выводится на экран. Следует заметить, что
в приведенном фрагменте использовалось несколько дополнительных дескрипторов НИ ЛЬ,
которые можно было бы разместить и в методе displayForm ().
При выполнении приведенного сценария с использованием класса Form будет созвана
форма с тремя полями (рис. 9.1).
CtcfiMffibie свойс(н?а и методы
Свойства и методы класса могут быть как открытыми (public), так и закрытыми
(private). Открытые свойства и методы доступны извне класса, т.е. из сценария, в котором используется
данный класс, или из другого класса. Рассмотрим пример класса, атрибут и ме год
которого являются открытыми:
class Car
{
var $gas = 0;
function addGas($amount)
158 Часть III. Основы программирования на PHP
$this->gas = $this->gas + $amount;
echo "в бак залито $amount галлонов бензина";
3 Форма для добавления телефонного номера
Файл Правка Вид Избранное Сервис Справка
Оказал • © - [К] [ i ' ^ >"> Поиск • & Избранное Щ
Адрес; ! j § | http://localhost/test/buildForm.php
- П X
а» - u fp
v : Q Переход
Пожалуйста, заполните поля данной формы:
Имя:
Фамилия:
Номер телефона:
Отправить данные
I Готово * д Местная интрасеть
Рис. 9.1. Результат выполнения сценария, представленного в листинге 9.2
Теперь к открытому атрибуту класса $gas можно получить доступ из-за его пределов
следующим образом:
$mycar = new Car;
$gas_amount = $mycar->gas;
После выполнения этого фрагмента в переменной $gas_amount будет содержаться значение
атрибута $gas объекта mycar. Значение атрибута можно также и изменить извне класса:
$mycar->gas = 20;
Прямой доступ к атрибутам класса считается плохим стилем программирования. Любое
взаимодействие объекта и внешнего сценария или другого класса должно осуществляться
лишь посредством методов. Метод addGas () из приведенного класса Саг является открытым
и применяется для "заправки" автомобиля (т.е. для увеличения значения атрибута $gas):
$new_car = new Car;
$new_car->addGas(5);
Язык PHP позволяет ограничить доступ к атрибутам и методам класса. Это можно осуществить
следующими способами.
| S Спецификатор p r i v a t e (закрытый) запрещает доступ к атрибутам и методам
класса из-за пределов класса, сценариев или других классов.
Глава 9. Объектно-ориентированное программирование на РНР 159
S Спецификатор p r o t e c t e d (защищенный) предоставляет доступ к защищенным
свойствам и методам класса только для его классов-наследников. El остальных
случаях доступ запрещен.
Для того чтобы атрибут стал скрытым, следует воспользоваться выражением
private $gas = 0;
При попытке прямого доступа к скрытому атрибуту отобразится следующее сообщен! Ее об
ошибке:
Fatal error: Cannot access private property car::$gas in
c : \ t e s t c l a s s . p h p on l i n e 17
(Фатальная ошибка: Нельзя получить доступ к закрытому атрибуту
car::$gas в файле c : \ t e s t c l a s s . p h p в строке 17)
Теперь изменить значение атрибута $gas класса Саг можно только с помощью метода
addGas (), поскольку он является частью класса Саг и, следовательно, имеет доступ к соответствующему
скрытому атрибуту.
Подобно атрибутам, методы класса также могут быть скрытыми (private) или защи ленными
(protected). Однако в классе Саг метод addGas () является открытым. В реал .пых
программах нужно быть уверенным в том, что за бензин, которым заправлен автомобил!, уплачено
и что он не взялся неизвестно откуда (например, был украден). Поэтому класс Саг
следует переписать следующим образом:
class Car
{
private $gas = 0;
private function addGas($amount)
{
$this->gas = $this->gas + $amount;
echo "в бак залито $amount галлонов бензина";
}
function buyGas($amount)
{
$this->addGas($amount);
}
>
Теперь единственный возможный способ изменения значения атрибута $gas класса Саг
(т.е. заправки автомобиля) заключается в использовании метода buyGas (). В свою очеэедь,
этот метод использует скрытый метод addGas (). Прямой вызов метода addGas () приведет
к возникновению ошибки.
$new_car = new Car;
$new_car->addGas(5);
Для того чтобы этого не произошло, необходимо воспользоваться методом buyGas ():
$new_car = new Car;
$new_car->buyGas(5);
В результате получим следующий результат:
в бак залито 5 галлонов бензина
Хороший стиль программирования заключается в сокрытии как можно большего количества
деталей реализации класса. Все атрибуты должны быть скрытыми (private), а методы
(те из них, которые должны быть открытыми) — p u b l i c .
В языке РНР атрибуты и методы класса могут быть объявлены открытыми несколькими способами.
Это связано с тем, что по умолчанию уровень доступа является открытым. Так, выражение
160 Часть III. Основы программирования на РНР
public $gas = 0;
равносильно
var $gas = 0;
использование исключений
Для обработки ошибок в языке РНР используется класс Exception (исключение). Его
можно применять для обработки нежелательных событий, которые могут возникнуть в сценарии.
Если возникает заранее определенная разработчиком ситуация, то выполняется соответствующая
процедура ее обработки. С точки зрения объектно-ориентированного подхода
этот процесс называется генерацией исключения.
В классе Саг автомобиль может двигаться до тех пор, пока в его баке есть горючее
(т.е. $gas>0). Поэтому сценарий должен правильно реагировать на ситуацию, когда значение
атрибута $gas станет отрицательным. Это и будет исключением. Для его обработки необходимо
воспользоваться классом Exception с помощью следующего фрагмента кода:
$this->gas = $this->gas - 5;
t ry
{
if ($this->gas < 0)
{
throw new Exception("Отрицательное количество бензина. " ) ;
}
}
catch (Exception $e) v
{
echo $e->getMessage();
echo "\n<br />\n";
exit();
}
В приведенном фрагменте содержатся блоки t r y и catch.
S В блоке t r y выполняется проверка условия. Если результат проверки условия
— TRUE, то генерируется исключение, т.е. создается новый объект класса
Exception. Этот объект имеет атрибут, в котором хранится сообщение, которое
будет использоваться при генерации исключения.
S В блоке c a t c h исключение перехватывается, и ему присваивается имя $е.
После этого выполняется обработка исключения. В частности, вызывается
метод getMesssage () класса Exception. Этот метод возвращает сообщение,
заданное при создании объекта Exception, которое выводится с помощью
функции echo.
Если исключение не сгенерировано, блок c a t c h игнорируется, а выполнение сценария
продолжается.
Копирование оЯъешпов
Для копирования объектов в языке РНР используется специальный метод clone ()
(с двумя символами подчеркивания). При необходимости этот метод можно переопределить.
Глава 9. Объектно-ориентированное программирование на РНР 161
По умолчанию (т.е. без переопределения) метод clone () просто скопирует все атрюуты
одного объекта в атрибуты другого объекта.
Рассмотрим следующий класс с переопределенным методом clone ():
class Car
{
private $gas = 0;
private $color = "красный";
func t i on addGa s($ amoun t)
{
$this->gas = $this->gas + $amount;
echo "в бак залито $amount галлонов бензина";
}
function clone()
{
$this->gas = 0;
}
}
Используя этот класс, можно создать объект, а затем скопировать его следующим образо и:
$firstCar = new Car;
$firstCar->addGas(10);
$secondCar=$firstCar-> clone();
После выполнения этого фрагмента кода будут созданы два объекта класса Саг.
•S $firstCar. Этот автомобиль имеет красный цвет и 10 галлонов бензина,
которые были добавлены с помощью метода addGas ().
S $secondCar. Этот автомобиль также имеет красный цвет, но 0 галлонов
бензина. Объект $secondCar был создан как копия $f i r s t C a r с помощью
вызова метода clone (), который присваивает переменной $gas значение
0 и вообще не устанавливает цвет ($color).
Если в классе Саг не переопределить метод clone (), интерпретатор РНР создаст его самостоятельно,
по умолчанию скопировав все атрибуты объекта $f i r s t C a r в $secondCar, т.е.
автомобиль $secondCar, как и $f irstCar, будет иметь красный цвет и 10 галлонов бензина
Удаление оЗъешпов
Удалить ранее созданный объект можно следующим образом:
unset($objName);
Ниже приведен пример, в котором объект класса Саг создается, а затем удаляется.
$myCar = new Car;
unset($myCar);
После вызова функции unset () объект больше не существует.
В РНР имеется специальный метод destruct (), который автоматически вызывается
при удалении объекта. Ниже приведен класс, содержащий этот метод.
class Bridge
{
function destruct()
{
echo. "Мост разрушен";
162 Часть III. Основы программирования на РНР
}
}
При создании объекта класса Bridge, а затем его удалении
$bigBridge = new Bridge;
unset($bigBridge);
отобразится следующее сообщение:
Мост разрушен
Оно отображается вследствие вызова метода destruct () при вызове функции unset ().
Метод destruct () не является обязательным. По необходимости его можно переопределить,
как методы construct () и clone (), и выполнить некоторые специфические
действия при удалении объекта. Например, при удалении объекта может потребоваться
закрыть некоторые файлы или переписать информацию в базу данных.
Глава 9. Объектно-ориентированное программирование на РНР 163
Часть IV
Стандартные РНР-приложения
5?
"ЛАЙНО, HAbipHOi, Я *>А5ЫЛ ЫСЛСМЬ, ИЫО totfctpb Ц
ABtoOMAtouHtGKW fcOtfAtto ?WW*A *Api60lM kpw p*SpW6i
В части IV речь пойдет о том, как использован, язык РНР для решения
стандартных задач программирования. Вы узнаете, как создавать сценарии,
которые чаще всего используются в Web-приложениях, как язык
РНР позволяет взаимодействовать с балами данных, операционными
системами и приложениями электронной почты. После изучения материала
этой части вы сможете писать сценарии, с которыми пользователи
будут взаимодействовать посредством HTML-форм, а также обрабатывать
различные данные и решать стандартные задачи, возникающие при
разработке Web-приложений.
Глава 10
Основы создания Web-приложений
Вэ/ной главе...
> Обеспечение безопасности Web-узлов
> Отображение статических страниц
> Получение информации от пользователей с помощью HTML-форм
> Обработка информации, полученной от пользователей
ервоначально язык РНР был разработан исключительно для Web-программирования.
Однако со временем он стал использоваться и для других целей. В настоящее
время РНР по-прежнему часто применяется для разработки динамических Web-
узлов. Статические (static) Web-страницы одинаковы для всех пользователей и не предоставляют
возможности интерактивного взаимодействия. В свою очередь, динамические
(dynamic) страницы предоставляют такую функциональность. В зависимости от введенной
пользователем информации в браузере могут отображаться различные страницы. Например,
перед тем как получить доступ к ресурсам некоторого Web-узла, пользователю может потребоваться
ввести свое имя и пароль. При этом узел сможет "настроиться" на этого пользователя,
основываясь на соответствующем профиле. Пользователь может также выбрать необходимый
тип товара из интерактивного каталога и получить только нужную информацию.
Динамические Web-страницы получают информацию от пользователей с помощью
HTML-форм. Данные, введенные в полях формы, обрабатываются, и в зависимости от результата
этой обработки пользователю могут предоставляться различные Web-страницы. При
этом для вывода различных страниц данные обработки можно сохранить (этот вопрос более
подробно рассматривается в главе 12) или использовать их в условных операторах.
В данной главе не рассматриваются дескрипторы HTML, используемые для создания
форм. Предполагается, что вы с ними уже знакомы. (В противном случае обратитесь к книге
Эда Титтела, Натаньи Пите и Челси Валентаин HTML 4 для "чайников", 3-е издание, которая
вышла в издательстве "Диалектика".) В этой главе также рассматриваются вопросы обеспечения
безопасности Web-узлов и использование языка РНР для отображения форм и обработки
пользовательской информации.
Обеспечение Яезопасноапи Web-t/зла
Web-приложения очень часто подвергаются атакам взломщиков. Большинство Web-
приложений размещается на открытых серверах и предоставляет набор услуг, товаров или
информации любому посетителю. Динамические Web-узлы оказываются особенно уязвимыми,
поскольку они получают информацию от своих посетителей. Несмотря на то что большинство
пользователей являются нормальными людьми, которые пользуются информационными
ресурсами в мирных целях, среди них все же есть злоумышленники. Как правило, их
можно разделить на следующие категории.
Я
•S Злоумышленники, которые пытаются найти файлы с номерами кредитных
карточек и другой конфиденциальной информацией, например с паролями
S Взломщики, пытающиеся разрушить Web-узел. Они считают забавным в шо-
мать Web-узел или причинить вред просто для того, чтобы продемонстрировать
свое мастерство.
S Злоумышленники, пытающиеся нанести ущерб пользователям, размс ща-
ют на Web-сервере средства, которые наносят вред его посетителям.
Данную книгу не следует рассматривать как исчерпывающий источник информации, кэто-
рая позволит решить все вопросы, связанные с обеспечением требуемого уровня защищенности
Web-приложения. Это достаточно обширная и сложная область, которой посвящено большое
количество специализированных книг. Однако некоторые вопросы все же заслуживают внимания
и здесь. Следующие основные замечания позволят существенно повысить уровень знци-
щенности Web-приложения, однако если оно предназначено для обработки действительно наж-
ной и секретной информации, лучше обратиться к соответствующим книгам или экспертам.
</ Обеспечение безопасности компьютера, на котором установлено Web-
приложение. Это относится к сфере ответственности системного администрат ора.
S Ограничение доступа к информации. Объем предоставляемой информации
должен быть не больше, чем требуется для предоставления услуг или решения
требуемой задачи. Информацию нужно хранить таким образом, чтобы ее
нельзя было легко извлечь через Web.
S Осторожность при получении информации от пользователей. Необходимо
тщательно проверять все данные, сгенерированные в клиентской части
вашего приложения.
S Настройка Web-сервера на функционирование в самом защищенном режиме.
Это потребует дополнительных забот, но, если информация очень наживи
и секретная, затраченные усилия того стоят.
Более подробно эти вопросы рассматриваются в следующих разделах.
Обеспечение безопасности компьютера, на котором
установлен Web-узел
Первой линией защиты Web-приложения является обеспечение защищенности компьютера,
на котором оно установлено. Ответственным за решение этой задачи, как правило, я тя-
ется системный администратор. При этом можно установить брандмауэр, активизировать режим
шифрования/сокрытия паролей, воспользоваться утилитами сканирования и т.д.
В большинстве случаев ни один из разработчиков Web-приложения не является системным
администратором. Однако в любом случае необходимо провести тщательный анализ подходов
к обеспечению безопасности либо с системным администратором, либо с Web-
хостинговой компанией, предоставляющей ресурсы для развертывания Web-приложения.
Ограничение доступа к информации
Доступ к информации, хранящейся на Web-узле, должен быть ограниченным. Вне всякого
сомнения, Web-страницы, предназначенные для просмотра пользователями, должны быть открытыми
и находиться в соответствующем общедоступном каталоге Web-сервера. При зтом
пользователю нет необходимости видеть имена хранящихся в них файлов. Вы, наверное, посещали
Web-узлы, которые отображали каталог со списком файлов. В общем случае так делать
не следует, поскольку посетители смогут просмотреть любой удаленный файл.
168 Часть IV. Стандартные РНР-приложечия
Список файлов отображается в том случае, когда в URL-адресе не указано имя целевого
файла, а в каталоге отсутствует файл, который отображается по умолчанию. Обычно Web-
сервер настроен таким образом, чтобы в подобных ситуациях выводить определенный файл
(обычно index. html), если явно не указано другое имя. В противном случае пользователь
сможет увидеть список файлов, а это — весьма нежелательно. Лучше всего настроить Web-
сервер таким образом, чтобы при попытке доступа к каталогам выводилось сообщение о невозможности
получения доступа к каталогу.
Forbidden
You don't have permission to access /secretdirectory on this server.
(Доступ запрещен
У вас нет прав доступа к каталогу / s e c r e t d i r e c t o r y на этом сервере.)
v При настройке Web-сервера Apache это можно сделать с помощью директивы Indexes
конфигурационного файла h t t p d . conf:
Options Indexes // позволяет отображать файлы каталога
Options -Indexes // запрещает отображать файлы каталога
При настройке других Web-серверов следует обратиться к соответствующей документации.
Кроме того, не следует присваивать файлам легко угадываемые имена. Например, если
в Web-приложении используется файл с пользовательскими паролями, то присваивание ему
имени passwords .php окажется далеко не лучшей идеей. Вместо этого такому файлу следует
дать непримечательное или обманчивое имя, например vegetableRecipes.php.
Можно возразить, что это противоречит правилу присваивания файлам отчетливых имен.
(Об этом упоминается во многих других главах этой книги.) Однако данный случай является
особенным. Некоторые злоумышленники вводят в браузере URL-адрес www.yoursite.com/
password. html и ждут, что из этого получится.
Далеко не вся информация Web-узла должна быть общедоступной. Например,
база данных не должна размещаться в открытом каталоге. Фактически подобную
информацию лучше всего хранить совсем на другом компьютере, доступ к которому
нельзя получить через Internet.
Осторожность при получении информации от пользователей
Пользователи могут случайно или злоумышленно ввести в форме опасную
(нежелательную) информацию. Поэтому перед ее сохранением или использованием необходимо
проверить ее на корректность и отсутствие опасных символов или строк. Введенная
информация (даже случайная) может нанести существенный вред сценарию или базе данных.
Особенно опасными являются дескрипторы HTML (например, <script>), поскольку их
можно использовать для размещения на Web-узле опасных сценариев. Если введенную пользователем
информацию принять и сохранить в базе данных без проверки, можно столкнуться
с целым ворохом проблем, особенно в том случае, если эту информацию впоследствии будут
использовать (и запускать) другие посетители Web-узла. Вопросы проверки данных, вводимых
в полях форм, более подробно рассматриваются ниже, в разделе "Проверка данных".
Использование безопасного Web-сервера
Взаимодействие Web-приложения с посетителями нельзя считать абсолютно безопасным.
Если находящийся на Web-узле файл передается в клиентскую часть приложения (браузер),
то вполне вероятно, что во время передачи данных по Internet кто-то посторонний сможет
прочитать содержимое файла. Для большинства Web-узлов это не является проблемой. Но
если среди передаваемых данных содержатся номера кредитных карточек или пароли, то
Глава 10. Основы создания Web-приложений 169
<D
вопросы обеспечения их конфиденциальности сразу же выдвигаются на передний план. У ро-
вень защищенности данных можно повысить и при использовании безопасного Web-серве за.
На безопасных Web-серверах для защиты данных часто используется протокол .SSL
(Secure Sockets Layer). При его использовании информация кодируется и лишь после этого
передается через Web. Клиентское программное обеспечение выполняет обратное декод» ро-
вание. Вне всякого сомнения, развертывание безопасного Web-сервера требует дополнительных
усилий, но для некоторых приложений без этого просто не обойтись.
При взаимодействии с использованием протокола SSL URL-адрес начинается
с префикса h t t p s , а не h t t p .
Каждый Web-сервер можно защитить по-своему. Информацию о том, как включить режим
использования защищенного протокола SSL, следует искать в соответствующей документации.
Например, при использовании сервера Apache необходимую информацию мо;шо
найти на двух Web-узлах: www.modssl.org и www.apache-ssl.org. Если вы решили
воспользоваться Web-сервером IIS компании Microsoft, то информацию о протоколе SSL
можно найти на Web-узле www.microsoft. com.
Gfflo^ficufceHue апа/пичеаеих Web-ctnfiaHUU,
Наиболее простыми являются статические Web-страницы. Если при разработке Web-) зла
таких страниц вполне достаточно, то в использовании языка РНР нет никакой необходимости.
Однако в то же время статические Web-страницы могут использоваться для взаимо; кистеня
с динамическими страницами.
Язык РНР можно использовать для отображения любых Web-страниц, в том числе и статических.
При этом для вывода HTML-кода можно воспользоваться функцией echo. Если же
на странице содержатся только дескрипторы HTML, которые нужно использовать в сцена зии
РНР, то лучше всего включить определенный файл в требуемое место следующим образом:
include("имя_файла") ;
Если по каким-то причинам статическую Web-страницу понадобилось преобразо! ать
в сценарий РНР, выполните следующее. Добавьте в начало и в конец соответствующего <} аила
дескрипторы РНР (<?php и ?>), а затем добавьте функцию echo в начале этого файла
и заключите весь код HTML в одинарные кавычки.
IPaJoina с НУиШ-фо/гмами
Для того чтобы Web-страница стала интерактивной, она должна обеспечивать получение
информации от пользователей. Это можно осуществить с помощью HTML-форм. Получаемые
от пользователей данные могут быть простыми, такими как регистрационное имя и пароль.
Однако форма может быть достаточно длинной и сложной и состоять из большого количества
полей. Так, например, форма, предназначенная для покупки товаров в электронном
магазине, должна предоставлять возможность ввода различной информации о покупателе
(например, его адреса и номера кредитной карточки). Одним словом, внешний вид фогмы
и набор ее полей — это серьезные вопросы для настоящего исследования.
При использовании HTML-формы для сбора информации сценарий сначала должен отобразить
ее на Web-странице. Затем пользователь может ввести необходимые данные, заг ол-
няя поля или выбирая требуемые значения из списка. После этого нужно щелкнуть на соответствующей
кнопке, чтобы введенная информация была отправлена другому сценарию,
который и будет ее обрабатывать.
170 Часть IV. Стандартные РНР-приложения
В этой главе рассматриваются вопросы использования форм при разработке динамических
Web-узлов. Зачастую собранная с их помощью информация сохраняется в базе данных.
Если вы планируете использовать формы HTML совместно с базой данных MySQL, то для
получения более подробной информации можно обратиться к книге РНР & MySQL For Dummies
издательства Wiley Publishing, b e , автором которой является ваш покорный слуга.
Получение информации от посетителей Web-узла
Для получения информации от посетителей Web-узлов используются формы HTML. Если вы
не имеете опыта работы с языком HTML, обратитесь к книге Эда Титтела, Натаньи Пите и Челси
Валентайн HTML 4 для "чайников", 3-е издание, которая вышла в издательстве "Диалектика".
Отображение HTML-форм
Для вывода формы средствами РНР можно воспользоваться любым из следующих способов.
S Используйте для вывода HTML-форм функцию echo, как в следующем
примере:
echo "<form action='processform.php' method='POST'>\n
<input t y p e = ' t e x t ' name='name'>\n
<input type='submit' value='Отправить данные'>\n
</form>\n";
S Используйте обычный код HTML за пределами разделов с кодом РНР.
При создании статической формы нет необходимости включать ее в код РНР.
Например, в следующем примере выводится форма из предыдущего фрагмента:
<?php
код РНР
?>
<form action="processform.php" method="POST">
<input type="text" name="fullname">
<input type="submit" value="Отправить данные">
</form>
<?php
код РНР
?>
Каждый из приведенных примеров позволяют вывести форму, представленную на рис. 10.1.
В этой форме содержится одно пустое текстовое поле и кнопка с именем Отправить
данные. Пользователь может ввести в это поле свое имя, а затем щелкнуть на кнопке. В результате
введенная информация будет передана сценарию, имя которого задано в атрибуте
a c t i o n дескриптора <form>. В приведенном примере этот атрибут имеет вид ас-
tion="processform.php". Следовательно, введенные данные будут обработаны сценарием
processform.php. (Естественно, имя processform.php было выбрано исключительно в
учебных целях. На самом деле в атрибуге a c t i o n может быть указано любое имя.)
Язык РНР позволяет использовать в формах переменные, что существенно повышает их
эффективность. Такой подход позволяет заполнять текстовые поля нужной информацией
и динамически создавать раскрывающиеся списки, переключатели и флажки.
Вывоц информации в текстовых полях
Иногда может понадобиться заполнить текстовое поле данными, а не выводить его пустым.
Например, в поле может содержаться значение по умолчанию. В других случаях нужно
обеспечить, чтобы при вводе некорректной информации пользователю пришлось бы повторно
вводить данные лишь в те поля, где он допустил ошибку.
Глава 10. Основы создания Web-приложений 171
Э Простая форм - Microsoft Internet Explorer [- | [ П | | Х|
Файл Правка Вид Избранное Сервис Справка Щ
Q Назад - 0 Й й Й >:'П0ИСК &**>** 0 0*Ш ш *
Адрес: [Ц) http://localhost/test/SimpleForm,php vj Q Переход
Отправить данные
«***J
$Ц Готово «)j Местная интрасеть .;
Рис. /0./. Форма, созданная с использованием дескрипторов HTML
Вывести текстовое поле с данными можно с использованием кода
<input type="text" name="fieldname" value="значение">
Пусть, например, нужно разработать форму для получения имени покупателя и его адр< са.
Предположим, известно, что большая часть клиентов проживает в США. Поэтому вполне ю-
гично, чтобы в соответствующем поле сразу же выводилось значение США, заданное по ум эл-
чанию. При этом если покупатель действительно из Соединенных Штатов, ему ничего не ю-
требуется вводить и, следовательно, делать ошибки. Если же покупатель из другой страны,
ему придется ввести корректное название своей страны.
Для отображения такого поля необходимо воспользоваться следующим выражением:
<input type="text" name= "country" value="CIHA">'
В некоторых случаях в поле формы может потребоваться вывести значение перемен* ой
РНР. Предположим, имеется информация о покупателе (например, его телефонный номер),
которая хранится в базе данных. Эти данные нужно вывести в форме, чтобы пользователь
смог изменить неверную или устаревшую информацию. Для решения этой задачи необходимо
выполнить следующее. Во-первых, нужно извлечь информацию из базы данных (как :то
сделать, описывается в главе 12) и сохранить ее в соответствующих переменных. Затем ;;ля
вывода формы можно воспользоваться двумя способами. Первый способ заключается в использовании
кода РНР, встроенного в дескриптор HTML <input>:
<input type="text" name="phone" value="<?php echo $phone ?>">
Для вывода дескриптора HTML можно также воспользоваться функцией echo:
echo "<input type='text' name='phone' value='$phone'>";
При создании формы с большим количеством полей и немногими переменными, котор ые
с ними связаны, более эффективным является первый способ. Второй подход оказывается гораздо
более эффективным при использовании большого количества переменных.
Сценарий из листинга 10.1 выводит форму с информацией о покупателе. Результат работы
этого сценария показан на рис. 10.2.
172 Часть IV. Стандартные РНР-приложенчя
3 Адрес покупателя - Microsoft Internet Explorer
Файл Правка Вид Избранное Сервис Справка
ф н а м д - ф Щ Щ Л' ^ Поиск ^Избранное ф \
Адрес: i f j | http://tacalhos4test/dlsplayForm.php
ge®
•V
®ИЖ
v g j Переход
Адрес Джон Джэй Смит
Пожалуйста, проверьте поля формы и при необходимости внесите изменения.
Имя:
Второе имя:
Фамилия:
Улица:
Город:
Штат:
вый индекс:
[Джон
|Джэй
[Смит
| ул. Дубов 1234
|Небольшой город
Iю
[88888
Отправить данные
V J . • | - | - • •
I ЩЦ Местная jQroToeS: иитрасать
Рис. 10.2. Форма с адресом покупателя
Листинг 10.1. Сценарий для отображения HTML-формы
<?php
/* Имя файла:
* Описание:
*
*/
displayForm
Сценарий отображает форму и заполняет
ее поля значениями из массива.
echo "<html>
<head><title>Aflpec пoкyпaтeля</title></head>
<body>";
$customer = array("firstName"=>"Джон",
"пис1Мате"=>"Джэй",
"lastName"=>"CMHT",
"street"=>"ул. Дубов 1234",
"с1Ъу"=>"Небольшой город",
"state"=>"ID",
"zip"=>"88888");
$labels = array("firstName"=>"Имя:",
"midName"=>"BTopoe имя:",
"las tName"= >"Фамилия:",
"street"=>"Улица:",
"city"=>"ropofl:",
"state"=>"IUTaT:", 11 zip" =>"ПОЧТОВЫЙ индекс:");
echo "<h2 align='center'>Адрес
{$customer['firstName1]}
{$customer['midName']}
Глава 10. Основы создания Web-приложений 173
{$customer['lastName']}</h2>\n";
echo "<p align='center'>
<b> Пожалуйста, проверьте поля формы и при '
необходимости внесите изменения.</Ь>
<hr>
<form action='processform.php' method='POST'>
<table width='95%' border='0' cellspacing='0'
cellpadding='2'>\n";
foreach($customer as $field=>$value)
{
echo "<tr> <td a l i g n = ' r i g h t ' > <B>{$labels [$field] } < / b r x / t d>
<td><input t y p e = ' t e x t ' name='$field1 size='65 '
maxlength='65' value='(Scustomer[$?ield]}'></td>
</tr>";
}
echo "</table>
<div align='center'><p><input type='submit' value='Отправить
данные' > </px/div>
</form>";
?>
< / b o d y x /html>
Вот некоторые пояснения к коду сценария из листинга 10.1 (файл displayForm.php)
S В начале сценария создается массив $customer, содержащий информа-
цию для вывода в полях формы. В реальных приложениях эти данные 13-
влекаются из базы данных, файла или других источников.
S Затем создается массив $ l a b e l s с именами полей.
S Для обработки данных формы используется сценарий с именем
processform.php.
S Форма представляется в виде таблицы HTML. Таблицы являются важн >IM
элементом HTML. Более подробную информацию о таблицах HTML можно
найти в книге Эда Титтела, Натаньи Пите и Челси Валентайн HTML 4 Аяя
"чайников", 3-е издание, которая вышла в издательстве "Диалектика".
S Проход по массиву $customer осуществляется в сценарии с использованием
оператора f oreach. На каждой итерации цикла выводится строка
таблицы с соответствующим значением из массива $ f i e l d .
С точки зрения обеспечения безопасности следует всегда использовать атризут
maxlength, который определяет максимальное количество символов, котозое
можно ввести в поле формы. Это позволит ограничить допустимый объем информации
и предотвратить опасность ввода опасного кода. Если полученная от
пользователей информация будет храниться в базе данных, то соответствующий
столбец таблицы также должен иметь ширину maxlength.
Добавление в форму раскрывающихся списков, переключателей и флажков
Другие элементы HTML-форм, такие как раскрывающиеся списки, переключатели
и флажки, также можно использовать вместе с переменными. Для этого достаточно встав ить
требуемую переменную в соответствующий дескриптор HTML, а затем вывести его с помо-
774 Часть IV. Стандартные РНР-прможемя
щью функции echo. Ниже приведен пример создания раскрывающегося списка с использованием
переменных РНР.
echo "<select name='dinner' >
<option>$dinnerl</option>
<option>$dinner2</option>
</select>",-
Значения конкретных элементов списка определяются значениями соответствующих переменных.
Например, в переменной $dinnerl может содержаться значение цыпленок,
а в $dinner2 — рыба. После выбора пользователем нужного значения данные формы передаются
для обработки следующему сценарию.
Точно так же можно создавать и переключатели. Например, при использовании приведенного
ниже фрагмента пользователь может выбрать значение цыпленок или рыба:
echo "<input type='radio' name='dinner'
value='$dinnerl'>$dinnerl
<input type='radio' name='dinner'
value='$dinner2'>$dinner2" ;
Флажки позволяют одновременно выбрать больше одного значения. Следовательно, атрибут
name дескриптора <input> должен быть массивом.
echo "<input type='checkbox' name='dinner[]'
value='$dinnerl'>$dinnerl
«cinput type= ' checkbox' name='dinner[]'
value='$dinner2'>$dinner2";
В данном примере введенная информация сохраняется в массиве $dinner. Если выбраны
оба значения, то этот массив будет иметь следующий вид:
$dinner[0]=цыпленок
$dinner[1]=рыба
В сценарии из листинга 10.2 выводится Web-страница, содержащая список для выбора даты.
По умолчанию выбирается текущая дата.
<?php
/* Имя файла: displayDate
* Описание: Сценарий, отображающий три раскрывающихся
* списка для выбора месяца, дня и года.
* По умолчанию выбирается текущая дата.
*/
echo "<html>
<headxtitle>flaTa</titlex/head>
<body>";
/* Создание массива, индексами элементов которого
* являются номера, а значениями - названия месяцев.
*/
$monthName = array(l=> "Январь", "Февраль", "Март",
"Апрель", "Май", "Июнь",
"Июль", "Август", "Сентябрь",
"Октябрь", "Ноябрь", "Декабрь");
$today = Time (),- #текущая дата
echo "<div align='center'><Ь>Выберите дату:</Ь>
<form action='processform.php' method='POST'>\n";
/* Создание раскрывающегося списка для месяца */
$todayMO = dateC'm", $today); Получение текущего месяца из $today
echo "<select name='dateMO1>\n";
Глава 10. Основы создания Web-приложений 175
for ($n=l; $n<=12; $n++)
{
echo "<option value=$n";
if ($todayMO == $n)
{
echo " выбран";
}
echo "> $monthName[$n]\n";
}
echo "</select>";
/* Создание раскрывающегося списка для дня */
$todayDay= dateC'd", $today); #получение текущего дня из $today
echo "<select name='dateDay'>\n";
for ($n=l; $n<=31; $n++)
{
echo " <option value=$n";
if ($todayDay == $n )
{
echo " выбран";
}
echo "> $n\n";
} echo "</select>\n";
/* Создание раскрывающегося списка для года */ $startYr = date("Y", Stoday); #получение текущего года из $today echo "<select name='dateYr'>\n"; for ($n=$startYr; $n<=$startYr+3; $n++)
{
echo " <option value=$n"; if ($startYr •• $n )
{
echo " выбран";
}
echo "> $n\n";
}
echo "</select>\n";
echo "</form>\n";
?>
</body>
</html>
В приведенном сценарии сначала создается массив $monthName, ключами которого являются
номера месяцев, а значениями— их названия. В переменной $ today размещаете
текущая дата.
В остальной части сценария отображаются три раскрывающихся списка формы для вво,1а
трех элементов даты: месяца, дня и года. Названия месяцев в цикле берутся из массиза
$monthName. При этом номер каждого месяца сравнивается с номером текущего меся1;а.
Если эти номера совпали, то в раскрывающийся список добавляется атрибут с флаге м
выбран. Именно этот месяц и используется в списке в качестве элемента по умолчанию.
Аналогичным образом создаются раскрывающиеся списки для выбора дня и года. П^и
этом в качестве значений по умолчанию также выбираются текущий день и год.
На рис. 10.3 представлена форма, созданная с использованием сценария из листинга 10.2,
176 Часть IV. Стандартные РНР-приложения
Э Дата - Microsoft Interne! Explore
Файл Правка Вид Избранное Сервис Справка
СЭ Назад
Адрес: j j g | http://localhost/test/selectDate.php
ч Э ' I S \Ш ,!**5 У"*1 П о и с к V J Избранное &h ' Ча* mm* :u3?mi
Ш\ ^ Переход
Выберите дату:
Январь
Февраль
Апрель >"; 19 Д Ц 2005 Щ
Апрель
Май
Июнь
Июль
Август
Сентябрь
Октябрь
Ноябрь
Декабрь
<йг :Щ Местная интрасеть
Рис. 10.3. Форма для выбора даты
Получение информации
В атрибуте a c t i o n дескриптора <f orm> указывается имя сценария, который будет обрабатывать
данные формы: action=" имя_сценария". Например, в листингах 10.1 и 10.2 использовался
сценарий action="processform.php". После щелчка на кнопке передачи
данных введенная информация передается сценарию, указанному в атрибуте a c t i o n.
Как говорилось в главе 6, переданные сценарию данные можно извлечь из встроенных массивов
РНР. Если при передаче использовался метод POST, то данные будут размещены в массиве
$_POST, а если метод GET — в массиве $_GET. Независимо от выбранного метода передачи
данные можно получить также из массива $_REQUEST. При этом в качестве ключей этих массивов
используются имена полей формы, а значениями являются пользовательские данные.
Рассмотрим пример, в котором информация передается с использованием метода POST,
а в форме содержится следующее поле:
echo "<input type='text' name='firstName'>";
Поскольку именем поля является f irstName, то для получения введенного значения
можно воспользоваться выражением $_POST[ ' f irstName' ] . Точно так же можно получить
данные, которые были введены в форме с использованием раскрывающегося списка или
переключателя. Если в форме содержатся флажки, пользователь может одновременно выбрать
несколько значений. Поэтому соответствующий элемент массива $_POST тоже будет
массивом (т.е. $_POST будет многомерным). Например, если перед обедом было выбрано
оба возможных варианта, цыпленок и рыба (см. предыдущий раздел), то в сценарии РНР
эти значения можно получить следующим образом:
$_POST['dinner'][0] = цыпленок
$_POST['dinner'][1] = рыба
Глава 10. Основы создания Web-приложений 177
Сценарий из листинга 10.3 позволяет отобразить значения всех полей формы, представленной
на рис. 10.2.
Листинг 10.3. Сценарий для вывода всех полей формы
displayFormFields
Сценарий, который выводит информацию,
введенную в полях формы.
<?рпр
/* Script name:
* Description:
*/
echo "<html>
<headxtitle>Aflpec пoкyпaтeля</title></head>
<body>";
foreach ($_POST as $field => $value)
{
echo "$field = $value<br>";
}
?>
</bodyx/html>
POST ПРОТИВ GET
Для передачи данных формы можно использовать два метода; POST и GET. Каждый из этих методов ймёгг
как преимущества, так и недостатки, а, кроме того, информация при использовании каждого из них
передается по-разному.
V Метод GET. При использовании этого метода данные формы передаются путем их добавления к UR.-
адресу вызываемого сценария, предназначенного для обработки информации, напримпр
processform.php?lname=Smith&fname=Goliath
Преимуществами этого метода являются его простота и скорость. Недостатки метода GET связаны с
возможностью передачи лишь ограниченного количества данных, а также с отображением информации в
браузере, что с точки зрения безопасности является весьма нежелательным.
/ Метод POST. При использовании метода POST данные формы передаются в области даннн< j
передаваемых пакетов. Основные преимущества этого метода заключаются в возможности передачи ;
неограниченного количества данных и их большей защищенности. К недостаткам следует отнес "и
небольшую скорость и необходимхть затраты дополнительных усилий разработчиков.
В CGI-программах, отличных от сценариев РНР, полученные из браузера данные необходимо преобразовать и
разместить в переменных. В этом случае гораздо проще воспользоваться методом GET. Именно поэтому
большинство разработчиков его и применяют. Однако в языке РНР все требуемые действия выполняют:?
автоматически. В языке РНР одинаково просто применять оба метода, и G E T И POST. Поэтому с учете м
преимуществ метода P O S T (неограниченное количество данных и большая безопасность) в языке РНР лучи;
использовать именно его.
Этот сценарий можно использовать для обработки данных формы, представленной на
рис. 10.2. Для этого в сценарии displayForm.php (см. листинг 10.1) необходимо измен\хь
атрибут a c t i o n дескриптора <form> на a c t i o n= "displayFormFields .php". Тогда
после щелчка на кнопке Отправить данные будет вызван сценарий displayFoim-
F i e l d s . p h p (см. листинг 10.3), который сгенерирует Web-страницу со следующей информацией:
firstName = Джон
lastName = Смит
street = ул. Дубов 1234
178 Часть IV. Стандартные РНР-приложешя
city = Небольшой город
state = ID
zip = 88888
После выполнения сценария из листинга 10.3 в окне браузера отобразятся значения, которые
были переданы через форму, представленную на рис. 10.2. В большинстве случаев информацию
необходимо не только отображать, но и использовать в условных операторах или
сохранять в базе данных.
Проверка данных
Перед тем как использовать введенную информацию в сценарии, ее необходимо проверить
и удостовериться в том, что получены именно те данные, которые ожидались. Например,
пользователь может оставить незаполненным обязательное поле, ошибиться при вводе,
так что данные не будут иметь никакого смысла, или ввести информацию, которая может нанести
ущерб Web-узлу. Поэтому никогда не стоит доверять информации, введенной пользователями
в форме. Ее всегда необходимо проверять.
Контроль данных
Обычно проверка данных (validating information), введенных в форме, связана с проверкой
на наличие незаполненных полей и на соответствие введенных данных заданному формату.
•S Проверка пустых полей. Можно потребовать, чтобы некоторую информацию
пользователь ввел обязательно, например свое имя и адрес электронной
почты. Если соответствующее поле формы оказалось все же незаполненным,
то форму можно отобразить повторно и сообщить пользователю о том, что
в обязательное поле не было введено никакой информации.
•S Проверка на соответствие заданному формату. Обычно пользователь должен
ввести данные, которые бы соответствовали определенному формату.
Например, почтовый индекс всегда должен содержать пять цифр. Поэтому,
если полученные данные не удовлетворяют заданному формату, пользователю
необходимо указать на допущенные ошибки и сообщить о том, что их нужно
ввести повторно. Например, строку аЬЗ&*хх вряд ли можно использовать
в качестве почтового индекса.
Для того чтобы проверить, было ли заполнено определенное поле, можно воспользоваться
функцией empty () со следующим синтаксисом:
empty($_POST[имя_поля]);
Например, в сценарий можно добавить следующий код:
i f(empty($_POST['имя_поля']))
{
echo "Поле не заполнено";
/ / повторное отображение формы
}
Проверка введенной информации поможет определить ее соответствие нужному формату.
Например, если в качестве почтового индекса (zip) пользователь введет строку 8899776, это
будет явной ошибкой. Она слишком длинна для индекса (содержит больше пяти знаков)
и слишком коротка для формата zip+4 знака (т.е. девять знаков).
Проверка формата данных формы поможет также предотвратить ввод нежелательной информации,
которая может нанести ущерб Web-узлу или базе данных, или кражу информации
у других посетителей. Например, очень нежелательно разрешать ввод дескрипторов HTML,
Глава 10. Основы создания Web-приложений 179
поскольку это может привести к непредсказуемым результатам при их передаче браузеру
других пользователей. (Особенно опасным является дескриптор <script>.)
Проверка данных, введенных в каждом поле формы, поможет избежать многих проблс м.
Однако ее следует выполнять с умом. Необходимо стремиться к выявлению как можно большего
количества некорректной информации, однако при этом нужно обеспечить и возможность
прохождения легитимных данных. Например, при проверке правильности телефоннс го
номера следует контролировать длину введенного числового значения. Тут может возникать
проблема, связанная с тем, что такие номера, как 555-5555 и (888) 555-5555, также являются
допустимыми. Поэтому длину телефонного номера придется увеличить до 14 символов и р гз-
решить ввод дефисов, скобок и пробелов. Как видите, не все так просто, как казалось на первый
взгляд. Одним словом, можно дать один следующий совет: хорошенько подумайте о тс м,
какую информацию вы намерены разрешить вводить пользователям.
Использование регулярных выражений для проверки
пользовательской информации
Для проверки введенной в полях формы информации можно воспользоваться регулярными
выражениями, которые уже рассматривались в главе 7. В этом случае полученные данные
проверяются на соответствие заданному шаблону. Если данные шаблону не соответствуют,
значит, пользователь ввел некорректную информацию и ему придется ввести ее еще раз.
Например, нужно проверить корректность ввода пользователем в поле формы своей фамилии.
При этом вполне логично предположить, что имя может содержать буквы (но не числа),
а также символ апострофа (О'Хара), дефис (Смит-Джонс) и пробел (Ван Дайк). Кроме го-
го, достаточно трудно представить себе фамилию, состоящую более чем из 50 символов.
Поэтому для проверки введенной строки можно воспользоваться следующим кодом:
$last_name = trim($_POST['last_name']);
if ( !ereg("[А-Яа-яА-Za-z' -]{1,50}", $last_name))
{ V
сообщение о необходимости повторного ввода фамилии
}
В приведенном фрагменте для удаления ненужных пробелов в начале и в конце строки
используется функция t r i m ( ) . Затем для проверки соответствия введенной строки заданному
шаблону (регулярному выражению) используется оператор if. Обратите внимание на
операцию ! в условии этого оператора: если введенная строка не соответствует шаблону, то
выполняется последовательность команд в фигурных скобках.
Если в список допустимых символов регулярного выражения, ограниченный
квадратными скобками ([ ]), необходимо добавить дефис (-), его следует разместить
либо в начале, либо в конце этого списка. В противном случае (т.е. при
размещении между двумя символами) дефис будет интерпретироваться как ci ie-
циальный символ, который используется для задания диапазона.
Использование РНРдля создания, отображения формы и проверки ее пол1й
Сценарий из листинга 10.4 позволяет проверить данные, которые были введены в полях
формы. При его первом вызове отображается форма с пустыми полями. После заполнения
полей формы и щелчка на кнопке Отправить данные введенные данные передаются это «у
же сценарию, который выполняет проверку на наличие пустых и неправильно заполненн >ix
полей. Если в процессе проверки были обнаружены ошибки, то отобразится соответствукж ее
сообщение и форма выведется повторно. Если все данные были введены правильно, отобразится
имя пользователя и его адрес.
180 Часть IV. Стандартные РНР-приложенм
В сценарии из листинга 10.4 подключаются два дополнительных файла. Один из. них
предназначен для создания массива, который будет использоваться для построения формы
(листинг 10.5). Второй файл обеспечивает ее отображение (листинг 10.6).
Листинг 10.4, Сценарий проверки всех данных, введенных в полях формы
<?php
/* Имя файла: validateForm
* Описание: Отображает форму и проверяет
* введенную информацию.
*/
include("info.inc"); #6
########################
## Вывод пустой формы ##
########################
if(!isset($_POST['Submit'])) #10
{
include("addressForm.inc");
}
########################################################
## Проверка данных, введенных в форме. Создается ##
## массив пустых или некорректно заполненных ##
## полей. Если при заполнении формы были допущены ##
## ошибки, выводится соответствующее сообщение и ##
## форма отображается повторно. В противном случае ##
## отображается введенная информация. ##
########################################################
else #21
{
foreach($_POST as $field=>$value) #23
{
if(empty($_POST[$field])) #25
{
if($field != "midName")
{
$blanks[$field] = "blank"; #29
}
}
else #33
{
$value = trim($value);
if($field != "zipcode")
{
if (!егед("л[А-Яа-яА-га-гО-9' .-] {1,65}$*-, $value) )
{
$formats[$field] = "bad";
}
}
elseif($field == "zipcode")
{
if(!егед("л[0-9]{5}(\-[0-9]{4})?", $value))
{
$formats[$field] = "bad";
}
}
}
} #51
Глава 10. Основы создания Web-приложений 181
• ### если хотя бы в одном поле допущена ошибка, ###
### выводится соответствующее сообщение и форма ###
### отображается заново ###
if (@sizeof($blanks) > 0 or @sizeof($formats) > 0)#54
{
if (Osizeof($blanks) > 0)
{
echo "<Ь>Вы не заполнили одно или несколько
обязательных полей. Необходимо
заполнить следующие поля: </bxbr>";
foreach($blanks as $field => $value)
{
echo " {$labels[$field]}<br>";
}
}
if (@sizeof($formats) > 0)
{
echo "<b>B одном или нескольких полях содержатся
некорректные данные. Исправьте
информацию в следующих полях:
</b><br>";
foreach($formats as $field => $value)
• {
echo " {$labels[$field]}<br>";
}
}
echo "<hr>";
include("addressForm.inc");
}
else #78
{
### если ошибок не обнаружено, отображаются ###
### введенные имя и адрес . ###
echo "<htmlxhead><title>MMH и адрес
</titlex/headxbody>\n" ;
foreach($_POST as $field=>$value)
{
if($field != "Submit")
{ echo "{$labels[$field]} $value<br>\n";
}
}
echo "</bodyx/html>" ;
}
}
?>
Некоторые строки сценария из листинга 10.4 были пронумерованы, чтобы можно бьло
сделать акцент на ряде следующих важных моментов.
S Строка 6. Это выражение подключает файл i n f o . i n c , который создает
массив $labels, который в сценарии будет использоваться позже. Исходный
код включаемого файла приведен в листинге 10.5. (Более подробно о вклинении
файлов в сценарий см. в главе 8.)
S Строка 10. Оператор i f проверяет, существует ли в массиве $_POST элемент
с индексом Submit. Дело в том, что кнопка, после щелчка на которой даньые
182 Часть IV. Стандартные РНР-приложения
•/
•
У
полей формы передаются серверному сценарию, имеет имя Submit. Поэтому
после щелчка на этой кнопке в массив $_POST будет помещено соответствующее
значение. Именно этот факт и проверяется в условии оператора if. Если
условное выражение оказалось истинным (т.е. элемента Submit не существует),
выполняется блок, в котором подключается файл addressForm. i n c (см. листинг
10.6), предназначенный для вывода формы. Блок оператора i f выполняется
при первом вызове основного сценария, что приводит к отображению
формы с пустыми полями.
Строка 21. С этой строки начинается выполнение else-блока (т.е. если в массиве
$_POST имеется элемент Submit). В этом блоке введенные данные проверяются
на корректность.
•S Строка 23. В этой строке с помощью цикла f oreach выполняется проход по
всем элементам массива $_POST.
Строка 25. В этой строке с использованием оператора i f каждое поле проверяется
на пустоту. Если поле оказалось заполненным, управление передается
в строку 33, с которой начинается проверка формата введенных данных.
Строка 29. В этой строке в массив $blanks добавляются элементы, соответствующие
незаполненным полям (кроме поля Второе Имя, которое является
необязательным и, следовательно, может оставаться пустым).
•S Строка 33. В этой строке начинается блок e l s e , в котором выполняется проверка
формата значений, введенных в полях формы. Все поля, кроме почтового
индекса, проверяются на наличие запрещенных символов. При этом допустимыми
считаются буквы, числа, апостроф, пробел, точка и дефис.
Корректность почтового индекса проверяется в отдельном блоке, поскольку
он должен в точности соответствовать заданному шаблону. Если оказалось,
что в каком-то из полей формы была введена неверная информация, соответствующий
элемент добавляется в массив $f ormats.
S Строка 51. В этой строке завершается проверка правильности заполнения полей
формы. В этот момент в сценарии существуют два массива, $blanks
и $ formats, в которых содержится информация о результатах проведенной
проверки. Если никаких ошибок обнаружено не было, то массивы $blanks
и $ formats не создаются.
•S Строка 54. В этой строке с использованием оператора i f проверяется, были
ли при вводе данных в поля формы допущены какие-либо ошибки. Для этого
проверяется, существуют ли массивы $blanks и $?ormats. Если хотя бы
один из этих массивов был создан, выводится сообщение об ошибке и форма
отображается повторно.
S Строка 78. Этот блок e l s e выполняется в том случае, если при вводе данных
не было допущено ошибок. В результате его выполнения отобразится вся информация,
введенная пользователем в форме.
Обратите внимание, что сценарий из листинга 10.4 является достаточно гибким и позволяет
обрабатывать информацию, введенную в любой форме (за исключением проверки данных
в строках 33-50). Однако эти строки можно без особых проблем модифицировать. Остальная
же часть сценария останется без изменений.
Глава 10. Основы создания Web-приложений 183
В листинге 10.5 приведен исходный код первого файла, включаемого в сценарий из листинга
10.4. В этом сценарии создается массив, используемый для отображения формы и сообщений
об ошибках.
<?php
/* Имя файла: info.inc
* Описание: создает массив имен для использования
* в форме.
*/
$label's = array( "f irstName"=>"MMfl: ",
"midName"=>"Второе имя:",
"lastName"=>"Фамилия:",
"street"=>":»OiHua: " ,
"city"=>"ropofl:",
"state"=>"lIlTaT:",
"z ipcode"=>"Почтовый индекс:");
?>
В листинге 10.6 приведен исходный код сценария, предназначенного для отображения
формы. Он основывается на сценарии из листинга 10.1, который выводит в окне браузера
форму, представленную на рис. 10.2.
< ?php
/* Имя файла: addressForm.inc
* Описание: Сценарий для отображения формы.
*/
echo "<html>
<headxtitle>Aflpec покупателя*;/titlex/head>
<body>";
echo "<p align='center'>
<form action='validateForm.php' method='POST'>
<table width='95%' border='0' cellspacing='0'
cellpadding='2'>\n";
foreach($labels as $field=>$value)
{
if(isset($_POST[$field])) #13
{
$value = $_POST[$field];
} •
else
{
$value = "";
}
echo "<trxtd align= ' right' >{$labels [$field] }</brx/td>
<tdxinput type= ' text' name='$field' size='65'
maxlength='65'
value='$value'> </td> </tr>";
}
echo " </table>
<div align='center'>
<pxinput type='Submit' name= ' Submit'
184 Часть IV. Стандартные РНР-приложеьия
value= ' Отправить данные ' ></px/div>
</form>";
?>
</bodyx/html>
Обратите внимание на блок i f - e l s e , который начинается в строке 13. В нем устанавливаются
значения, отображаемые в полях формы. При первом отображении формы массив $_POST
еще не существует, поэтому переменной $value присваивается пустое значение. В противном
случае этой переменной присваивается значение, которое ранее было введено пользователем
в соответствующем поле формы. Это значение используется при повторном выводе формы.
«ajj^^ Обратите внимание на строку, в которой создается кнопка Submit:
f C°J1 <pxinput type= ' Submit' name= ' Submit'
^^^r value= ' Отправить данные ' > < / p x / d i v>
При передаче данных сценарию значение value будет добавлено в массив $_POST.
В форме можно использовать две таких кнопки, с одинаковыми именами, но разными значениями,
и выполнять действия в зависимости от того, на какой кнопке щелкнул пользователь.
В этом случае пригодится оператор i f следующего вида:
if($_POST['Submit'] == "Отправить данные").
На рис. 10.4 показана форма, в которой пользователь случайно ввел свое имя во второе
поле и указал несуществующий почтовый индекс. При этом на Web-странице выведены два
сообщения об ошибке. Первая ошибка связана с оставшимся пустым полем для ввода имени,
а вторая свидетельствует о вводе неправильного почтового индекса.
Вы не заполнили одно нлн несколько обязательных полги. Необходимо заполнить следующие поля:
Имя:
В одном нлн нескольких полях содержатся некорректные данные. Исправьте информацию р. следующих полях:
Второе имя:
Фамилия
Улица:
Город
Почтовый индекс:
Имя:[
Второе имя: |Мэри
Фамилия: [Контрори
Улица: (КантркЛэйн 1234
Город: [Странажеланий^
Штат: [ЬТГ~
Почтовый индекс: 888-88
Отправить данные
ф|Готсео *й| Местная интрасать
Рис. 10.4. Результат обработки формы, в которой осталось не заполненным одно обязательное поле,
а в другое поле были введены некорректные данные
Глава 10. Основы создания Web-приложений 185
Очистка данных
Тщательной проверки данных зачастую бывает вполне достаточно, чтобы предотвратить
ввод нежелательной (опасной) информации. Можно проверить формат введенных данных
(например, почтового индекса или телефонного номера) или ограничить список допустимых
символов буквами и числами. Однако иногда необходимо предоставить возможность ввода всех
символов из числа возможных, включая математические символы или HTML-код. Например, а ;е-
нарий для доски объявлений должен разрешать пользователям оставлять сообщения любого видг.
Если жестких ограничений на пользовательские данные установить нельзя, злонамеренные
взломщики смогут ввести в поля формы опасную информацию. Например, с использо1 а-
нием дескриптора < s c r i p t> можно передать на сервер исполняемый сценарий. От того, как
эта информация будет обработана, зависит, сможет ли злоумышленник запустить свой сцеь :а-
рий или загрузить его на компьютеры других посетителей Web-узла.
Для удаления опасной информации в языке РНР предназначены две полезных функции.
S s t r i p _ t a g s (). Эта функция позволяет удалить из текста все дескрипторы,
хотя можно указать, какие из них следует оставить.
S htmlspecialchars (). Эта функция позволяет преобразовать некоторое
специальные символы HTML в другой формат. При этом они будут отображаться
без учета их специального назначения. Например:
• < преобразовывается в <
• > преобразовывается в >
• & преобразовывается в &апур.
Удаление из полученной информации всех дескрипторов позволит существенно повыс1 ггь
безопасность. Например, для удаления всех дескрипторов можно воспользоваться выражением
$last_name = strip_tags($last_name);
При вызове функции s t r i p _ t a g s ( ) интерпретатор РНР выполнит поиск в строке
$last_name символа начала дескриптора < и удалит все символы, вплоть до символа > \ш
конца строки. При этом можно указать, какие дескрипторы удалять не следует:
$last_name = s t r i p _ t a g s ($last_name, "<bxi>");
В этом случае в строке $last_name будут удалены все дескрипторы, кроме <Ь> и <i>.
Однако в некоторых случаях символы < и > не нужно связывать с дескрипторами, например
при их использовании в качестве символов математических операций. Их можно пре эб-
разовать в такие символы, которые не будут интерпретироваться как дескрипторы HTML.
Для этого необходимо воспользоваться следующей функцией h t m l s p e c i a l c h a r s ():
$message = htmlspecialchars($message);
Теперь нужно разобраться, чем же отличаются друг от друга функции s t r i p _ t a g s ()
и h t m l s p e c i a l c h a r s (). Пусть имеется переменная $message, в которой содержигся
следующее значение:
Используйте дескрипторы <?php ?> для размещения операторов РНР.
Для удаления ненужных дескрипторов воспользуемся функцией s t r i p _ t a g s ():
$message = strip_tags($message);
echo $message;
В результате получим:
Используйте дескрипторы для размещения операторов РНР.
186 Часть IV. Стандартные РНР-приложеиия
Однако для достижения этой же цели можно воспользоваться и функцией htmlspec
i a l c h a r s ( ) :
$message = htmlspecialchars($message);
echo $message;
В этом случае получим следующий результат:
Используйте дескрипторы <?php ?> для размещения операторов РНР.
Причем в браузере эта строка отобразится следующим образом:
Используйте дескрипторы <?php ?> для размещения операторов РНР.
т.е. исходная строка будет отображаться без ошибок. Это связано с тем, что символы < и > не
интерпретируются как относящиеся к дескрипторам, и соответственно код РНР не выполняется.
Для удаления ненужной информации можно воспользоваться также функцией
t r i m ( ) . Зачастую в начале или в конце строки пользователи случайно вводят
пробелы. Позже такие данные могут быть неправильно обработаны, например
при сравнении с заданным шаблоном. Для удаления ненужных пробелов как раз
и предназначена функция t r im (), которую можно вызвать следующим образом:
$last_name = trim($last_name);
Глава 10. Основы создания Web-приложений 187
Глава 11
Другие виды Web-приложений
В э/Яой главе...
> Передача информации между страницами
> Использование данных cookie
> Скрытые поля HTML-форм
> Сеансы РНР
> Использование JavaScript в сценариях РНР
щ амые простые Web-приложения получают информацию от пользователей через НПЛЬ-
V** формы, а затем используют ее для вывода, хранения или проверки условных выражи :ий.
(Несколько примеров таких приложений рассматривалось в главе 10.) Однако Web-приложения
могут быть и гораздо более сложными. Так, торговая тележка должна "уметь" собирать и отображать
различную информацию, следить за заказом клиента, вычислять сумму покупки, наг оги
и стоимость доставки, проверять состояние кредитной карточки, а также выполнять множес тво
других действий. Такое приложение должно состоять из нескольких сценариев, в которых
используются одни и те же данные. Кроме того, разработчики Web-приложения дол>сны
обеспечить возможность приема от пользователей целых файлов, а не только данные формы.
В этой главе рассматриваются фундаментальные вопросы, связанные с разработкой сложных
Web-приложений.
Независимость Web-cinfiaHUk,
Web-страницы являются независимыми друг от друга. После того как пользователь щелкнет
на ссылке, Web-сервер передает браузеру новую страницу. При этом браузеру о предыдущей
странице уже ничего не известно. Она может оказаться даже первой Web-страницей в мировой
истории. При использовании статических Web-страниц, которые пользователь может просто
просматривать в браузере, подобная независимость нисколько не мешает. Однако в большинстве
динамических Web-приложений информацией нужно обмениваться между страницами. Например,
имя пользователя можно ввести на одной странице, а затем вывести его на другой.
В следующих нескольких разделах рассматриваются различные способы передачи данных
между страницами.
Ле^емещение межуц ан[юницами Web-t/cua
Большинство Web-узлов состоит из нескольких страниц. Так, на статических Web-^злах
переход от одной страницы к другой осуществляется с помощью ссылок (иногда реализс ванных
в виде кнопки), на которых щелкают пользователи. Таким образом, можно путешес тво-
вать по узлу и искать требуемую информацию. В динамических Web-приложениях для i :epe-
хода между страницами можно использовать и другие методы, основные из которых
приведены ниже.
•f Ссылки. На новую страницу пользователь может перейти, щелкнув на ссылке.
•/ Использование форм. Формы позволяют перемещаться между страницами
щелчком на кнопке Submit.
S Перемещение пользователей. В языке РНР имеется функция header(),
с использованием которой пользователь может перейти на новую страницу
без выполнения каких-либо действий.
Все эти методы более подробно рассматриваются в следующих разделах.
Вывод ссылок
В языке РНР можно воспользоваться функцией echo и просто вывести ссылку HTML
(точно так же, как и другой фрагмент HTML). После этого ее можно использовать для перехода
на новую страницу:
echo "<a href='newpage.php';>Новая страница</а>";
Использование форм
Для перехода на новую страницу можно использовать и формы (см. главу 10). Дескриптор
<form> позволяет задать сценарий, который будет обрабатывать информацию, введенную
пользователем. После щелчка на кнопке Submit этому сценарию будут переданы данные
формы и отобразится новая Web-страница.
Безусловно, для перехода на новую страницу совсем необязательно использовать форму
для сбора информации. Можно воспользоваться пустой формой с кнопкой, после щелчка на
которой пользователь переместится на новую страницу. Например, можно создать кнопку
Cancel (Отменить) или Next (Следующая) с использованием дескрипторов <form>
и <input>. Тогда после щелчка на этой кнопке будет выполнен переход на страницу, адрес
которой указан в атрибуте a c t i o n дескриптора <f orm>.
: Функции, которые следует вызывать первыми
В РНР существуют функции, которыми можно воспользоваться только до начала генерации всего остального
содержимого Web-страницы. К таким функциям относятся h e a d e r { ) , s e t c o o k i e () и s e s s i o n ( ) . Если
их вызвать после завершения формирования содержимого страницы, будет выведено следующее сообщение:
Warning: Cannot modify header information - headers already sent by
(output started at /test.php:2) in /test.php on line 3
(Предупреждение: Нельзя изменить заголовок — заголовки уже
отправлены (/test.php:2) в файле /test.php в строке 3)
Как можно заметить, в этом сообщении указано имя файла и строка, в которой была сгенерирована ошибка.
Вполне возможно, что сообщение об ошибке выведено не будет, а страница вообще не появится в окне браузера.
(Это зависит от используемого режима вывода ошибок в РНР; см. главу 4.) Обработка следующего фрагмента
кода приведет к возникновению ошибки, поскольку вывод заголовка расположен после раздела HTML:
<html>
<head><title>TecTMpoBaHne функции header()</title></head>
:<body>
<?php
header("Location: http://janetscompany.com");
?>'
</bodyx/html>
Как можно заметить, перед вызовом функции header () расположено несколько строк кода HTML.
Следующий фрагмент кода является работоспособным, однако не имеет особого смысла. Поскольку код
Глава 11. Другие виды Web-приложений 189
• HTML расположен после инструкции PHP, предназначенных для вывода заголовка, то перед его отображением
будет выполнен переход на другую страницу.
<?php
header("Location: http://janetscompany.com");
. ?>
<html>
: <head><title>TecTMppBaHMe функции header()</title></head>
<body>
</body>
j. </html>
; Следующий фрагмент приведет к генерации сообщения об ошибке:
| <?php
header("Location: http://company.com");
I ?>
i <html>
I <head><title>TecTHpoBaHHe функции header()</titlex/head>
[ <body>
</body^</html>
| Причину вывода сообщения об ошибке обнаружить не так то просто. Однако при внимательном анализе перед ;
! открывающим дескриптором <?php можно заметить символ пробела. Этот символ также отображается на .
i Web-странице, и, следовательно, функция h e a d e r ( ) вызывается после некоторого выражения (хотя оно и .
[ является пробелом). Это типичная ошибка начинающих разработчиков, на обнаружение которой Мохю j
! потратить достаточно много времени.
Перемещение пользователей
Язык РНР предоставляет метод, с использованием которого можно перейти на другую
страницу вообще без щелчка на ссылке или кнопке. Это позволяет осуществить функция
header () со следующим синтаксисом:
header("Location: URL");
С помощью этой функции Web-серверу можно передать сообщение вида Location:
URL. В ответ браузеру будет передан файл, расположенный по указанному URL-адресу. Н иже
приведено несколько примеров корректного использования функции header ().
header("Location: newpage.php");
header("Location: http://company.com/catalog/catalog.php");
Как уже отмечалось выше, функция header () имеет одно важное ограничение: она
должна вызываться перед генерацией какого-либо содержимого страницы. Нельзя сначала
поместить код HTML, а после него — где-то в середине сценария — вызов функ ции
header (). Эти же ограничения касаются и функций s e t c o o k i eO и s e s s i o n ()
(см. врезку "Функции, которые следует вызывать первыми").
Однако, несмотря на все эти ограничения, функция header () оказывается чрезвычайно
полезной. Она предоставляет единственный способ перехода на новую страницу без вмешательства
пользователя. Другими словами, функцию header () можно использовать для вывода
различных страниц для разных пользователей. Рассмотрим такой пример:
<?php
if ($typeAcct == "admin")
{
header("Location: AdminPage.php");
}
else
{
190 Часть IV. Стандартные PHP-приложения
header("Location: SiteHomePage.php");
}
?>
В приведенном фрагменте для администратора выводится специальная страница администрирования,
а для других пользователей — главная страница Web-приложения. Перед функцией
header () можно использовать сколько угодно функций РНР, которые не связаны
с формированием HTML-кода Web-страницы. Однако размещение перед вызовом функции
header () какого-либо HTML-кода приведет к ошибке.
71е/геме1цение с/ашшх межс/ц сйг/ганицаиш
При перемещении пользователя между страницами Web-приложения может возникнуть
ситуация, когда информация, введенная на одной странице, может понадобиться на другой
странице. Для реализации этого требования на языке РНР можно воспользоваться несколькими
способами.
•S Добавление информации к URL-адресам. В этом случае требуемую информацию
можно добавить к URL-адресу новой страницы. Этот подход оказывается
наиболее эффективным только при передаче небольшого количества данных.
S Хранение информации с помощью данных cookie. Для передачи информации
между сценариями можно воспользоваться данными cookie, которые представляют
собой множество пар "переменная-значение" (имя_переменной=значение).
При этом информация сохраняется в клиентской части приложения, т.е. на
локальном компьютере пользователя. После того как данные cookie были сохранены,
ими можно воспользоваться с любой Web-страницы. Существенный
недостаток такого подхода заключается в возможности отключения режима
использования данных cookie в клиентском браузере.
•/ Передача данных с использованием HTML-форм. Для передачи информации
между различными сценариями Web-приложения могут использоваться
HTML-формы. После щелчка на кнопке Submit данные из полей формы будут
переданы серверному сценарию. Такой подход оказывается весьма полезным,
если необходимо взаимодействовать с пользователями.
*/ Использование сеансов. Начиная с версии 4, язык РНР позволяет реализовать
поддержку пользовательских сеансов и всю необходимую информацию
хранить на сервере. Доступ к этой информации можно получить из любого
сценария (Web-страницы). Этот подход оказывается особенно эффективным
при просмотре большого количества Web-страниц.
В следующих разделах каждый из упомянутых подходов рассматривается более подробно.
Добавление информации к URL-адресу
Один из наиболее простых способов передачи информации между сценариями заключается
в добавлении необходимых данных к URL-адресу. Для этого необходимо воспользоваться
следующим синтаксисом:
переменная^значение
В этом случае переменная— это имя переменной (без использования символа $),
а значение — ее значение. Пару переменная=значение можно добавить к адресу URL после
символа ?. Например:
Глава 11. Другие виды Web-приложений 191
S <a href= " nextpage. р!тр?аде=14">перейти на следующую
страницу</а>
•f header("Location: nextpage.php?age=14") ;
S <form action="nextpage.php?age=14" method="POST">
Во всех трех примерах при переходе на новую страницу nextpage. php передается переменная
$аде со значением 14. Строка аде=14 добавляется в конец URL-адреса сразу после
знака ?.
При передаче в адресе URL нескольких пар "переменная-значение" они отделяются друг
от друга амперсантом (&). Например:
<form action="nextpage.php?state=CA&city=Moлл" method="POST">
Доступ ко всем переменным, передаваемым в строке URL, можно получить через всгро-
енный массив $__GET. В сценарии nextpage. php из предыдущего примера для отобрг .женил
переданных значений можно воспользоваться выражением
echo "{$_GET['city']}, {$_GET['state']};
и получить следующий результат:
МОЛЛ, СА
Эти же данные можно извлечь и из массива $_REQUEST. Например:
echo "{$_REQUEST['city']}, {$_REQUEST['state']};
С использованием URL удобно передавать лишь небольшое количество информаши.
Кроме того, такой подход обладает и рядом других недостатков (в том числе связанных
и с обеспечением безопасности), среди которых следует выделить следующие.
</ Общедоступность. Адрес URL всегда отображается в адресной строке окна
браузера. Естественно, что передаваемая информация также будет видна
пользователю. Например, если требуется передать пароль, вряд ли стоил использовать
для этого URL-адрес.
S В URL-адресе можно передавать любую информацию. Рассмотрим ситуацию,
когда пользователь зашел на Web-узел с ограниченным доступом.
В этом случае к URL-адресу добавляется строка auth=yes (свидетельствующая
о том, что аутентификация завершилась успешно). При этом проверка
равенства $_GET[' auth1 ] =yes будет выполняться на каждой странице.
Лишь при истинности этого условия будет осуществляться переход на
новую страницу. Однако любой пользователь может ввести в окне 6payjepa
URL-адрес h t t p : //www.имя-узла, com/page.php?auth=yes и без ввода
каких-либо данных аутентификации получить доступ к страницам с ограниченным
доступом.
•S Адрес URL можно сохранить в браузере. Пользователь может сохранить
в браузере закладку с URL-адресом, а вместе с ним и добавленную к нему информацию.
S Ограниченная длина адреса URL. Для разных браузеров и их версий максимальная
длина URL-адреса всегда конечна (хотя и различается). Если необходимо
передать большое количество информации, то объективные ограничения,
наложенные на длину адреса URL, могут не позволить этого сделать.
192 Часть IV. Стандартные РНР-приложения
Передача информации с помощью данных cookie
Информацию, которую необходимо передавать от страницы к странице, можно сохранить
как данные cookie. Эти данные представляют собой набор пар "переменная-значение"
(переменная=значение) и очень напоминают фрагменты, добавляемые к URL-адресу. Особенность
данных cookie заключается в том, что они сохраняются браузером на пользовательском
компьютере и позже могут использоваться сценариями.
На первый взгляд, данные cookie позволяют решить все проблемы, связанные с обменом
данных между отдельными компонентами (страницами) Web-приложения. Их необходимо хранить
в клиентском браузере и использовать по мере необходимости. Сохранив данные cookie
один раз, их можно использовать при последующих посещениях данной Web-страницы. Однако,
как легко догадаться, не все так просто. Дело в том, что режим использования (или неиспользования)
данных cookie в клиентском браузере полностью определяется пользователем.
Другими словами, в любой момент он их может удалить или вообще от них отказаться. Большинство
посетителей Web-узлов зачастую именно так и поступают. Далеко не все из них рады
тому, что кто-то сохраняет у них на компьютере свою информацию. Подобная реакция вполне
объяснима. Приведенные выше рассуждения и факты существенно сужают область применения
механизма cookie. Если основу функционирования Web-приложения составляют данные cookie
и пользователь отключил режим их использования, то оно будет работать некорректно.
Изначально данные cookie предназначались для хранения небольшого количества данных
в течение короткого промежутка времени. Если для данных cookie не указать время их жизни,
то они будут удалены сразу же после завершения работы с Web-приложением. Несмотря на
то что данные cookies достаточно полезны, следует хорошенько подумать, прежде чем принять
решение о необходимости их использования. И вот по каким причинам.
•S Возможность отключения режима использования данных cookie. До тех
пор пока нет полной уверенности в том, что все пользователи разрешают использование
данных cookie (или согласны установить этот режим работы
браузера), возможно возникновение проблем и нарушение корректного функционирования
Web-приложения.
S Язык РНР предоставляет гораздо более эффективные средства. Начиная
с версии 4 языка РНР, механизм поддержки сеансов обеспечивает возможность
хранения данных на протяжении всего сеанса (session) работы пользователя —
другими словами, до тех пор, пока он остается на Web-узле. При этом информации
хранится на сервере, так что пользователь на это никак не может повлиять.
•S Информацию можно хранить в базе данных. Если имеется доступ к базе
данных, которая позволяет как хранить, так и извлекать информацию, то эта
возможность гораздо лучше, чем использование данных cookie. Пользователи
не смогут удалить информацию из базы данных.
Манипулирование данными cookie
Для того чтобы сохранить данные cookie, следует воспользоваться функцией s e t -
cookie (), которая имеет следующий синтаксис:
setcookie("переменная", "значение");
Параметр переменная представляет собой имя переменной (без символа $), а
значение — ее значение. Это выражение будет сохраняться до тех пор, пока пользователь
не покинет Web-узел. Рассмотрим следующий пример, в котором с помощью данных cookie
на клиентском узле сохраняется выражение state=CA:
s e t c o o k i e ( " s t a t e " , "СА");
Глава 11. Другие виды Web-приложений 193
К данным cookie можно обратиться с помощью встроенного массива $_СООК1Е. Например,
можно вывести выражение
echo "Вы живете в штате {$_COOKIE['state']} ";
В результате будут получены следующие данные:
Вы живете в штате СА
Следует отметить, что данные cookie недоступны на той странице, на которой они были
установлены. Для получения к ним доступа нужно заново отобразить текущую страницу или
перейти на новую.
Установка времени жизни данных cookie
В случае необходимости можно задать время жизни данных cookie. Для этого преднаша-
чена функция s e t c o o k i e () с синтаксисом
setcookie("переменная", "значение", время-жизни);
Параметр время-жизни определяет время, по истечении которого данные cookie будут
удалены. Обычно это значение вычисляется с помощью функции t i m e () или mktime ( ).
•S t i m e ( ) . Эта функция возвращает текущее значение даты и времени. Для задания
времени жизни данных cookie к результату функции t i m e ( ) следует
прибавить соответствующее значение в секундах. Например:
s e t c o o k i e ( " s t a t e " , "СА", time ()+3 600) ; #удаление данных:
через 1 час
s e t c o o k i e ( " N a m e " , $Name, t i m e ( ) + ( 3 * 8 6 4 0 0 ) ) #удаление
данных через 3 дня
S mktime(). Эта функция позволяет преобразовать указанное значение дггы
и времени в форму, которая понятна компьютеру. Для этого требуемую .вату
необходимо представить в следующем виде: часы, минуты, секунды, ме<яц,
день и год. Если какое-то значение будет пропущено, по умолчанию используется
значение, соответствующее текущему моменту времени. Ниже npi- ведено
несколько примеров установки времени жизни данных cookie с помощью
функции mktime ( ).
s e t c o o k i e ( " s t a t e " , "СА", m k t i m e ( 3 , 0 , 0 , 4 , 1 , 2 0 0 3 ) );
#удаление c o o k i e 1 апреля 2003 года в 03:00
s e t c o o k i e ( " s t a t e " , "СА", m k t i m e ( 1 3 , 0 , 0 , , , ) ) ; #удаление
данных сегодня в 13:00
Для удаления данных cookie соответствующей переменной необходимо присвоить пустое
значение. Это можно осуществить двумя способами:
setcookie("имя") ;
setcookie("имя", " " ) ;
Однако функция s e t c o o k i e () имеет одно существенное ограничение. Она должна iназываться
до генерации какой-либо части Web-страницы. Невозможно задать данные cookie
где-то в середине сценария после того, как некоторая часть страницы уже была сформирована.
Более подробную информацию по этому вопросу см. выше, во врезке "Функции, котор ые
следует вызывать первыми".
Передача информации с помощью HTML-форм
Один из стандартных способов передачи информации между страницами заключается
в использовании форм. Дело в том, что HTML-формы могут содержать кнопку Submit. После
щелчка на этой кнопке введенная в поля формы информация передается сценарию, UP.L-
194 Часть IV. Стандартные РНР-приложения
адрес которого задан в дескрипторе <f orm>. Для описания формы используется следующий
общий синтаксис:
<form action="processform.php" method="POST">
поля формы
<input type="submit" value="строка">
</form>
Обычно формы используются для получения информации от пользователей и передачи ее
следующей странице (сценарию). (Более подробно об этом см. в главе 10). Однако формы могут
оказаться полезными и при передаче данных другого вида.
Поля, которые не отображаются на Web-странице, но используются при передаче данных,
называются скрытыми (hidden fields). Их можно использовать как вместе с обычными полями,
так и отдельно от них. После щелчка на соответствующей кнопке значения скрытых полей передаются
следующей странице. В следующем примере после щелчка на кнопке Следующая
страница регистрационные данные пользователя будут переданы странице nextpage. php:
<?php
$acct = "admin";
echo "<form action='nextpage.php' method='POST'>
<input type='hidden' name='acct' value='$acct'>
<input type='submit' value='Следующая страница'>
</form>\n";
?>
Ha Web-странице отображается только кнопка Следующая страница, причем пользователю
не нужно вводить никакой информации. После щелчка на этой кнопке вызывается
сценарий nextpage. php, а значение скрытого поля сохраняется в элементе массива
$_POST [' a c c t ' ]. Такой подход позволяет передавать требуемую информацию между
страницами Web-узла. Например, приведенный фрагмент можно включить в сценарий, предназначенный
для отображения различных видов товаров. Тогда после щелчка на кнопке
Следующая страница регистрационные данные пользователя будут переданы новой странице
и, таким образом, окажутся доступными для соответствующего сценария.
Использование сеансов РНР
Сеанс (session) можно определить как промежуток времени, в течение которого пользователь
взаимодействует с Web-приложением. В течение одного сеанса посетители Web-узла
обычно просматривают большое количество страниц, и очень часто требуется иметь доступ
к одной и той же информации на каждой из них. Начиная с версии 4.0, язык РНР позволяет
реализовать такой подход, основанный на механизме поддержки сеансов.
Как работают сеансы РНР
Язык РНР предоставляет средства для создания сеансов и хранения связанных с ними переменных.
После создания сеанса значения установленных переменных становятся доступными
на любой странице (или в сценарии) Web-приложения. При открытии сеанса интерпретатором
РНР выполняются следующие действия.
1. Сеансу присваивается уникальный идентификатор (session Ш number). Обычно идентификатор
представляет собой очень длинную строку, которая является уникальной для
конкретного пользователя (например, 523afal5f4a8e05e95241481c0cbc71e). Такую
строку подобрать практически невозможно. В окружении РНР это значение хранится
в переменной $PHPSESSID.
2. Все необходимые переменные сеанса сохраняются в файле, который размещается на
сервере. Причем имя файла совпадает с идентификатором сеанса. Каталог, в котором
Глава 11. Другие виды Web-приложений 195
хранятся файлы сеансов, определяется директивой session. save_path фаЗла
php. i n i . Причем этот каталог должен быть создан предварительно.
3. Интерпретатор РНР передает идентификатор сеанса каждой странице. Если у пользователя
активизирован режим использования данных cookie, то передача требуемых
данных между сервером и клиентским браузером осуществляется с использованием
этого механизма. В противном случае работа модуля РНР определяется значением директивы
t r a n s - s i d конфигурационного файла p h p . i n i . (Более подробно этот механизм
описывается ниже, в разделе "Поддержка сеансов при отключенном режиме
использования данных cookie".)
4. Файл с данными сеанса доступен для всех сценариев в рамках этого сеанса. При э гам
переменные хранятся также в массиве $_SESSION.
В версиях РНР 4.1.2 и более ранних директива t r a n s - s i d доступна только в том
случае, если модуль РНР скомпилирован с параметром - - e n a b l e - t r a n s - s id
Открытие и закрытие сеансов
Сеанс нужно открывать в начале каждой страницы, используя функцию s e s s i o n _ s t a r t ().
Эта функция сначала проверяет, был ли ранее создан сеанс. Если да, то выполняется устанс вка
переменных сеанса. В противном случае создается новый сеанс с уникальным идентификатором.
Поскольку механизм поддержки сеансов во многом зависит от режима поддержки дан!ых
cookie, то на использование функции s e s s i o n _ s t a r t () накладываются те же ограничения. Другими
словами, ее нужно вызывать до вывода какой-либо информации на Web-странице. Более i юд-
робно этот вопрос рассматривался во врезке "Функции, которые следует вызывать первыми".
Интерпретатор РНР может автоматически добавлять функцию session_start: ()
в начале каждой серверной страницы. Для этого необходимо внести соответств ую-
щие изменения в конфигурационный файл php. i n i , а именно: задать для дирегги-
вы s e s s i o n . a u t o _ s t a r t значение 1. Для того чтобы внесенные изменения
вступили в силу, нужно перезапустить Web-сервер. После этого добавлять функцию
s e s s i o n _ s t a r t () в начало каждой страницы уже не понадобится.
Зачастую необходимо, чтобы Web-узлы посещали только пользователи с корректным
идентификатором и паролем. Для каждого из них создается свой собственный сеанс. Однако
после завершения работы необходимо обеспечить закрытие текущего сеанса работы. Для : гго-
го предназначена функция session_destroy ().
Эта функция удаляет всю информацию, хранящуюся в переменных сеанса. С этого момента
идентификатор сеанса больше не будет передаваться между страницами. Однако следует
заметить, что на текущей странице эти переменные по-прежнему будут доступны. Цля
их полного удаления предназначена функция
unset($переменная1, $переменная2, ...);
Использование сеансовых переменных
Для того чтобы сохранить переменную в рамках сеанса и обеспечить ее доступность на
других Web-страницах, нужно сохранить ее в массиве $_SESSION следующим образом:
$_SESSION['имя_переменной'] = "Джон Смит";
При открытии сеанса на другой странице к предварительно сохраненным значениям можно
обратиться через массив $_SESSION.
196 Часть IV. Стандартные РНР-приложемя
Для удаления переменной в любой момент можно воспользоваться функцией u n s e t ( ):
unset($_SESSION['имя_переменной'] );
В следующих двух сценариях показано, как с помощью механизма сеансов передавать
информацию между страницами. Сценарий из листинга 11.1 отображает первую страницу,
а сценарий из листинга 10.2 — вторую.
<?php
/ * Имя сценария: sessionTestl.php
* Описание: создает сеанс и сохраняет связанные
* с ним переменные.
*/
s e s s i o n _ s t a r t ( ) ;
$_SESSION['session_var'] = "тестирование";
?>
<html>
<headxtitle>TecTOBaH страница 1 ceaHca</titlex/head>
<body>
<р>Тестирование свойств сеансов.
<form action="sessionTest2.php" method="POST">
<input type="text" name="form_var" value="тестирование">
<input type="submit" value="Перейти на следующую страницу">
</form>
</body>
</html>
В приведенном сценарии с помощью функции s e s s i o n _ s t a r t () создается сеанс с одной
переменной session__var. На странице содержится также форма с одним текстовым
полем и кнопкой Перейти на следующую страницу, после щелчка на которой вызывается
сценарий s e s s i o n T e s t 2 .php.
<?php
/ * Имя сценария: sessionTest2.php
* Описание: получение данных текущего сеанса.
*/
session_start();
?>
<html>
<headxtitle>TecTOBaH страница 2 ceaHca</titlex/head>
<body>
<?php
$session_var = $_SESSI0N['session_var'];
$form_var = $_POST['form_var'];
echo "session_var = $session_var<br>\n";
echo "form_var = $form_var<br>\n";
?>
</body>
</html>
Этот сценарий отображает значения переменных, переданных из предыдущего сценария
( s e s s i o n T e s t l . php).
Глава 11. Другие виды Web-приложений 197
Если пользователь загрузил в браузер страницу s e s s i o n T e s t l .php и щелкнул на кнопке
Перейти на следующую страницу, то будет получен следующий результат:
session_var = тестирование
form_var = тестирование
Как можно увидеть, значения обеих переменных, s e s s i o n _ v a r (связанная с сеансом)
и form_var (из поля формы), можно получить из встроенных массивов $_SESS:ON
и $_POST соответственно.
Поддержка сеансов при отключенном режиме использования данных cookie
Зачастую пользователи отключают в браузере режим использования данных cookie. Лри
использовании механизма поддержки сеансов модуль РНР проверяет, допускает ли клиентский
браузер использование данных cookie. Если соответствующий режим включен, выполняются
следующие действия.
•S Переменной $PHPSESSID присваивается значение идентификатора сеанса.
S Данные cookie используются для передачи $PHPSESSID между сценариями
или страницами.
Если клиентский браузер запрещает использовать данные cookie, то модуль РНР ф;тос-
ционирует по-другому.
•S Создается константа с именем SID, в которой содержится пара "переменгая-
значение" вида PHPSESSID=идентификатор-сеанса.
S После этого использование идентификатора сеанса определяется значением
директивы t r a n s - s i d в конфигурационном файле p h p . i n i . Если эта директива
включена, то идентификатор сеанса передается между страниц ши
или сценариями, в противном случае — нет.
По умолчанию директива t r a n s - s i d отключена. Для ее включения следует внести соответствующие
изменения в строку s e s s i o n . use_trans_sid= файла php. i n i . Если в этой
строке содержится значение 0, то директива t r a n s - s i d отключена, если 1— включена.
После внесения изменений нужно перезапустить Web-сервер.
Включение директивы t r a n s - s i d имеет как преимущества, так и недостатки.
S Преимущества. Механизм поддержки сеансов функционирует корректно даже
в том случае, если пользователь отключил режим использования данных
cookie, т.е. при использовании директивы t r a n s - s i d можно создавать сценарии,
не зависящие от настроек клиентского браузера.
•S Недостатки. Идентификатор сеанса передается в URL-адресе и, как следствие,
отображается в адресной строке браузера. С точки зрения обеспечения
безопасности этого следует избегать.
Использование сеансов с включенной директивой trans-sid
Если директива t r a n s - s i d включена и в клиентском браузере отключен режим исполззо-
вания данных cookie, то идентификатор сеанса автоматически пересьшается с помощью URL
или скрытых полей формы. При переходе на новую страницу с помощью ссылки, функции
header () или формы с методом GET идентификатор сеанса размещается в URL-адресе. Если
же новая страница отображается в результате заполнения полей формы, в которой для перех ачи
данных на сервер указан метод POST, то идентификатор сеанса размещается в скрытых полях.
При этом в обоих случаях идентификатор сеанса хранится в переменной $PHPSESSID.
198 Часть IV. Стандартные РНР-приложеиия
Идентификатор сеанса добавляется только к URL-адресам, которые находятся
в рамках одного Web-узла. Если же в URL содержится имя сервера, идентификатор
сеанса не добавляется. Например, к ссылке
<а href="newpage.php">
интерпретатор РНР добавит идентификатор сеанса. Однако при обработке ссылки
<а href="HTTP://www.janetscompany.com/newpage.php">
идентификатор сеанса добавляться уже не будет.
Использование сеансов с отключенной директивой trans -sid
Если в директиве t r a n s - s i d содержится значение 0 и в клиентском браузере отключен
режим использования данных cookie, то модуль РНР не будет пересылать идентификатор сеанса
на следующую страницу или в сценарий. Разработчик должен сделать это самостоятельно.
К счастью, в окружении РНР имеется соответствующая константа SID, значение которой
можно пересылать на следующую страницу вручную. В этой константе содержится пара
"имя-переменной=значение", которую к адресу URL можно добавить следующим образом:
<а href="nextpage.php?<?php echo SID?>" > следующая страница </а>;
В приведенной ссылке после имени файла стоит вопросительный знак и константа SID
с идентификатором сеанса. Выражение echo SID позволяет получить примерно следующий
результат:
PHPSESSID=f8544042bf883ca93b5e2c5dc6794755
Таким образом, адрес URL будет выглядеть примерно так:
nextpage.php?PHPSESSID=f8544042bf883ca93b5e2c5dc6794755
По определенным причинам (которые уже рассматривались выше) появление идентификатора
сеанса в окне браузера может привести к самым нежелательным последствиям. Поэтому
можно воспользоваться еще одним способом передачи идентификатора сеансов: с помощью
скрытых полей формы и метода POST. Сначала нужно получить идентификатор сеанса, а затем
переслать его в скрытом поле. Рассмотрим пример, в котором иллюстрируется данный подход:
<?php
$PHPSESSID = session_id();
echo "<form action='nextpage.php' method='POST'>
<input type='hidden' name='PHPSESSID'
value='$PHPSESSID'>
•cinput type='submit' value='Следующая страница'>
</form>";
?>
В приведенном фрагменте выполняется следующее.
1. Переменной $PHPSESSID присваивается значение идентификатора сеанса, возвращаемое
функцией s e s s i o n _ i d ().
2. Затем с использованием скрытого поля формы значение $PHPSESSID передается на
следующую страницу.
Таким образом, переменная $PHPSESSID автоматически будет доступна на следующей
странице nextpage. php.
ЛЦНИ,
Глава 11. Другие виды Web-приложений 199
Создание сеансов для групп пользователей
Сеансы прекрасно подходят для обеспечения ограниченного доступа к ресурсам Web-yaa
и ввода регистрационных данных. На таких узлах обычно содержится большое количесгво
страниц. Однако заставлять пользователя постоянно вводить регистрационные данные не> желательно.
К счастью, сеансы РНР позволяют отслеживать действия зарегистрированного
пользователя и по необходимости предотвратить возможность доступа к той или иной странице
тем пользователям, которые ранее не были зарегистрированы. С помощью механисма
поддержки сеансов можно выполнить следующие действия.
1. Отобразить страницу регистрации для ввода имени пользователя и пароля.
2. После успешной регистрации создать и сохранить соответствующие переменные сеанс а.
3. При переходе пользователя на следующую страницу на основе переменных сеанса
проверить факт успешно пройденной процедуры регистрации.
4. Если пользователь зарегистрировался, отобразить Web-страницу.
5. В противном случае предложить пользователю ввести регистрационное имя и паролэ.
Для проверки правильности введенных имени и пароля пользователя в начало кахцой
страницы необходимо добавить следующий фрагмент кода:
<?php
session_start()
if (@$_SESSION['login'] != "go")
{
header("Location: loginPage.php");
exit();
}
?>
В этом фрагменте кода проверяется переменная сеанса l o g i n (которая была инициалиш-
рована при вводе) на равенство значению до. Если данное условие не выполняется, это означает,
что пользователь не был зарегистрирован, и в браузере отображается страница для в ю-
да регистрационных данных. В противном случае сценарий продолжает выполняться.
3azfttf3tca файлов
Зачастую необходимо обеспечить, чтобы пользователи могли удаленно загружать файпы
на Web-узел. Например, на Web-узел вакансий необходимо загружать резюме, а в электронный
фотоальбом — фотографии.
Использование форм для загрузки файлов
Для обеспечения загрузки файлов на Web-узел можно разработать специальную HTML-
форму, которая может иметь следующий вид:
<form enctype="multipart/form-data"
action="processfile.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="30000">
<input type="file" name="user_file"> <input type="submit" value="Загрузить файл">
</form>
Рассмотрим элементы формы более подробно.
200 Часть IV. Стандартные РНР-лриложения
•S Атрибут enctype дескриптора <form>. Для обеспечения корректной загрузки
файла этот атрибут должен иметь значение m u l t i p a r t / form-data.
•S Скрытое поле, в котором указан максимальный размер загружаемого
файла MAX_FT.LE_SI.ZE (в байтах). Пользователь не сможет загрузить файл,
размер которого превышает MAX_FILE_SIZE. Однако перед использованием
значения MAX_FILE_SIZE в конфигурационный файл php. i n i нужно внести
следующие изменения.
• upload_max_f i l e s i z e . Значение MAX_FILE_SIZE не может превышать
значение upload_max_filesize. Если необходимо загрузить файлы
большего размера, следует изменить значение upload_max_filesize
в файле php. i n i . По умолчанию оно составляет 2 Мбайт.
• post_max_size. Эта переменная определяет максимальный объем информации,
который можно передать с использованием метода POST. По умолчанию
значение post_max_size равно 8 Мбайт, но его можно изменить.
•/ Поле f i l e , которое используется для удаленной загрузки файла.
Значение MAX_FILE_SIZE должно быть установлено перед удаленной загрузкой
файла. Лишь в этом случае можно ограничить его размер.
При загрузке файла он сохраняется во временном каталоге. Поскольку после завершения
выполнения сценария этот файл из временного каталога удаляется, следует скопировать его
в другое место. С помощью функции phpinf о () можно определить, где расположен временный
каталог. Его можно изменить с помощью директивы upload_tmp_dir файла
php. i n i . Если же в файле php. i n i путь не указан, то используется временный каталог, установленный
по умолчанию.
Получение информации о загружаемом файле
Кроме самого файла, вместе со значениями полей формы передается и информация о самом
файле. Эта информация сохраняется во встроенном массиве $_FILES, который можно
использовать для получения данных о каждом загружаемом файле. При этом доступ к информации
осуществляется посредством имен полей. Общий формат извлечения информации
о файле имеет вид
$_FILES['имя-поля']['name']
$_FILES['имя-поля']['type']
$_FILES['имя-поля']['tmp_name']
$_FILES['имя-поля'] [ ' s i z e ']
Пусть, например, файл загружается с помощью следующего поля формы:
<input type="file" name="user_file">»
Тогда при загрузке файла t e s t . t x t информацию о нем можно получить следующим
образом:
$_FILES[user_file][name] = test.txt
$_FILES[user_file][type] = text/plain
$„FILES[user_file][tmp_name] = D:\WINNT\php92C.tmp
$_FILES[user_file][size] = 435
Глава 11. Другие виды Web-приложений 201
В массиве _FILES значение name определяет имя загружаемого файла; type — его тип;
tmp_name— путь или имя временного файла; s i z e— размер файла. Обратите внимание,
что в поле name содержится только имя файла, а в поле tmp_name — полный путь и имя.
Если же размер файла оказался слишком большим, то в поле tmp_name будет содержаться
значение попе, а в поле s i z e — 0.
По умолчанию загружаемые файлы временно сохраняются в системном каталоге Windc ws
(Windows — в системе Win98/XP и Winnt — в Win2000) и в каталоге /tmp систем Unix/Linux.
Чтобы изменить временный каталог, нужно модифицировать файл php. i n i . Для этого найдите
в этом файле строку
;upload_tmp_dir =
Затем удалите в начале строки точку запятой и задайте требуемый путь. Например:
upload_tmp_dir = d:\tempfiles
При этом каталог tempf i l e s должен быть создан предварительно. В противном слугае
загружаемые файлы будут сохраняться в каталоге, заданном по умолчанию.
Перемещение файлов в требуемый каталог
Для перемещения загруженных файлов из временного каталога в требуемое местоположе] ше
предназначена функция move_uploaded_f i l e () со следующим общим синтаксисом:
move_uploaded_file(путь/имя_временного_файла,
путь/имя_постоянного_файла);
В элементе tmp_name массива $_FILES хранится временное имя файла и его местоположение.
Так что для перемещения файла, например в каталог с : \data\new_f i l e . t;:t,
можно воспользоваться функциейmove_uploaded_f i l e () следующим образом:
move_uploaded_file($_FILES['user_file'] t'tmp_name'],'с:\data\new_file.txt');
Следует заметить, что каталог, в который перемещается файл (в приведенном примере
с: \ d a t a \ ) , должен быть предварительно создан, поскольку функция move_upload_f i l e ()
этого не делает.
С точки зрения обеспечения безопасности удаленная загрузка файлов может оказаться
достаточно опасным делом. Эти файлы могут содержать опасное содержимое.
Поэтому перед сохранением файла необходимо тщательно проверить его
формат и размер. Иногда для обеспечения большей защищенности стоит даке
изменить имя и расширение загруженного файла.
Совмещая все вместе
Пример полноценного сценария приведен в листинге 11.3. Этот сценарий отображ.ет
форму для загрузки файлов изображений и позволяет сохранять эти файлы. Кроме того, после
проверки файла и его успешной загрузки выводится соответствующее сообщение. Форма л ля
загрузки изображений показана на рис .11.1. '
Листинг 11.3. Сценарий для загрузки файлов с помощью формы с методом POST
<?php
/* Имя сценария: uploadFile.php
* Описание: загружает файл с помощью протокола HTTP
* и формы с методом POST.
*/
202 Часть IV. Стандартные РНР-приложения
#9
#11
if(!isset($_POST['Upload'])) #5
{
include("form_upload.inc");
} # endif
else
{
if($_FILES['pix']['tmp_name'] == "none")
{
echo "<Ь>Файл не был загружен. Проверьте его
размер. Размер файла должен быть менее 500K.<br>",
include("form_upload.inc");
exit();
}
if(!ereg("image", $_FILES['pix']['type'])) #16
{
echo "<Ь>Файл не является изображением.
Попробуйте загрузить другой файл.</Ь><Ьг>";
include("form_upload.inc");
exit();
}
else #23
{
$destination = 'c:\data'. "\\".$_FILES['pix']['name'];
$temp_file = $_FILES['pix']['tmp_name'];
move_uploaded_file($temp_file, $destination);
echo "<р><Ь»Файл успешно загружен:</Ь>
{$_FILES['pix']['name']}
({$_FILES['pix']['size']})</p>";
}
}
?>
В листинге 11.3 заслуживают внимания следующие строки.
•/ В строке 5 с использованием условного оператора i f проверяется, бьши ли
значения из формы переданы пользователем. Если нет, исходная форма отображается
путем включения файла, приведенного в листинге 11.4.
•S Строка 9. В блоке e l s e обрабатывается файл и вся полученная информация.
•S В строке 11 с использованием оператора i f проверяется успешность загрузки
файла. Если файл не был загружен, выводится соответствующее сообщение
об ошибке и исходная форма отображается повторно.
•S В строке 16 проверяется корректность формата файла. Если загружаемый
файл не является изображением, выводится соответствующее сообщение об
ошибке и исходная форма отображается заново.
S Строка 23. В блоке e l s e (т.е. при успешной загрузке) загруженный файл
перемещается в требуемое местоположение и выводится соответствующее
сообщение.
В листинге 11.4 приведен код включаемого файла, который обеспечивает отображение
исходной формы для загрузки изображений.
Глава 11. Другие виды Web-приложений 203
Листинг 11.4. Включаемый файл, обеспечивающий отображение формы для загрузки файлоЕ
<!-- Имя сценария: form_upload.inc
Описание: отображает форму для загрузки файла -->
<html>
<headxtitle>3arpy3Ka фaйлa</title></head>
<body>
<о1><И>Введите имя изображения, которое вы
хотите поместить в архив, или воспользуйтесь
кнопкой Обзор, чтобы указать его
местоположение.</li>
<И>После появления пути к файлу в
текстовом поле щелкните на кнопке Загрузить
изображение-;/li>
</ol>
<div align="center"><hr>
<form enctype="multipart/form-data"
action="uploadFile.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="500000">
<input type="file" name="pix" size="60">
<pxinput type="submit" name= "Upload"
value="Загрузить изображение">
</form>
</bodyx/html>
Файл Правка Вид Избранное Сервис Справка
Ф Назад ' Q - [и] Q ^ ?) Поиск «jj? Избранное *g>
Адрес: М http:№caliost/test/uptoedFle.php
вот w
& в-.У'ФАЯ
•Й Q Переход
1, Введите имя изображения, хоторое вы хотите поместить в архив, или воспользуйтесь кнопкой Обзор,
чтобы указать его местоположение.
2. После появления пути к файлу в текстовом поле, щелкните на кнопке Загрузить изображение.
1 Обзор...
Загрузить изображение |
ЧЙ Готово *»| Местная интрасеть
Рис. 111. Форма для загрузки файла с изображением
204 Часть IV. Стандартные РНР-приложеиия
Обратите внимание, что в этом файле содержится только HTML-код.
Исходная форма для загрузки файлов изображена на рис. 11.1. В ней содержится текстовое
поле для ввода имени загружаемого файла и кнопка для его поиска.
использование JavaScrifit и ?/&
При разработке Web-узлов может оказаться, что нужно использовать и язык сценариев
JavaScript. Например, может понадобиться изменить содержимое Web-страницы в зависимости
от местоположения курсора мыши или щелчка на ней, т.е. изменить страницу без ее повторного
отображения. Это нельзя сделать с помощью РНР, поскольку он является серверным
языком разработки сценариев. Интерпретатору РНР ничего неизвестно о том, что
происходит в клиентском браузере, поскольку он выполняет сценарии только на сервере. Поэтому
для изменения Web-страницы следует воспользоваться языком создания клиентских
сценариев, к которым и относится язык JavaScript.
Пользователь может отключить режим использования сценариев JavaScript,
и браузер не сможет их выполнить. Поэтому, прежде чем принять решение об
использовании языка JavaScript, необходимо удостовериться в том, что соответствующий
режим поддерживается клиентским программным обеспечением.
В данной главе язык клиентских сценариев JavaScript подробно рассматриваться не будет.
Здесь речь пойдет лишь о том, как совместно использовать языки сценариев JavaScript и РНР.
(Более подробную информацию о языке JavaScript можно найти в книге JavaScript для
"чайников" Эмили Вандер Вер, вышедшей в издательстве "Диалектика".)
Добавление кода JavaScript в сценарий РНР
Код JavaScript, так же как и код HTML, интерпретируется и выполняется клиентским
браузером. Поэтому его можно добавить в сценарий РНР точно так же, как и код HTML. По
существу, сценарии JavaScript являются частью HTML-кода Web-страницы, которые можно
добавить следующим образом:
<script language="JavaScript">
код JavaScript
</script>
В сценариях РНР код JavaScript используется точно так же, как и код HTML: выводится
с помощью функции echo. Например:
<?php
echo "<script language=\"JavaScript\">
<! - -
document.write('Данная страница изменялась: '+ document
.lastModified + '<br>')
/ / —>
</script>";
?>
При выполнении этого фрагмента кода в браузере будет выведена строка с датой и временем,
когда данная страница была в последний раз модифицирована:
Данная страница изменялась: 03/24/2003 12:01:47
Код JavaScript, так же как и дескрипторы HTML, можно размещать вне дескрипторов РНР
и не использовать вместе с функцией echo. В этом случае он будет обрабатываться только
клиентским браузером.
Глава 11. Другие виды Web-приложений 205
Использование переменных РНР в сценариях JavaScript
Переменные РНР допустимо использовать в коде JavaScript точно так же, как и дескр т-
торы HTML. Например, в приведенный выше код можно добавить переменную $ s t r i ng
следующим образом:
<?php
$ s t r i n g = "Данная страница изменялась:";
echo " < s c r i p t l a n g u a g e = \ " J a v a S c r i p t s ">
< ! - -
d o c u m e n t . w r i t e ( ' $ s t r i n g '
+ document.lastModified + ' < b r > ')
/ / -->
< / s c r i p t > " ;
?>
В свою очередь, в сценариях JavaScript используются собственные переменные, котор >м
можно присваивать значения переменных РНР. Например:
<?php
$ s t r i n g = "Данная страница изменялась:";
echo " < s c r i p t l a n g u a g e = \ " J a v a S c r i p t \ ">
<! —
var message = \ " $ s t r i n g \ ";
document.write(message
+ d o c u m e n t . l a s t M o d i f i e d + '<br>')
/ / —>
< / s c r i p t > " ;
?>
Поскольку код JavaScript выполняется в клиентском браузере, то "обменяться" значения ии
переменных JavaScript с переменными РНР на текущей странице нельзя. Значения JavaScript
должны быть переданы следующему сценарию РНР. Для этого их можно добавить к UEL-
адресу, разместить в данных cookie или передать в качестве элемента формы.
206 Часть IV. Стандартные РНР-приложення
Глава 12
Хранение данных с использованием РНР
в э*?ой главе...
> Запись и чтение файлов
> Обмен данными между РНР и другими приложениями
> Поддержка баз данных в РНР
> Использование РНР для взаимодействия с базами данных
> Обработка ошибок при подключении к базе данных
о многих приложениях требуется обеспечить длительное хранение информации. Непродолжительное
хранение данных в сценариях РНР можно осуществить с помощью
механизма сеансов (session). Однако зачастую информация должна быть доступна в любое
другое время, например через день или на следующей неделе. Как уже говорилось в главе 11,
после завершения сеанса это можно обеспечить с помощью данных cookie. Однако при их
использовании разработчик не управляет режимом поддержки данных cookie. Пользователь
может удалить или изменить информацию в любой момент или вообще отключить соответствующий
режим в своем браузере. Поэтому информацию следует хранить в более безопасном
месте с ограниченным доступом, например на сервере.
На сервере информация может храниться в текстовых файлах или в базе данных. Текстовые
файлы хранятся в локальной файловой системе. Их можно прочитать с помощью команд операционной
системы, например команды a t систем Linux/Unix. Для редактирования таких файлов можно
воспользоваться любым текстовым редактором, таким как Notepad или vi. Информация в файлах
обычно хранится в строковой форме. Для ее извлечения сценарию РНР необходимо "знать"
соответствующий формат. Например, для извлечения из файла имени покупателя сценарию РНР
необходимо "знать" о том, что имена покупателей занимают первые 20 символов каждой строки.
В свою очередь, при использовании баз данных требуется установить специализированное
программное обеспечение, такое как MySQL или Oracle. Базы данных тоже представляют собой
файлы, которые, однако, создаются соответствующими приложениями и могут быть доступны
только через них. В базе данных можно хранить информацию любой сложности. При
этом нет необходимости знать принципы ее хранения — важно иметь навыки работы с соответствующим
программным обеспечением. Например, для получения имени покупателя
в сценарии РНР достаточно правильно сформулировать запрос на языке SQL, чтобы система
управления базами данных обработала этот запрос и предоставила результат. При этом абсолютно
не важно, где и в каком виде хранится требуемая информация.
Ниже приводится несколько преимуществ использования текстовых файлов по сравнению
с базами данных. I
•S Гибкость. Создавать и хранить данные можно в файловой системе любой
операционной системы. При этом не требуется устанавливать какое-либо дополнительное
программное обеспечение. Кроме того, текстовые файлы можно
обрабатывать во многих текстовых редакторах или электронных таблицах.
•S Простота использования. В установке дополнительной системы управления
базами данных, создании и проектировании самой базы данных нет никакой
в
необходимости. Достаточно создать файл средствами РНР и хранить в нем
полезную информацию.
•S Экономия дискового пространства. Текстовые файлы занимают гораздо
меньше дискового пространства, чем базы данных.
Подводя итог, можно сказать, что текстовые файлы являются простым, эффективным
и экономным (с точки зрения использования ресурсов) способом хранения небольших объемов
информации. Они просты в использовании и обеспечивают быстрый доступ к данным. Кроме
того, текстовый формат поддерживается различными редакторами и электронными таблицами.
В то же время текстовые файлы доступны для всех, кто обладает правами на доступ к i pe-
буемому каталогу, поэтому их можно использовать в качестве средства обмена информацией.
Базы данных также имеют свои преимущества.
•S Безопасность. Кроме обеспечения безопасности на уровне операционной
системы, базы данных предоставляют дополнительный уровень защиты. Информация
в базах данных защищена от внешнего вторжения гораздо лучше,
чем в простых файлах.
•S Поддержка сложной структуры данных. В базах данных можно хранить
информацию с очень сложной структурой, различными типами данных
и взаимосвязями. Это позволяет существенно упростить поиск и извлече! не
требуемой информации.
•S Поддержка многопользовательского режима. Если к одному и тому же фа] пу
(например, с именами и адресами клиентов) обращаются много пользователей,
то с помощью средств системы управления базами данных можно обеспечшъ
согласованность данных и предотвратить опасность их затирания или потери.
Одним словом, при использовании баз данных требуется гораздо больше усилий и дис со-
вого пространства. Однако вместе с тем они позволяют обрабатывать данные со сложной
структурой. Базы данных существенно упрощают извлечение требуемой информации, обгс-
печивают больший уровень защиты и предоставляют возможность одновременного подключения
многих пользователей.
При установке РНР 5 по умолчанию устанавливается расширение SQLite, которое предназначено
для использования файлов и баз данных. При использовании расширения SQLite информация
хранится в текстовых файлах, однако для доступа к ним применяется стандартн >[й
язык запросов SQL. Поэтому устанавливать дополнительное программное обеспечение не
требуется. Расширение SQLite удобно использовать для хранения и обработки небольших
объемов данных, однако для организации большого хранилища данных все же лучше воспользоваться
специализированными пакетами.
использование /пекс&овых файлов
Текстовые файлы использовать гораздо проще, чем базы данных. Кроме того, при их использовании
не нужно устанавливать дополнительное программное обеспечение. Для чтен ия
или записи в файл достаточно воспользоваться соответствующими операторами языка РНР
При работе с текстовыми файлами нужно выполнить следующие этапы.
1. Открыть файл.
2. Записать или извлечь данные из файла.
3. Закрыть файл.
Каждый из этих этапов более подробно рассматривается в следующих разделах.
208 Часть IV. Стандартные РНР-приложення
Доступ к файлам
Перед чтением или записью информации из файла необходимо его открыть. Для этого
предназначена функция
$fh = fopen("имя_файла", "режим");
Переменная $fh является дескриптором файла (file handle), который используется при
чтении или записи данных в файл. Дескриптор файла содержит информацию о местоположении
открытого файла.
При открытии файла необходимо указать соответствующий режим, который определяет
те действия, которые планируется выполнять с файлом после его открытия. Возможные режимы
открытия файлов приведены в табл. 12.1.
Таблица 12.1. Режимы открытия файлов
Режим Описание Что происходит, если файл не существует
г Только чтение Выводится предупреждающее сообщение
г+ Чтение и запись Выводится предупреждающее сообщение
w Только запись Создается новый файл. Если файл существует,
новый файл перезаписывается поверх старого
w+ Чтение и запись Создается новый файл. Если файл существует,
новый файл перезаписывается поверх старого
а Добавление данных в конец файла Если файл не существует, создается новый файл
а+ Чтение и добавление данных в конец файла Если файл не существует, создается новый файл
Параметр имя_файла может содержать имя файла ( f i l e n a m e . t x t ) , полный путь к нему
( с : / d a t a / f i l e n a m e . t x t ) или адрес U R L ( h t t p : / / y o u r s i t e . c o m / f i l e n a m e . t x t ).
Открытие файла в режиме чтения
Для открытия файла f i l e l . t x t и считывания из него информации воспользуйтесь
функцией f open () со следующими параметрами:
$fh = f o p e n ( " f i l e l . t x t " , " r " );
В результате интерпретатор РНР выполнит поиск файла f i l e l . t x t в текущем каталоге.
Текущим считается каталог, в котором расположен сценарий РНР. Если файл не существует,
может быть выведено сообщение об ошибке (в зависимости от выбранного режима вывода
сообщений об ошибках, см. главу 4):
Warning: f o p e n ( f i l e l . t x t ) : f a i l e d to open stream: No such f i l e or
d i r e c t o r y in d : \ t e s t 2 . p h p on l i n e 15
(Предупреждение: f o p e n ( f i l e l . t x t ) : ошибка открытия потока: Файла или
каталога не существует в файле d : \ t e s t 2 . p h p на строке 15)
Однако не забывайте о том, что вывод предупреждения не приведет к прерыванию выполнения
сценария. Поэтому любые функции, оперирующие с несуществующим файлом, будут
работать некорректно.
Дня прерывания выполнения сценария в случае отсутствия файла воспользуйтесь фрагментом
$fh = f o p e n ( " f i l e l . t x t " , "r") or die("He удалось открыть файл");
Как упоминалось в главе 8, функция d i e () прерывает выполнение сценария и выводит
заданное сообщение.
Глава 12. Хранение данных с использованием РНР 209
Открытие файла в режиме записи
Для открытия файла в заданном каталоге в режиме записи воспользуйтесь функцией
f open () со следующими параметрами:
$fh = f o p e n ( " с : / t e s t d i r / f i l e l . t x t " , "w") ;
Если заданный файл не существует, будет создан новый файл. Однако если отсутствует
требуемый каталог, будет выведено сообщение об ошибке. (Другими словами, каталог должен
быть предварительно создан.)
Проверить существование каталога можно следующим образом:
i f ( i s _ d i r ( " с : / t e s t e r " ) )
{
$fh = fopen("c:/testdir/filel.txt", "w");
}
Теперь открытие файла будет выполняться только в том случае, если существует требуемый
каталог.
Открытие файла на другом Web-узле
Файл, расположенный на другом Web-узле, можно открыть следующим образом:
$fh = fopen("http://janet.valade.com/index.html", "г");
URL-адрес можно использовать для открытия файлов только для чтения.
Закрытие файла
После использования файл нужно закрыть:
fclose($fh);
В качестве входного параметра функция использует дескриптор файла $fh, который )а-
нее был создан при его открытии.
Запись в файл
После открытия файла можно приступать к записи в него различной информации, /дя
этого предназначена функция f w r i t e () со следующим синтаксисом:
fwrite($fh, данные);
Параметрами этой функции являются дескриптор файла $fh, созданный при его открытии,
и данные, которые необходимо сохранить. В качестве данных можно использовать
текстовую строку или переменную. Например:
$today = date("Y-m-d");
$fh = f o p e n ( " f i l e 2 . t x t " , "a");
fwrite($fh, $today);
fclose($fh);
В этом фрагменте текущая дата записывается в файл f i l e 2 . t x t . Причем файл открывагг-
ся для добавления информации. Если при открытии файла не существовало, будет создан нов >ш
файл. При этом данные будут записаны в его первую строку. При открытии существующего
файл текущая дата добавляется в конец файла. Таким образом, можно создать журнал регистрации,
содержащий, например, время запуска сценария. Следует заметить, что функгия
f w r i t e () записывает в файл только ту информацию, которая была указана при ее вызове. TJK,
после повторного запуска сценария содержимое файла будет выглядеть следующим образом:
2 003-04-222003-04-22
210 Часть IV. Стандартные РНР-приложенм
Гораздо удобнее размещать различные даты в отдельных строках. Для этого функцию
f w r i t e () нужно вызвать таким образом:
fwrite($fh, $today"\n");
После добавления символа \п файл f i l e 2 . t x t будет содержать следующие данные:
2003-04-22
2003-04-22
Если в файл нужно добавить информацию, его необходимо открыть в режиме а.
При открытии в режиме записи файл каждый раз будет создаваться заново, а информация
— перезаписываться.
Чтение файла
Для чтения файла предназначена функция f g e t s () со следующим синтаксисом:
$line = fgets($fh);
где $fh— дескриптор файла, который был создан при его открытии. Функция f g e t sO
считывает файл до тех пор, пока не будет достигнут конец строки или файла. При этом извлеченная
информация сохраняется в переменной $line. Построчно можно прочитать весь
файл. Для определения конца файла в языке РНР предназначена функция f eof (). В следующем
примере считываются и выводятся все строки файла:
while(Ifeof($fh))
{
$line = fgets($fh);
echo "$line";
}
Функция f eof () возвращает значение TRUE при достижении конца файла с дескриптором
$fh. Восклицательный знак в условном выражении цикла w h i l e обеспечивает чтение
всех строк файла.
Если приведенный фрагмент использовать для чтения журнала регистрации, созданного
в предыдущем разделе, получим следующий результат:
2003-04-22 '
2003-04-22
Как можно увидеть, символ перевода строки используется функцией f g e t s () по умолчанию.
В некоторых случаях этого не требуется, так что эти символы нужно удалить:
while(ifeof($fh))
{
$line = rtrim(fgets($fh));
echo "$line";
}
Функция r t r i m ( ) удаляет пробелы в конце строки и символы перевода строки. Так что
при ее использовании будет получен следующий результат:
2003-04-222003-04-22
Чтение файлов по частям
Иногда из файла необходимо считать строки определенного размера. Для этого следует
воспользоваться функцией f g e t s () со следующим синтаксисом:
$line = fgets($fh, л);
Глава 12. Хранение данных с использованием РНР 211
В данном случае строка длиной л-1 будет считываться до тех пор, пока не будет достигнут
конец строки или файла. Например:
while{Ifeof($fh))
{
$char4 = fgets($fh, 5);
echo "$char4\n";
}
В приведенном фрагменте считываются каждые четыре символа, пока не будет достиг нут
конец файла. При этом будет получен следующий результат:
2003
- 0 4 -
22
2003
- 0 4 -
22
Обратите внимание, что после каждой строки по умолчанию используется символ пере вода
строки.
Размещение файла в массиве
Зачастую содержимое всего файла удобно разместить в массиве. Это можно выполн 1ть
следующим образом:
$fh = f o p e n C f i l e 2 . t x t " , "г");
while(Ifeof($fh))
{
$content[] = fgets($fh);
}
fclose($fh);
В результате будет создан массив $content, ключами которого будут целые числа,
а значениями — строки, считанные из файла.
То же самое можно осуществить с помощью одной функции f i l e (). При этом получ IT-
ся аналогичный результат:
$content = f i l e C f i l e 2 . t x t " ) ;
Эта функция открывает файл, размещает строки в массиве $content и закрывает файл.
Если открываемый файл очень большой, то использование функций f i l e () может
существенно замедлить работу сценария. Это зависит от размера доступной
памяти на компьютере. Если сценарий действительно работает медленно, вместо
функции f i l e () следует воспользоваться функцией f g e t s О, а затем проверить,
повлияло ли это на быстродействие.
Функцию f i l e () можно использовать для открытия файлов во включаемом каталоге
(см. главу 8):
$content = f i l e ( " f i l e 2 . t x t " , 1);
Параметр 1 указывает, что поиск файла f i l e 2 . t x t следует осуществлять в каталоге
включений, а не в текущем каталоге.
Размещение файла в строке
Иногда содержимое файла необходимо разместить в одной длинной строке. Например,
это может оказаться полезным, если данные из файла нужно отправить по электронной поч re.
Для этого предназначена
$content = file_get_contents("file2.txt", 1);
212 Часть IV. Стандартные PHP-приложения
Функция f i l e _ g e t _ c o n t e n t s () полностью аналогична f i l e (), за исключением того,
что содержимое файла размещается не в массиве, а в строке. Затем можно вывести значение
переменной $content:
echo $content;
При этом получим следующий результат:
2003-04-22
2003-04-22
Обратите внимание, что символы перевода строки входят в состав строки $content и,
естественно, учитываются при выводе.
.„ЛИН!
Функция f i l e _ g e t _ c o n t e n t s ( ) появилась в PHP 4.3.O. В более ранних версиях
она отсутствует.
Обмен данными с другими программами
Файлы оказываются очень полезными, если нужно обеспечить взаимодействие сценариев
РНР с другими приложениями. Практически все без исключения программы предоставляют
возможность считывания или записи данных в файл. Например, текстовые редакторы по
умолчанию сохраняют информацию в своем собственном формате. Однако они позволяют
работать и с текстовыми файлами, т.е. созданный с использованием сценария РНР текстовый
файл можно прочитать и в других приложениях.
Однако при взаимодействии со многими программными продуктами все же приходится считаться
с используемым в них специальным форматом. Например, в адресной книге каждому
фрагменту данных соответствует свое предопределенное место. Так, первые 20 символов строки
могут использоваться для хранения имени, вторые 20 символов — для адреса и т.Д. Поэтому для
работы с файлами подобного типа нужно точно знать их формат. В сценарии РНР такой формат
можно сгенерировать с помощью функции fwrite (), которая уже рассматривалась выше.
Файлы CSV (comma-separated values — значения, разделяемые запятой), иногда называемые
также файлами с символами-разделителями , (comma-delimited file), являются стандартным
средством обмена данными между различными приложениями. Файлы CSV могут использоваться
для обмена информацией, содержащейся в таблице (со столбцами и строками).
Такой формат поддерживается большинством табличных приложений (например, Microsoft
Excel). Файлы CSV удобно использовать и при передаче данных между различными базами
данных, такими как MySQL и Microsoft Access. Формат CSV достаточно распространен и
поддерживается различным программными обеспечением.
CSV-файл имеет следующую структуру: каждая его строка соответствует строке таблицы,
а значения, разделенные запятой, — столбцам. Рассмотрим следующий пример адресной книги,
организованной с использованием файла CSV:
Джон Смит, ул. Дубов 1234, Большой город, OR, 99999
Мэри Джонс, Сосновая ул. 5678, Больший город, ME, 11111
Луис Рохас, ул. Вязов 1234, Самый большой город, ТХ, 88888
Excel позволяет прочитать этот файл и преобразовать его в таблицу, состоящую из пяти
столбцов. При этом запятая используется в качестве символа-разделителя. Outlook Express
также сможет импортировать этот файл в свою адресную книгу.
Следующий фрагмент кода на языке РНР позволяет создать файл в формате CSV.
$address[] = "Джон Смит, ул. Дубов 1234, Большой город, OR, 99999";
$address[] = "Мэри Джонс, Сосновая ул. 5678, Больший город, ME, 11111";
$address[] = "Луис Рохас, ул. Вязов 1234, Наибольший город, ТХ, 88888";
$fh = fopen("addressbook.txt", "a");
Глава 12. Хранение данных с использованием РНР 213
for ($i=0;$i<3;$i++)
{
f w r i t e ( $ f h , $ a d d r e s s [ $ i ] . " \ n " );
}
f c l o s e ( $ f h ) ;
Для чтения CSV-файла можно воспользоваться функцией f i l e О или f g e t s ( ) , сак
описывалось выше, в разделе "Размещение файла в массиве". Однако специально для э"их
целей в языке РНР имеется функция f g e t c s v ( ) . При чтении файла с использованием т ой
функции каждая строка записывается в массив, элементами которого являются значения
столбцов. Например:
$address = f g e t c s v ( $ f h , 1000);
В приведенной строке из файла с идентификатором $fh считывается строка дликой
1000 символов. Результатом выполнения функции f g e t c s v () будет следующий массив:
$address[0] = Джон Смит
$ a d d r e s s [ l ] = ул. Дубов 1234
$ a d d r e s s [ 2 ] = Большой город
$ a d d r e s s [ 3 ] = OR
$ a d d r e s s [ 4 ] = 99999
Формат CSV очень удобно использовать при передаче данных между различными припо-
жениями. Однако не забывайте о том, что если символ , является частью данных, то зго
нельзя использовать в качестве символа-разделителя. Рассмотрим следующую строку:
Компания Смита, мл., ул. Дубов 1234, Большой город, OR, 99999
Запятая используется в названии компании и соответственно при считывании привезет
к его разделению его на две части (столбца): Компания Смита и мл., т.е. вместо ожидавшихся
пяти столбцов будет шесть. Для решения этой проблемы в качестве символа-
разделителя следует использовать другой символ, например символ табуляции ( \ t ) . (Именно
так и поступают чаще всего.) В этом случае файл уже будет называться TSV (tab-separated
values — значения, разделенные символами табуляции).
Для чтения такого файла можно воспользоваться функцией ? g e t c s v () такого вида:
$address = f g e t c s v ( $ f h , 1000, " \ t " );
В общем случае в качестве третьего параметра, т.е. разделителя, можно указать любой симвс л.
В листинге 12.1 приведен сценарий, который преобразует файл CSV в файл TSV.
Листинг 12.1. Сценарий, преобразующий файл CSV в TSV-файл
<?php
/ * Имя сценария: Convert
* Описание: считывает CSV-файл и записывает данные в
TSV-файл. CSV-файл должен иметь расширение .CSV.
*/
$myfile = " t e s t i n g ";
f u n c t i o n convert($filename)
{
if(@$fh_in = fopen("{$filename}.csv"
{
$fh_out = f o p e n ( " { $ f i l e n a m e } . t s v ",
w h i l e ( I f e o f ( $ f h _ i n ) )
{
$line = fgetcsv($fh_in, 1024);
if($line[0] == "")
{
"r'D
a");
#7
#8
#10
#12
#13
#15
#16
214 Часть IV. Стандартные РНР-приложегия
fwrite($fh_out, "\n");
}
else { #20
fwrite($fh_out,implode($line, "\t")."\n");#21
}
}
fclose($fh_in);
fclose($fh_out);
}
else {
echo "Файл не существует\n";
return FALSE;
}
echo "Преобразование завершено!\n";
return TRUE;
}
convert($myfile);
#27
#32
#34
?>
В листинге 12.1 некоторые строки пронумерованы. Ниже представлены соответствующие
пояснения.
•S В строке 7 задается имя обрабатываемого файла.
S В строке 8 определяется функция convert () с параметром $f ilename.
S Строка 10. В этой строке для чтения открывается файл с расширением . csv.
Если файл был успешно открыт, выполняется его преобразование в блоке if.
В противном случае выполняется блок e l s e строки 27.
•S Строка 12. В этой строке в режиме добавления открывается файл с расширением
. t s v . Предполагается, что файл находится в текущем каталоге, т.е. там
же, где расположен и сам сценарий.
•S Строка 13. В этой строке начинается цикл while, который завершается при
достижении конца файла.
•S Строка 15. Строка файла считывается в массив $ l i n e . Каждый элемент массива
содержит значение столбца.
•S Строка 16. В этой строке проверяется, содержит ли строка исходного файла
какую-либо информацию. Если нет, выводится символ перевода строки (\п).
Тем самым обеспечивается, что пустая строка исходного файла будет содержаться
и в выходном файле.
S Строка 20. Если строка исходного файла не пуста, выполняется ее преобразование
в формат TSV и запись в файл.
S Строка 21. В этой строке выполняется преобразование строки. При этом результат
записывается в выходной файл. Функция implode () используется
для преобразования массива $ l i n e в текстовую строку, в которой в качестве
символов-разделителей применяются символы табуляции (\t).
S Строка 27. Блок e l s e выполняется в том случае, если исходный файл отсутствует.
При этом выводится соответствующее сообщение об ошибке, а функция
convert () возвращает значение FALSE.
•S Строка 32. Если функция выполнена успешно, возвращается значение TRUE.
S Строка 34. В этой строке вызывается функция convert (), которой в качестве
параметра передается значение переменной $myf i l e .
Глава 12. Хранение данных с использованием РНР 215
Padotna с базами данных
Если необходимо хранить данные со сложной структурой, обеспечивать безопаснс сть
и обрабатывать множество одновременных запросов, базы данных оказываются гораздо более эффективными,
чем обычные файлы. Если же вы имеете опыт работы со специальным программным
обеспечением, то это позволит существенно упростить решение поставленной задачи.
Системы управления базами данных
Базы данных (database) напоминают электронную картотеку, в которой хранится упорядоченная
информация, извлекаемая по мере необходимости. База данных может быть небольшой,
с простой структурой данных, например база данных имен, адресов и телефонных номеров
всех ваших друзей. В свою очередь, в базе данных Amazon содержится огромное
количество информации, которая имеет чрезвычайно сложную структуру.
Формально базу данных можно определить как файл или группу файлов, в которых хранятся
данные. Доступ к этим дгнным можно получить с использованием системы управления
базами данных (СУБД) (DBMS — Database Management System). В настоящее время практически
все СУБД являются реляционными (relational), поддерживающими хранение данных
в наборе взаимосвязанных таблиц.
Одно из значительных преимуществ языка РНР заключается в поддержке более двадцати
возможных СУБД. К наиболее известным относятся следующие.
S IBMDB2
S Informix
S Ingres
^ Microsoft SQL Server (MS SQL)
• mSQL
• MySQL
S Oracle
* PostgreSQL
S Sybase
Кроме того, язык PHP поддерживает также и стандарт ODBC (Open Database Connectivity —
открытый интерфейс доступа к базам данных) компании Microsoft. Его поддерживают пра*ти-
чески все реляционные СУБД, особенно те из них, которые предназначены для использования
в операционной системе Windows. Используя поддержку ODBC в языке РНР, можно обращаться
к таким базам данных, как DB2 и Access. При использовании стандарта ODBC для взаимодействия
с базой данных необходимо установить соответствующий драйвер. Более подробную
информацию по этому вопросу можно получить в соответствующей документации.
После установки СУБД к ней можно обращаться из сценариев РНР, в которых информацию
нужно сохранить или извлечь из базы данных. Выбор и установка системы управле *ия
базами данных выполняется независимо от РНР. После установки СУБД следует проверить
ее работоспособность и научиться ее использовать. После этого можно приступать к ее использованию
в сценариях РНР.
Выбор реляционной СУБД зависит от реальных потребностей. Одна из них может прекра:но
подходить для решения одной задачи, тогда как при решении другой задачи, возможно, потребуется
воспользоваться совершенно другим программным обеспечением. Следует взвесить все "за" и
"против" и лишь после этого приступать к выбору системы управления базами данных, которая
будет использоваться впоследствии. При выборе СУБД следует учитывать следующее.
216 Часть IV. Стандартные РНР-приложегия
•S Стоимость. Стоимость СУБД может быть достаточно разной. Она может
быть как бесплатной, так и достаточно дорогостоящей. Так, системы управления
базами данных MySQL, mSQL и PostgreSQL были разработаны как открытое
программное обеспечение и, следовательно, являются бесплатными.
Другие СУБД, например Sybase, MS SQL Server и Oracle, являются коммерческим
программным обеспечением, приобретение которого связано с существенными
денежными затратами.
S Предоставляемые возможности. Различные системы управления базами
данных предоставляют разные возможности. Например, система mSQL обладает
ограниченным набором функций, однако в определенных условиях их
может оказаться вполне достаточно. С другой стороны, Oracle позволяет выполнить
практически любые действия, кроме, возможно, управления автомобилем.
Кроме того, не следует забывать и о том, что чем больше возможностей
предоставляет СУБД, тем больше она потребляет ресурсов и является
более дорогостоящей. Поэтому не стоит устанавливать компоненты, которые
в дальнейшем наверняка не понадобятся.
S Потребляемые ресурсы. Некоторые СУБД потребляют гораздо больше ресурсов
(например, дискового пространства и памяти), чем другие. Так, системы
mSQL и MySQL не требуют больших ресурсов, а для функционирования
Oracle в зависимости от установок может потребоваться достаточно много
вычислительных ресурсов.
•S Поддержка. Вне всякого сомнения, при использовании коммерческого и
открытого программного обеспечения предоставляется различная техническая
поддержка.
•S Коммерческое программное обеспечение. Компании-разработчики предоставляют
различную техническую поддержку потребителям своего коммерческого
программного обеспечения. Иногда это связано с дополнительными денежными
затратами, в других случаях— с потерей времени на ожидание
связи со специалистами. Но в любом случае компания-разработчик всегда
предоставляет помощь и помогает справиться с возникающими проблемами.
•/ Программное обеспечение с открытым кодом. При использовании открытого
программного обеспечения нельзя воспользоваться прямой телефонной
связью с его разработчиком. Его развитие обеспечивается сообществом пользователей.
При возникновении проблем можно обратиться к соответствующему
списку рассылки или форуму. Иногда это позволяет получить ответ гораздо
быстрее, чем при телефонном звонке в службу технической поддержки
компании-разработчика.
После выбора системы управления базами данных необходимо установить соответствующее
программное обеспечение, а затем научиться его использовать. Кроме того, нужно уметь проектировать
и создавать базы данных, к которым впоследствии будут обращаться сценарии РНР.
Как правило, база данных состоит из двух частей: структуры данных и самих данных.
В свою очередь, структура определяет саму базу данных и таблицы, в которых будет храниться
информация. Перед тем как приступить к наполнению базы данных информацией, необходимо
спроектировать саму структуру базы данных. Реляционные таблицы аналогичны
любым другим таблицам и состоят из строк и столбцов.
Пусть, например, необходимо разработать интерактивный каталог товаров, который позволял
бы клиентам делать заказы. Для этого можно создать базу данных Catalog (Каталог), в состав
Глава 12. Хранение данных с использованием РНР 217
которой входила бы таблица Product (Товар). Каждая строка таблицы Product соответстиует
одному товару. В данном случае товаром являются рубашки. Тогда каждый столбец будет соответствовать
их различным характеристикам: название (тенниска, белая рубашка к вечерь ему
костюму, спортивная рубашка с короткими рукавами и т.д.), описание, размер, цвет и т.п.
При создании таблицы каждому столбцу нужно присвоить название, т.е. имя поля (field папе).
Так, таблица Product будет содержать столбцы со следующими именами:
S Туре (тип)
S Description (описание)
S Size (размер)
•/ Color (цвет)
S Price (цена)
Конечно, в базе данных Catalog могут содержаться и другие таблицы с информацией
о стоимости доставки и налогах.
Кроме проектирования и создания базы данных, необходимо решить также и вопросы,
связанные с обеспечением безопасности. Обеспечение требуемого уровня защиты данных является
одной из отличительных возможностей системы управления базами данных. В тс же
время это может существенно усложнить сохранение и извлечение информации.
Так, доступ к данным может получить лишь зарегистрированный пользователь. При этом,
если база данных размещается на сервере Web-хостинговой компании, ее администраторы
должны создать и предоставить соответствующие учетные записи. Если же вы сами обеспечиваете
работоспособность системы управления базы данных, все эти действия придется научиться
делать самостоятельно.
После выполнения всех действий по проектированию и созданию базы данных мо:кно
приступать к ее использованию. Соответствующие средства языка РНР позволяют существенно
упростить решение этой задачи.
Поддержка баз данных в РНР
Для взаимодействия с базами данных в языке РНР предназначены специальные фуню [ии.
Причем каждой поддерживаемой СУБД соответствует свой собственный набор средств. Например,
для взаимодействия с базой данных MySQL версии 4.0 или ниже следует воспользоваться
функциями mysgl_connect () и mysql_query (), а для подключения к базе данных
MySQL версии 4.1 или выше — mysgli_connect () и mysqli_cruery (). Для рабэты
с базой данных Sybase предназначены функции sybase_connect () и sybase_guery ().
В РНР по умолчанию поддерживается стандарт ODBC, поддержку других баз даншх
нужно активизировать самостоятельно. При работе с Web-хостинговой компанией тасую
поддержку должны обеспечить ее администраторы. Если же база данных размещается на вашем
компьютере, все требуемые настройки придется выполнить самостоятельно
(подробности — в следующем разделе).
Поддержка баз данных в системах Unix/Linux/Mac
Поддержка баз данных обеспечивается при использовании в процессе компиляции модуля
РНР соответствующего параметра. В приложении А параметры компиляции рассматривг ют-
ся более подробно. Например, для включения поддержки mSQL в процессе компиляции ьуж-
но воспользоваться командой
./configure --with-msql=/usr/msgl
218 Часть IV. СтандартныеРНР-припожетя
В табл. 12.2 приведены параметры, включающие поддержку других систем управления
базами данных. Помните о том, что если база данных устанавливается в каталоге по умолчанию,
параметр DIR указывать не нужно. Например:
./configure --with-msql
Таблица 12.2. Параметры включения поддержки различных баз данных
СУБД Параметр компиляции Значение D I R ПО умолчанию
IBM DB2
Informix
Ingres II
mSQL
MySQL 4.0 или ниже
with-ibm-db2=D/fl
with_informix=D/fl
with-ingres=D/R
with-msql=D/R
with-mysql=D/fl
/home/db2instl/sqllib
Значение по умолчанию отсутствует
/II/ingres
/usr/local/Hughes
/usr/local/mysql
MySQL 4.1 или выше
Oracle 7 или более новые версии
Ранние версии Oracle
PostgreSQL
Sybase
Sybase-CT
wi th-mysql i =Ш?
with-oci8
with-oracle=D/fl
with-pgsql=D/ft
with-sybase=D/fl
with- Sybase- с t=DIR
Значение по умолчанию отсутствует.
Значение параметра D I R должно совпадать с
путем к файлу m y s q l _ c o n f i g , который
устанавливается вместе с MySQL 4.1 или
выше
Значение по умолчанию содержится
в переменной окружения ORACLE_HOME
Значение по умолчанию содержится
в переменной окружения ORACLE_HOME
/usr/local/pgsql
/home/Sybase
/home/sybase
После компиляции модуля РНР с соответствующим параметром нужно удостовериться
в успешном завершении процесса компиляции. Это можно осуществить с помощью функции
phpinf о (), которая предоставит всю необходимую для этого информацию.
Поддержка баз данных в системе Windows
Включение режима поддержки баз данных в модуле РНР для системы Windows предполагает
выполнение двух следующих этапов.
1. Копирование одной из динамически подключаемых библиотек (Dynamic Link
Library — DLL) в основной каталог.
2. Активизация режима поддержки базы данных.
После выполнения этих этапов, которые подробно описываются ниже, с помощью функции
phpinf о () можно проверить конфигурационные параметры, связанные с поддержкой
баз данных.
Копирование (ill-библиотеки
Все необходимые dll-библиотеки можно найти в архивном zip-файле, который ранее был
загружен с Web-узла РНР. Процесс загрузки архива и ручной установки модуля РНР более
подробно рассматривается в приложении А. После установки в каталоге, в котором был уста-
Глава 12. Хранение данных с использованием РНР 219
новлен пакет PHP, можно найти также и каталог e x t (например, c : \ p h p \ e x t ) . Имеыю
в этом каталоге и будут содержаться динамические библиотеки поддержки баз данных.
Скопируйте требуемый dll-файл в основной каталог РНР, такой как с : \php. Далее, для
активизации поддержки баз данных, например PostgreSQL в системе Windows 2000, скопируйте
файл с : \ p h p \ e x t \ p h p _ p g s q l . d l l в основной каталог РНР. (Для этого вполне подойдут
команды c d и сору.)
Если для установки модуля РНР использовалась автоматическая процедура инсталляции,
то dll-файлы поддержки баз данных по умолчанию не устанавливаются. Поэтому после завершения
автоматической процедуры установки все требуемые действия понадобится вып зл-
нить вручную, как описывалось выше.
Активизация режима поддержки баз данных
Для включения режима поддержки баз данных нужно внести изменения в конфигура ли-
онный файл p h p . i n i . Найдите в этом файле строки следующего вида:
; e x t e n s i o n = p h p _ p g s q l . d l l
; e x t e n s i o n = p h p _ m s q l . d l l
Каждый элемент этого перечня соответствует одной из баз данных, которая поддерживается
языком РНР. Легко заметить, что в начале каждой строки содержится точка с запятой.
Это означает, что все строки закомментированы и, следовательно, неактивны. Для включения
режима поддержки требуемой базы данных найдите соответствующую строку и удалите Е ее
начале точку с запятой. Например:
e x t e n s i o n = p h p _ p g s q l . d l l
В этой строке активизируется поддержка системы управления базами данных PostgreSQL.
Для того чтобы внесенные изменения вступили в силу, нужно перезапустить Web-сервер.
Если в файле p h p . i n i был включен режим поддержки базы данных, а соответствующая
динамическая библиотека не была скопирована, то при попытке запуска сценария будет ш-
ведено сообщение об ошибке примерно такого вида:
Unknown(): Unable to load dynamic l i b r a r y ' p h p _ p g s q l . d l l '.
The s p e c i f i e d module could not be found.
(Unknown () : He удается подключить динамическую библиотеку 'php_pgsql.dll .
Указанный модуль не найден.)
Если оба этапа были выполнены корректно (копирование dll-библиотеки и активизадия
соответствующего расширения в файле p h p . i n i ) , но при этом не было установлено гро-
граммное обеспечение баз данных, будет выведено следующее сообщение об ошибке:
The dynamic l i n k l i b r a r y m s q l . d l l could not be found in the s p e c i f i e d p a ti
(Динамически подключаемая библиотека m s q l . d ll отсутствует по указанному п^ти)
Для пользователей MS SQL. Кроме сервера баз данных необходимо также установить
набор средств MS SQL Server Client Tools. Его можно найти на устгно-
вочном компакт-диске MS SQL.
Для пользователей MySQL. Убедитесь, что вы используете <|айл
php_mysql. d l l для MySQL версии 4.0 или ниже или файл php_mysqli . d l l
для MySQL версии 4.1 или выше.
Взаимодействие с базой данных
Большинством систем управления базами данных поддерживается язык SQL (Structured
Query Language — язык структурированных запросов). Оператор SQL, называемый также запросом
(query), определяет те действия, которые должна выполнить система управления б;оой
220 Часть IV. Стандартные РНР-приложечия
данных. Например, SQL-запрос может быть предназначен для создания базы данных или таблицы,
сохранения информации в базе данных, извлечения или удаления данных и т.д.
Несмотря на то что практически все системы управления базами данных предоставляют
возможность использования языка SQL, при его использовании все же могут возникнуть определенные
нюансы. Так, сервер mSQL поддерживает только ограниченный набор операторов
SQL. В то же время Oracle и Sybase поддерживают свои собственные расширения SQL,
которые даже не определены в соответствующем стандарте.
Полное описание языка SQL не входит в задачи этой книги. Если же вы нуждаетесь в получении
дополнительной информации по этому вопросу, обратитесь к какой-нибудь другой
книге. Например, в книге mySQL, 2-е издание, вышедшей в Издательском доме "Вильяме",
рассматриваются вопросы использования сервера баз данных MySQL. Подробную информацию
о языке запросов SQL можно найти в книге SQL для "чайников", 5-е издание, которая
вышла в издательстве "Диалектика".
Рассмотрим несколько простых SQL-запросов, которые ниже будут использоваться в реальных
примерах сценариев РНР. Получить информацию из базы данных можно с помощью запроса
SELECT * FROM ммя_таблицы
Этот запрос позволяет извлечь все данные, содержащиеся в таблице имя_таблицы. Символ
* является специальным символом-заполнителем (wild card), который позволяет выбрать
все поля таблицы. Предположим, необходимо извлечь информацию из базы данных Catalog
(см. выше раздел "Системы управления базами данных"). В этой базе данных содержится одна
таблица Product с информацией обо всех товарах из каталога. Для получения всех данных
из таблицы Product можно воспользоваться запросом
SELECT * FROM Product
Для того чтобы добавить запись в таблицу, можно воспользоваться следующим SQL-запросом:
INSERT INTO имя_таблицы (ИМЯ_ПОЛЯ1, имя_поля2, ...)
VALUES {значение!, значение2, ...)
При выполнении этого запроса в таблице имя_таблицы будет создана новая запись,
в которой в соответствующих столбцах будут размещены заданные значения. Например, добавить
новый товар в каталог можно с помощью следующего запроса:
INSERT INTO Product (Type, Description, Size, Color, Price)
VALUES ("Тенниска", "100% хлопок", "L", "Черный", 20)
Обратите внимание на то, что все строки помещаются в двойные кавычки, а числа — нет.
Кроме того, следует заметить, что для каждого указанного поля задано соответствующее значение.
В противном случае будет сгенерировано сообщение об ошибке.
В следующем разделе вы узнаете, как сценарии РНР взаимодействуют с базами данных.
Использование РНР для взаимодействия с базами данных
Независимо от типа используемой базы данных для ее использования нужно выполнить
следующие шаги.
1. Подключиться к базе данных.
2. Передать системе управления базой данных SQL-запрос с инструкциями.
3. Получить и обработать данные.
4. Закрыть соединение с базой данных.
Все эти шаги более подробно рассматриваются в следующих разделах.
Глава 12. Хранение данных с использованием РНР 221
Подключение к базе данных
Перед использованием базы данных к ней нужно сначала подключиться. Для этого мо:кно
воспользоваться специальными функциями РНР, которым в качестве входных параметров
нужно передать следующую информацию.
•/ Местоположение. База данных может содержаться не только на том же компьютере,
где установлен интерпретатор РНР. Поэтому для подключения к базе
данных нужно указать имя компьютера, на котором она содержится. В качестве
такого имени можно использовать либо доменное имя (например,
mycompany.com), либо IP-адрес (172.17.204.2). Если же база дашых
расположена на том же компьютере, что и модуль РНР, то в качестве имени
узла достаточно указать имя l o c a l h o s t.
•S Регистрационное имя. Для того чтобы получить доступ к базе данных, необходимо
указать корректное регистрационное имя, которое должен предо повить
администратор.
•S Пароль. Для доступа к базе данных необходимо также указать пароль, который
тоже должен быть предоставлен администратором.
•S Имя базы данных. Поскольку система управления базами данных может одновременно
поддерживать несколько хранилищ, при подключении слелует
указать имя базы данных, которую вы хотите использовать.
Для повышения уровня защиты параметры соединения с базой данных следует
хранить в отдельном файле, который подключался бы в сценариях РНР с помощью
функции include (). Поскольку включаемые файлы обычно хранится
в безопасном месте (см. главу 8), то и содержащаяся в них информация также будет
в безопасности. Например, создадим файл i n f o . i n c со следующими параметрами
подключения к базе данных:
$host - "localhost";
$account = "admin";
$password = "secret";
$dbname = "Catalog";
После этого во все сценарии, в которых используется база данных, нужно добавить следующую
строку:
include("info.inc");
Для подключения к разным базам данных в языке РНР предназначены различные фзнк-
ции. В противном случае все было бы слишком просто. Однако в то же время следует ЗЕ метить,
что все функции достаточно похожи друг на друга. Так, при разработке Web-
приложений наиболее популярной системой управления базами данных по праву считается
MySQL. Для подключения к серверу MySQL 4.0 и более ранних версий предназначены функции
$connect = mysql_connect($host, $account, $password);
$db = mysql_select_db("Catalog", $connect);
Первая функция устанавливает соединение с системой управления базой данных, а втерая
позволяет выбрать конкретную базу данных. При взаимодействии с сервером MySQL 4.1
и более поздних версий используются другие функции:
$connect = mysqli_connect($host, $account, $password);
$db = mysqli_select_db($connect, "Catalog");
При подключении к базе данных некоторые СУБД требуют использования двух отдельных
функций (как в случае с MySQL). Например, для установки соединения с сервер ши
mSQL и Sybase используются похожие пары функций:
222 Часть IV. Стандартные РНР-приложения
$connect = msql_connect($host, $account, $password);
$db = msql_select_db("Catalog", $connect);
$connect = sybase_connect($host, Saccount, $password);
$db = sybaseselect_db("Catalog", $connect);
При подключении к базе данных другого типа может оказаться достаточно одной функции.
Например, для соединения с базой данных PostgreSQL можно воспользоваться функцией
$connect = pg_connect("host=$host user=$user
password=$password dbname=Catalog");
При подключении к другим базам данных используется аналогичный синтаксис, хотя
и с некоторыми отличиями. Так, для соединения с базой данных Oracle с помощью интерфейса
OCI8 предназначена функция
Sconnect = OCILogon($account, $password);
OWE;
При подключении к базе данных Oracle требуется, чтобы была установлена также
переменная окружения ORACLE_SID.
Функции, которые необходимо использовать для подключения к конкретной базе данных,
можно найти в справочном руководстве РНР. Это руководство можно загрузить с Web-узла
www.php.net.
Передача запросов к базе данных
После установки соединения с базой данных можно выполнять любые действия, связанные,
например, с извлечением, изменением или добавлением информации. Эти действия задаются
с использованием запросов SQL, передаваемых системе управления базой данных
с помощью специальных функций РНР. Как и при подключении к базе данных, эти функции
имеют похожий синтаксис, хотя каждая из них имеет и свои особенности. Например, передать
SQL-запрос серверу MySQL можно следующим образом:
$sql = "SELECT * FROM Product";
$result = mysql_query($sql, $connect);
В первой строке SQL-запрос присваивается переменной $sql. Этот запрос предназначен для
извлечения всех данных из таблицы Product. Функция mysql_query () передает SQL-запрос
$sql базе данных, определяемой идентификатором $connect. Затем полученные данные сохраняются
во временной таблице 1, указатель на которую содержится в переменной $result.
При использовании базы данных PostgreSQL запрос SQL может выглядеть так:
$sql = "SELECT * FROM Product";
$result = pg_query($connect, $sql);
В первой строке SQL-запрос сохраняется в переменной $sql, а во второй строке этот запрос
выполняется. В свою очередь, при взаимодействии с сервером Oracle для выполнения
аналогичных действий придется вызвать три функции:
$sql = "SELECT * FROM Product";
$query = OCIParse($connect, $sql);
$result • OCIExecute($query);
В первой строке создается SQL-запрос. (Обратите внимание, что первая строка одинакова
для всех трех баз данных.) Далее, для выполнения запроса и получения результата используются
две другие функции.
Любой SQL-запрос передается базе данных с использованием одной и той же функции.
В трех предыдущих примерах информация извлекалась из базы данных. Ниже приведен пример,
в котором осуществляется ввод данных.
$first_name = "Джон";
$last_name = "Смит";
Глава 12. Хранение данных с использованием РНР 223
$sql = "INSERT INTO Customer (firstName, lastName) VALUES
( ' $ f i r s t _ n a m e ' , '$last_name') ";
$ r e s u l t = m y s q l _ q u e r y ( $ s q l );
Если при обработке запроса SQL не было получено никаких данных, перемен юй
$ r e s u l t присваивается значение TRUE.
Перечень функций, предназначенных для передачи SQL-запросов базе данных, содер» ит-
ся в справочном руководстве РНР. Его можно найти на Web-узле www. p h p . n e t .
Обработка данных
Если запрос к базе данных предназначен для извлечения информации, то вполне естестиен-
но, что после получения данные должны быть каким-то образом обработаны. Например, н; их
основе на Web-странице можно создавать раскрывающиеся списки, формы со значениями полей
по умолчанию и т.д. Для обработки полученной информации ее необходимо сначала извлечь из
временной таблицы, в которой она была размещена после выполнения SQL-запроса. Для извлечения
данных из временных таблиц в языке РНР предназначены специальные функции.
Временная таблица состоит из строк и столбцов. Функции РНР позволяют извлечь информацию
из одной строки этой таблицы и сохранить ее в массиве. При этом имена попей
базы данных будут использоваться в качестве ключей. Для MySQL соответствующая функция
имеет следующий вид:
$row = m y s q l _ f e t c h _ a r r a y ( $ r e s u l t );
В примерах из предыдущего раздела результаты выполнения SQL-запроса сохранялись
в переменной $ r e s u l t . Функция mysql_f e t c h _ a r r a y () возвращает из временной таблицы
(которая определяется переменной $ r e s u l t ) одну строку данных.
После вызова функции mysql_f e t c h _ a r r a y () массив $row будет содержать такую
информацию:
$ r o w [ ' f i r s t N a m e ' ] = Джон
$ r o w [ ' l a s t N a m e ' ] = Смит
Для обработки всех данных, хранящихся во временной таблице, можно реализовать щ:кл,
в котором на каждой итерации будет извлекаться одна строка. Например, для базы данных
PostgreSQL можно воспользоваться циклом
w h i l e ( $ r o w = p g _ f e t c h _ a s o c ( $ r e s u l t ) )
{
foreach($row as $value)
{
echo "$value<br>";
}
}
Одна строка временной таблицы извлекается на каждой итерации цикла w h i l e . При этом
на каждой такой итерации создается массив $row. В свою очередь, для прохода по массиву
$row и вывода соответствующих значений используется цикл f o r e a c h .
В следующем фрагменте для извлечения информации из временной таблицы PostgreS QL
используется цикл f o r . При этом достигается аналогичный результат:
$Nrows = pg_num_rows($result);
f o r ( $ i = 0 ; $i<$Nrows; $i++)
{
$row = pg_fetch_row($result,$i);
foreach($row as $value)
{
echo "$value<br>";
}
}
224 Часть IV. Стандартные PHP-приложения
В приведенном примере функция pg_num_rows () возвращает количество строк временной
таблицы. (При работе с MySQL можно воспользоваться аналогичной функцией
mysql_num_rows ($result).) На каждой итерации цикла for из таблицы выбирается, а затем
обрабатывается одна строка. Проход по каждой строке (т.е. по массиву $row) осуществляется
с помощью цикла foreach. Обратите внимание на то, что функции pg_fetch_row()
передается параметр $i, определяющий номер строки, которую нужно извлечь из таблицы.
При работе с базой данных Oracle можно также выполнить аналогичные действия:
$Nfields = OCINumCols($result);
while (OCIFetch($result))
{ f o r ( $ i = l ; $i<=$Nfields; $i++)
{
$value = OCIResult($result, $i);
echo "$value<br>";
}
}
В данном примере в переменной $Nfields содержится количество полей таблицы,
а функция OCIFetch () используется для извлечения из таблицы одной строки. Цикл while
выполняется до тех пор, пока не будут обработаны все строки временной таблицы. Функция
OCIResult () возвращает значение из одного поля строки, полученной с помощью функции
OCIFetch (). Цикл for предназначен для прохода и отображения значений всех полей текущей
строки временной таблицы.
В предыдущих примерах приведен минимальный набор функций, которого достаточно
для взаимодействия с реляционной базой данных. Однако следует заметить, что в языке
РНР для работы с каждой системой управления базами данных имеется свой собственный
богатый набор функций. Например, функция mysql_af fect_rows () возвращает количество
строк, которые были изменены в процессе выполнения запроса, а функция
pg_f ield_name () возвращает имена полей.
Для более детального знакомства с функциями, предназначенными для работы с различными
базами данных, обратитесь к справочному руководству РНР, которое можно найти на
Web-узле www.php.net. Там же вы найдете и некоторые примеры. Много полезной информации
о базах данных MySQL содержится в книге mySQL, 2-е издание, которая вышла в Издательском
доме "Вильяме".
Закрытие соединения с базой данных
По завершении работы сценария любое открытое соединение с базой данных автоматически
закрывается. Однако хорошим стилем программирования является закрытие соединения
в самом сценарии (с помощью специальной функции РНР). Это позволит избежать многих
потенциальных проблем. Например, закрыть соединение с базой данных MySQL можно следующим
образом:
mysql_close($connect);
Ниже приведены аналогичные функции для других баз данных.
ocilogoff($connect); # Oracle
pg_close($connect); # PostgreSQL
mssql_close($connect); # MS SQL
Обработка ошибок
Установка соединения с базой данных с использованием функций _connect () далеко не
всегда завершается успешно. Например, сервер баз данных может оказаться незапущенным, или
при подключении могут быть указаны неверные регистрационные данные. Так, при попытке подключения
к базе данных MySQL с неверным паролем будет выведено следующее сообщение:
Глава 12. Хранение данных с использованием РНР 225
Warning: m y s q l _ c o n n e c t ( ) : Access denied for user:
1 r o o t @ l o c a l h o s t ' (Using password: YES) in
c : \ t e s t l 2 . p h p on l i n e 10
(Предупреждение: m y s q l _ c o n n e c t ( ) : Доступ
для пользователя запрещен:
' r o o t S l o c a l h o s t ' (Использование пароля: ДА)
в файле c : \ t e s t l 2 . p h p в строке 10)
В приведенном сообщении содержится регистрационное имя и указывается, использовался
ли пароль при попытке соединения. При этом сам пароль не отображается. Получение такого
сообщения свидетельствует о том, что доступ к базе данных MySQL запрещен, поскольку
при установке соединения использовались неверные регистрационные данные.
Это лишь предупреждение, а не сообщение об ошибке. Поэтому после его вывода выполнение
сценария продолжится. Однако это далеко не всегда будет корректным. Дело в том, что, если
невозможно получить доступ к базе данных, оставшаяся часть сценария может выполнят ься
с ошибками. Поэтому лучше воспользоваться функцией d i e () .которая позволит прервать зы-
полнение сценария в случае неудачной попытки соединения с базой данных. Ниже приведен
пример использования функции d i e () при подключении к базе данных PostgreSQL.
$connect = p g _ c o n n e c t ( " h o s t = $ h o s t user=$user
password=$password dbname=Catalog")
or dieC'He удалось подключиться к базе данных"),-
Если попытка подключения к базе данных по каким-то причинам завершилась неуда! ей,
выполнение сценария будет прервано и отобразится сообщение, указанное в качестве пера-
метра функции d i e ( ).
При извлечении данных из временной таблицы также возможно возникновение различных
проблем и, как следствие, вывод предупреждающих сообщений. Например, рассмотрим
случай, когда в сценарии содержится следующий фрагмент:
$sql = "SELECT * FROM P r o d u c t t ";
$ r e s u l t = m y s q l _ q u e r y ( $ s q l );
$row = m y s q l _ f e t c h _ a r r a y ( $ r e s u l t );
В результате использования неверного имени таблицы (лишний символ t в имени Produ : t)
отобразится следующее предупреждающее сообщение:
Warning: mysql_fetch_array(): supplied argument is not a
valid MySQL result resource in test.php on line 9
(Предупреждение: mysql_fetch_array():
используемая переменная является некорректным
результатом выполнения запроса к базе данных
MySQL в файле test.php в строке 9)
В этом сообщении указано, что в переменной $ r e s u l t не содержится корректных хан-
ных, т.е. ее нельзя использовать в качестве указателя на временную таблицу с результатами
обработки запроса. Обычно подобные сообщения свидетельствуют о том, что SQL-запрос
нельзя выполнить корректно или были получены не те данные, которые ожидались. В приведенном
примере использование неверного имени таблицы привело к тому, что перемен юй
$ r e s u l t было присвоено значение FALSE. В свою очередь, передача этого значения в качестве
параметра функции mysql_f e t c h _ a r r a y () может привести (и привела) к получению
только неверного результата.
Обратите внимание, что при вызове"*функции mysql_query () не было выведено никакого
предупреждающего сообщения, хотя ошибка была допущена именно в самом запросе.
Для того чтобы вывести ошибку и прервать выполнение сценария при неверно заданном запросе
SQL, можно воспользоваться специальной функцией m y s q l _ e r r o r ( ) . При ее использовании
можно более точно выявить причину и место возникновения ошибки. Для этого предыдущий
фрагмент можно переписать так:
226 Часть IV. Стандартные РНР-приложеиия
$sql = "SELECT * FROM Productt";
$result = mysql_query($sql)
or die("Запрос не выполнен: ".mysql_error());
$row = mysql_fetch_array($result);
Это приведет к получению следующего результата:
Запрос не выполнен: Table 'Catalog.productt' doesn't exist
(Запрос не выполнен: Таблица 'Catalog.productt' не существует)
Если в приведенном фрагменте попытка выполнения запроса завершилась неудачно,
функция d i e () выведет сообщение с ошибкой SQL (которая генерируется функцией
mysql_error ()) и прервет выполнение сценария.
Общие процедуры обработок ошибок в сценариях РНР применимы и при работе с базами
данных. Например, сообщения об ошибках можно не выводить на экран, а записывать в специальном
журнале. (Об обработке ошибок см. в главе 4.)
Собирая все вместе...
В предыдущих разделах рассматривались функции, которые нужно использовать для реализации
взаимодействия РНР-приложений с базами данных. В этом разделе все эти функции
будут совместно использоваться в полнофункциональном сценарии.
В первом примере используется база данных PostgreSQL с именем Sales (Продажи),
в которой содержится таблица Customer (Покупатель). В этой таблице содержатся имена,
фамилии и номера телефонов покупателей. В листинге 12.2 приведен код сценария, отображающего
все содержимое таблицы Customer на Web-странице.
Листинг 12.2. Сценарий для отображения информации о покупателях
<?php
/* Имя сценария: DisplayCustomers
* Описание: этот сценарий позволяет извлечь из базы
* данных PostgreSQL всю информацию о
* покупателях и вывести ее на Web-странице.
*/
include (" info, inc") ,- # содержит параметры соединения с базой данных
$connect = pg_connect("host=$host user=$user
password=$password dbname=Sales")
or die("He удалось подключиться к базе данных");
$sql = "SELECT * from Customer";
$result = pg_query($sql)
or die ("Запрос не выполнен :" .mysql_error ()) ,-
$Nrows = pg_num_rows($result);
echo "<html>
<headxtitle>CnncoK пoкyпaтeлeй</title></head>
<body>
<table width=\"100%\" border=\"0\">\n";
for($i=0;$i<$Nrows;$i++)
{
echo "<tr>";
$row = pg_fetch_row($result,$i);
echo "<td>{$row[l]}, {$row[0]}</td>
<td>{$row[2]}</td>";
echo "</tr>\n";
}
echo "</tablex/body></html>"; . .
?>
Глава 12. Хранение данных с использованием РНР 227
Этот сценарий извлекает из базы данных Customer всю информацию о покупателях,
а затем с помощью цикла f o r выводит данные на Web-странице в виде таблицы HTML.
Во втором примере (листинг 12.3) создается группа флажков, с использованием которых
пользователь может выбрать вид товара, который он хочет просмотреть. При этом виды го-
вара выбираются из базы данных MySQL. Таблица этой базы данных состоит из двух полги,
ProductType (Тип товара) и D e s c r i p t i o n (Описание).
Листинг 12.3. Сценарий для создания группы флажков
<html>
<head><title>TecTHpoBaHMe <J>ai«iOB</title></head>
<body>
<?php
/* Имя сценария: DisplayCheckboxes
* Описание: получает информацию из базы данных MySQL и
* создает группу флажков на Web-странице.
*/
include("info.inc"); # содержит параметры соединения с базой данных
$connection = mysql_connect($host,$user,$password)
or die ("He удалось подключиться к серверу");
$db = mysql_select_db("Catalog",$connection)
or die ("He удалось выбрать базу данных");
$query = "SELECT * FROM ProductType";
$result = mysql_query($query)
or die("3anpoc не выполнен: " .mysql_error () ) ,-
echo "<htmlxhead><title>ToBapbi</title></head>
<bodyxdiv style='margin-left: .2in'>
<пЗ>Какой вид товаров Вас интересует?</пЗ>\п";
## создание формы с флажками ##
echo "<form action='processform.php' method='post'>\n";
echo "<hrxtable width='100%'>" ;
while ($row = mysql_fetch_array($result))
{
echo "<tr>";
echo "<td width='20%'><b><input type='checkbox'
name=\"interest['ProductType']\ "
value=\"{$row['ProductType']}\">{$row['ProductType']}
< / b x / t d > \ n " ;
echo "<td>{$row['Description']}</td>";
echo "</tr>\n";
}
echo "</table>";
echo "<pxinput type='submit' value='Выбрать товар'>
</form>\n";
?>
< / d i v x / b o d y x / h t m l >
В приведенном сценарии создается форма с HTML-таблицей. В цикле w h i l e из временной
таблицы $ r e s u l t выбираются строки, данные из которых затем используются при создании
строк HTML-таблицы. Этот цикл завершается после обработки всех строк временной
таблицы, полученной в результате выполнения SQL-запроса.
Обратите внимание на вывод элементов массива в ячейках таблицы с испольчо-
ванием фигурных скобок. В противном случае при синтаксическом анализе буд;ет
сгенерирована ошибка.
228 Часть IV. Стандартные РНР-приложенля
При выполнении сценария из листинга 12.3 будет сгенерирована страница, показанная на
рис. 12.1. В группе флажков представлены все виды товаров, информация о которых содержится
в базе данных.
Ц Товары - Microsoft Internet txplorer
Файл Правка Вид Избранное Сервис Справка
Ср Назад " СЗ ' \щ\ [flf| t ...Поиск ^ ' ? Избранное ^2)
Адр.**с: { Щ http://localhost/test/DiaplayCheckboxes.php
шш
Переход
Какой вид товаров Вас интересует?
П Мебель Мебель для всех комнат.
Г" Одежда Все виды одежды для мужчин, женщин, детей и младенцев.
О Музыка CD-диски всех известных музыкантов
Выбрать товар
Цу Готово * ••* Местная интрасеть
Рис. 12.1. Web-страница с флажками, сгенерированная в результате выполнения сценария
из листинга 12.3
использование ftactuufienusi SQClte
Расширение SQLite позволяет взаимодействовать с данными, как будто бы они хранятся
в базе данных, а не в обычных файлах. При этом не требуется устанавливать никакого специального
программного обеспечения, а для извлечения информации можно использовать язык
SQL. Расширение SQLite позволяет использовать основные преимущества текстовых файлов,
которые связаны с незначительным потреблением вычислительных ресурсов. Кроме того, расширением
SQLite предоставляются и преимущества SQL, поскольку нет необходимости изучать
команды операционных систем, предназначенные для открытия и манипулирования файлами.
В некоторых случаях расширение SQLite обеспечивает и более высокую скорость доступа
к данным. Однако расширение SQLite не лишено и некоторых существенных недостатков. К ним
следует отнести низкий уровень защищенности информации и невозможность обработки сложных
структур данных. Одним словом, можно сказать, что расширение SQLite обеспечивает быстрый
и простой доступ к данным, хранящимся в текстовых файлах, однако его нельзя рассматривать
как альтернативу баз данных в тех случаях, когда нужно работать с большими объемами
информации, сложными структурами данных или обеспечить высокий уровень безопасности.
Методы хранения и извлечения данных с использованием средств SQLite аналогичны методам,
которые применяются при работе с базами данных. Для взаимодействия с файлом
Глава 12. Хранение данных с использованием РНР 229
данных используется язык SQL, а для передачи SQL-запросов и получения данных— функции
РНР. При этом необходимо выполнить аналогичные действия.
1. Установить соединение с файлом данных.
Так же как и при работе с базами данных, сначала нужно установить соединение
с файлом данных. Для этого предназначена следующая функция РНР:
$db = sqlite_open("testdb");
Функция s q l i t e _ o p e n () позволяет открыть файл t e s t d b . Если указанный файл не
существует, будет создан новый файл.
2. Передать SQL-запрос.
Для передачи SQL-запроса предназначена функция s q l i t e _ q u e r y ().
$sql = "SELECT * FROM Product";
$result = sqlite_query($db, $sql);
3. Обработать полученные данные.
Как и при взаимодействии с базами данных, полученная в результате обработки SOL-
запроса информация сохраняется во временной таблице. В языке РНР имеются функции,
массиве. При этом в качестве ключей массива будут использоваться имена полей.
$row = s q l i t e _ f e t c h _ a r r a y ( $ r e s u l t );
После вызова этой функции в массиве $row будет содержаться следующая информащя:
$row['firstName'] = Джон
$row['lastName'] = Смит
Для обработки всех строк временной таблицы можно воспользоваться циклом while.
while($row=sqlite_fetch_array($result))
{
foreach($row as $value)
}
echo "$value<br>";
4. Закрыть соединение с файлом данных.
После завершения работы с файлом его нужно закрыть с помощью функции
sqlite_close($db);
При использовании расширения SQLite можно применять те же основные принципы
обработки ошибок, которые рассматривались в разделе "Обработка ошибок". Напримгр,
очень полезной является функция d i e ( ) . В расширении SQLite имеется также функция
s q l i t e _ e r r o r (), которая позволяет генерировать сообщения об ошибках SQLite в слугае
неудачной обработки SQL-запроса. Например:
$sql = "SELECT * FROM Product";
$result = sqlite_query($sql)
or die("Запрос не выполнен:".sqlite_error());
$row = sqlite_fetch_array($result);
Весь материал разделов, посвященных работе с базами данных, можно в полной мере эт-
нести и к расширению SQLite. Единственное отличие заключается в том, что при использовании
SQLite информация хранится в простых текстовых файлах, а не в специальных 6aiax
данных, которые создаются с помощью специализированного программного обеспечения.
230 Часть IV. Стандартные РНР-приложения
Глава 13
PHP и операционная система
3 aificu главе...
> Работа с файлами
> Запуск внешних программ
> Передача файлов с одного компьютера на другой
> Отправка электронных сообщений и вложений
ШГ^ ак и любой другой универсальный язык программирования, РНР предоставляет пол-
т \* ный набор средств для работы с файлами. С помощью языка РНР с информацией,
хранящейся на компьютере, можно выполнять любые действия. Так, файлы можно создавать,
копировать, удалять или выполнять их поиск. Язык РНР позволяет также запускать любые
программы, пересылать файлы с одного компьютера на другой и передавать информацию по
электронной почте. В этой главе рассматриваются все те возможности языка РНР, которые
позволяют ощутить реальную мощь современной вычислительной техники.
Управление файлами
Информация, которая хранится на жестком диске, упорядочена в файлах (file). В свою очередь,
для обеспечения их более эффективной обработки (например, для поиска) файлы распределены
по каталогам (directory) или папкам (folder). Набор файлов и каталогов называется файловой
системой (file system). Она имеет иерархическую структуру и содержит единственный
корневой (root) каталог, такой как С: \ в операционной системе Windows или / — в Linux.
В корневом каталоге содержатся другие каталоги, каждый из которых также содержит другие
каталоги, и т.д. При этом количество вложенных каталогов может быть произвольным.
В общем случае каталог следует рассматривать как специальный файл, используемый для
объединения других файлов. В каталоге содержится список файлов и информация, необходимая
операционной системе для их поиска. Очевидно, что каталог может содержать как файлы,
так и другие каталоги.
В языке РНР имеются функции, которые позволяют открывать файлы и считывать или записывать
в них информацию (см. главу 12). Файлы можно копировать, удалять, переименовывать,
а также выполнять над ними много других действий. Именно такие функции и рассматриваются
в следующих разделах. Кроме того, в этой главе вы узнаете, как управлять
каталогами и исследовать их содержимое.
В этой главе рассматривается только часть функций для работы с файлами. Если
над файлами или каталогами необходимо выполнить какие-либо действия, обратитесь
к справочному руководству и посмотрите, не определена ли в языке РНР
соответствующая функция. Если такая функция отсутствует, можно воспользоваться
командами операционной системы или программой, написанной на другом
языке. Все эти возможности более подробно рассматриваются ниже, в разделе
"Использование команд операционной системы".
Получение информации о файле
Зачастую требуется получить какие-нибудь данные о файле. В языке РНР определены
функции, которые в сценарии позволяют получить всю необходимую информацию.
Для того чтобы узнать, существует ли файл, предназначена функция f i l e _ e x i s t s ().
$result = f i l e _ e x i s t s ( " s t u f f . t x t " );
После вызова этой функции переменной $ r e s u l t присваивается либо значение TRUE, либо
FALSE. Обычно функция f i l e _ e x i s t s () используется в условных операторах. Например:
i f ( ! f i l e _ e x i s t s ( " s t u f f . t x t " ) )
{
echo "Файл не найден!\п";
}
После того как вы убедитесь в существовании файла, можно приступать к сбору информации
о нем.
В табл. 13.1 приведены функции, позволяющие получить полезную информацию о файлах
Таблица 13.1. Функции, предоставляющие информацию о файлах
Функция Описание Возвращаемое значение
is_file("stuff.txt")
is_dir("stuff.txt")
is_executable("do.txt")
is_writable("stuff.txt")
is_readable("stuff.txt")
fileatime("stuff.txt")
filectime("stuff.txt")
filemtime("stuff.txt")
filegroup("stuff.txt")
fileowner("s tuf f.txt")
filesize("stuff.txt")
filetype("stuff.txt")
Проверяет, является ли файл обычным
файлом, или представляет собой каталог,
или любой другой файл специального типа
Проверяет, является ли файл каталогом
Проверяет, является ли файл исполняемым
Проверяет, можно ли записывать данные в
файл
Проверяет, можно ли из файла считывать
данные
Возвращает время последнего доступа
к файлу
Возвращает время создания файла
Возвращает время последней модификации
файла
Возвращает присвоенный файлу
идентификатор группы
Возвращает идентификатор владельца
файла
Возвращает размер файла в байтах
Возвращает тип файла
basename (" / 1 1 / d o . t x t " ) Возвращает имя файла на основе
указанного пути
d i r n a m e (" / t i / d o . t x t " ) Возвращает имя каталога, где размещается
файл
TRUE ИЛИ FALSE
TRUE ИЛИ FALSE
TRUE ИЛИ FALSE
TRUE ИЛИ FALSE
TRUE ИЛИ FALSE
Время в формате Unix
(например, 10571961221
ИЛИ FALSE
Время в формате Unix или
FALSE
Время в формате Unix или
FALSE
Целое число (идентификато)
группы) ИЛИ FALSE
Целое число (идентификато)
пользователя) или F A L SE
Целое число или F A L SE
Тип файла (например, f i l e ,
d i r , l i n k , char) ИЛИ
F A L S E при вoзникнoвeни^
ошибки или невозможное™
определения типа
d o . t x t
/ t i
232 Часть IV. Стандартные РНР-приложенм
Часть информации можно получить лишь в операционных системах Linux/Unix/Mac, другую
ее часть — и в системе Windows.
В языке РНР имеется полезная функция p a t h i n f о ( ) , которая позволяет получить путь
и имя файла. Например:
$pinfo = p a t h i n f о (" / t o p d i r / n e x t d i r / s t u f f . t x t " ) ,-
После вызова этой функции в массиве $ p i n f о будет содержаться следующая информация:
$pinfо[dirname] = /topdir/nextdir
$pinfo[basename] = stuff.txt
$pinfо[extension] = txt
При проверке файла с помощью функции вида 1з_нечто() любая ошибка при
использовании аргумента, например опечатка в имени файла, приведет к возврату
значения FALSE. Например, при вызове функции i s _ d i r ("tyme") будет
получено значение FALSE, если tyme является файлом, а не каталогом. Это же
значение будет возвращено, если файла tyme не существует.
Некоторые функции, приведенные в таблице, возвращают результат в формате
времени Unix. Для преобразования его к стандартному виду даты следует воспользоваться
функцией d a t e () (см. главу 5).
Копирование, переименование и удаление файлов
В главе 12 рассматривались вопросы создания файлов и записи информации в них. В данном
разделе описываются другие возможности работы с файлами, в том числе копирование и удаление.
РНР позволяет скопировать существующий файл в новый и получить два идентичных
файла с разными именами. Копирование файлов особенно полезно при создании резервных
архивов важной информации. Для этого в РНР используется функция сору ( ).
сору ("f i l e o l d . t x t " , " f i l e n e w . t x t " ) ,-
После выполнения этой функции файл f i l e o l d . t x t скопируется в f i l e n e w . t x t . Если
же файл с именем f i l e n e w . t x t уже существует, он будет перезаписан. Чтобы избежать
этого, следует воспользоваться таким фрагментом кода:
i f ( ! f i l e _ e x i s t s ( " f i l e n e w . t x t " ) )
{
c o p y ( " f i l e o l d . t x t " , "filenew.txt");
}
e l s e
{
echo "Файл уже существует!\n";
}
Для переименования файла предназначена функция rename ( ):
r e n a m e ( " o l d n a m e . t x t " , "newname.txt");
Если попытаться присвоить файлу уже существующее имя, будет выведено предупреждающее
сообщение и файл не будет переименован:
Warning: r e n a m e ( f i l e o l d . t x t , f i l e n e w . t x t ) : F i l e e x i s t s in c : \ t e s t . p hp
on l i n e 17
Для удаления ненужного файла можно воспользоваться функцией u n l i n k ( ):
u n l i n k ( " b a d f i l e . t x t " ) ;
Глава 13. PHP и операционная система 233
После вызова этой функции файл badf i l e . t x t будет удален. Однако следует заметигь,
что, если файл не существует, никакое сообщение об ошибке не отобразится. Поэтому следует
быть внимательным при использовании этой функции.
Организация файлов
Как уже отмечалось, файлы размещаются в каталогах (directory), которые также называют
папками (folder). В этом разделе рассматриваются функции, позволяющие создавать
и удалять каталоги, а также получать списки находящихся в них файлов.
Создание каталога
Для создания каталога в языке РНР используется функция mkdi г ( ):
mkdir("testdir");
После вызова этой функции будет создан новый каталог с именем t e s t d i r в той же папке,
где находится и основной сценарий РНР. Например, если сценарий расположен по адр гсу
/ t e s t / t e s t .php, то новый каталог будет помещен в папку / t e s t / t e s t d i r . Если попытаться
создать каталог с уже существующим именем, будет выведено предупреждающее сообщение
следующего вида:
Warning: m k d i r ( ) : F i l e e x i s t s in d : / t e s t / t e s t . p h p on l i n e 5
Для проверки существования каталога с определенным именем можно воспользоваться
функцией i s _ d i r ( ) . Рассмотрим следующий фрагмент кода:
i f ( ! i s _ d i r ( " m y n e w d i r " ) )
{
mkdir("mynewdir");
}
e l se
{
echo "Каталог уже существует! ";
}
После создания каталога с его содержимым можно выполнять любые действия. Например,
можно скопировать или удалить файлы (см. раздел "Копирование, переименование и
удаление файлов").
Для создания каталога в другом месте следует задать полный путь к нему. Например:
m k d i r ( " / t o p d i r / n e x t d i r / m y n e w d i r " ) ;
В функции mkdir () можно также использовать относительный путь к каталогу, как
в следующем примере.
m k d i r ( " . . / m y n e w d i r " ) ;
Если сценарий находится в каталоге / t o p d i r / t e s t / m a k e d i r . p h p , то в результате
выполнения этой команды новый каталог будет размещен по адресу / t o p d i r / m y n e w d i r.
Для изменения имени каталога в РНР предусмотрена функция следующего вида:
c h d i r (" . . / a n o t h e r d i r " ) ,-
Получение списка файлов каталога
Очень часто необходимо знать содержимое каталогов. Например, нужно вывести пользователю
список предлагаемых для загрузки файлов или извлечь изображения из каталога, чтобы
отобразить их в окне браузера.
РНР предоставляет набор разнообразных функций для открытия и чтения каталогов. Рассмотрим
следующую строку кода:
$dh = o p e n d i r ( " / t o p d i r / t e s t d i r " );
234 Часть IV. Стандартные PHP-приложения
Функция opendir () позволяет открыть каталог и, таким образом, получить к нему доступ.
Если же попытаться обратиться к несуществующему каталогу, будет выведено следующее
предупреждающее сообщение:
Warning: opendir(testdir): failed to open dir: Invalid argument in
testl3.php on line 5
В строке, содержащей вызов функции opendir (), переменная $dh используется в качестве
дескриптора каталога (directory handle). Он является своеобразным указателем, который
впоследствии можно использовать для обращения к файлам этого каталога. Для считывания
имени файла из данного каталога в РНР предназначена функция r e a d d i r ():
$filename = readdir($dh);
После ее вызова в переменной $f ilename будет содержаться имя файла, но не полный путь
к нему. Чтобы считать все файлы каталога, можно воспользоваться циклом while. Например:
while($filename = readdir($dh))
{
echo $filename. "\n";
}
Следует также отметить, что при использовании функции r e a d d i r () порядок считывания
файлов может быть произвольным.
Предположим теперь, что на Web-странице необходимо создать "картинную галерею",
в которой будут содержаться изображения из определенного каталога. Для этого можно воспользоваться
функциями opendir () и r e a d d i r (). В листинге 13.1 приведен сценарий, который
позволяет это осуществить.
Листинг 13.1. Сценарий, создающий "картинную галерею"
<?php
/*Имя сценария: displayGallery
•Описание: отображает все картинки, хранящиеся в
* определенном каталоге.
*/
echo "<html><head><title>Гaлepeя M3o6pa;KeHttH</title></head>
<body>";
$dir = "../testl/testdir/"; #8
$dh = opendir($dir); #9
while($filename = readdir($dh)) #10
{
$filepath = $dir.$filename; #12
if(is_file($filepath)and ereg("\.jpg$",$filename)) #13
{
$gallery[] == $filepath;
}
}
sort($gallery); #16
foreach($gallery as $image) #17
{
echo "<hr>";
echo "<img src='$image'><br>";
}
?>
</bodyx/html>'
Глава 13. PHP и операционная система 235
Обратите внимание на наличие номеров в конце некоторых строк. Рассмотрим код этих
строк более подробно.
S Строка 8. Переменной $dir присваивается значение пути, которое будет
впоследствии использоваться в сценарии. Обратите внимание на наличие со-
сой черты (/) в конце строки, а также на использование этого символа вместо
обратной косой (\) (даже в операционной системе Windows).
S Строка 9. В этой строке происходит открытие каталога.
•S Строка 10. Начинается цикл while, считывающий все файлы из каталога.
•S Строка 12. Создается переменная $f i l e p a t h , значение которой соответ:т-
вует полному пути к файлу.
Если в строке 8 не включить символ /, переменная $f i l e p a t h будет содержать
ошибочное значение.
•S Строка 13. В этой строке проверяется, является ли файл графическим, -е.
имеет ли он расширение . jpg. Если это так, полный путь к изображению добавляется
в массив с именем $gallery.
•S Строка 16. В этой строке осуществляется сортировка значений массива
$ g a l l e r y в алфавитном порядке.
S Строка 17. С помощью цикла foreach изображения выводятся на Wsb-
страницу.
использование команд операционной
CUCtfieAtbl
Операционная система содержит большое количество команд, которые пользователь монет
выполнить из командной строки. Например, если необходимо вывести список файлов каталога i LTH
скопировать файл, в Windows можно воспользоваться командами d i r и сору, а в Unix/Linux — Is
и ср. (Для доступа к консольному окну, позволяющему работать с командной строкой в операционной
системе Windows 2000, нужно выбрать следующую команду меню: Start^Programo^
Accessories^Command Prompt (ПускОПрограммы^Стандартные1* Командная строка.)
В этом разделе предполагается, что читатель знаком с синтаксисом и назначением системных
команд используемой операционной системы. Описание этой области выходит за
рамки настоящей книги. В данном разделе рассказывается о том, как запустить команды о ю-
рационной системы из сценария РНР.
В РНР имеется множество функций, предназначенных для выполнения тех или иных действий.
Например, содержимое каталога можно считать с помощью функций opendir () и readdii ()
(см. предыдущий раздел), а файлы можно скопировать с использованием функции сору ()
Однако в некоторых случаях может потребоваться выполнить некоторые действия,
для которых не существует специальных функций РНР. Например, иногда нужно скопировать
каталог со всем его содержимым, просмотреть или изменить текущий путь, очистить
экран и т.д. В некоторых случаях может оказаться, что проще использовать <о-
манды операционной системы, например I s или d i r , чем встроенные функции РНР —
opendir или r e a d d i r . Вам также может понадобиться вызвать программу, написш-
ную на другом языке программирования, например на Perl. Нет проблем! Все эти задг.чи
можно легко решить с помощью РНР.
ЗУ
236 Часть IV. Стандартные РНР-приложения
Сообщения об ошибках при вызове системных команд
Ни один из используемых методов РНР для вызова системных команд не поддерживает вывод или возврат j
| сообщений при ошибках. Вы знаете, что системная команда не сработала, поскольку не получили нужный
| результат. Но что именно не так — неизвестно.
! Для вывода сообщений об ошибках при несрабатывании системной команды необходимо добавить несколько !
| символов в строку вызова. Таковыми для большинства операционных систем являются 2>&1. Рассмотрим
! следующий пример:
| $ r e s u l t = s y s t e m ) " d i c : \ p h p " );
I-В данном случае функция s y s t em { ) используется для вывода содержимого каталога c : \ p h p,
| но системная команда d i r написана с ошибкой. Не существует такой команды, как d i , соответственно
I ничего выведено не будет. Добавим нужные символы:
I $ r e s u l t = s y s t e m ( " d i c : \ p h p 2>&1");
! В этом случае отобразится сообщение об ошибке. В операционной системе Windows 2000 оно будет иметь
| следующий вид:
! 'di' is not recognized as an internal or external command, operable
; program or batch file
Заметьте, что набор символов 2>&1 используется без пробелов.
I ::::• :• : . ; ~~ L - ,
Для вызова системных команд или внешних программ в РНР предусмотрены следующие
методы.
S Обратные одинарные кавычки (" "). Для вызова системной команды ее
имя можно заключить в обратные одинарные кавычки, и результат работы
отобразится на экране.
•/ Функция system (). Вызывает команду операционной системы, выводит результат
выполнения на экран и возвращает последнюю строку вывода.
S Функция exec (). Вызывает команду операционной системы, результат выполнения
сохраняет в массиве и возвращает последнюю строку результата
выполнения.
•S Функция p a s s t h r u (). Вызывает системную команду и отображает результат
выполнения на экране.
В общем случае РНР позволяет вызывать любые команды. При этом они будут выполняться
точно так же, как если бы они были вызваны непосредственно из командной строки
операционной системы. Можно вызывать простые команды, такие как I s или d i r , rename
или mv, rm или del, можно перенаправлять результаты выполнения, вызывать две команды
в одной строке и т.д., т.е. вся функциональность, которая поддерживается операционной системой,
может быть доступна и в сценариях РНР. Ниже приводятся примеры системных команд,
которые можно вызвать из кода РНР.
dir
rm badfile.txt
dir | sort
cd c:\php ; dir (Недоступна в Windows)
"cd c:\php && dir" (Для Windows 2000)
dir > dirfile
sort < unsortedfile.txt
Глава 13. PHP и операционная система 237
<*oS&
Иногда процесс выполнения системной команды занимает большой промежуток
времени. РНР позволяет вызвать команду в фоновом режиме (если, конечно, используемая
операционная система поддерживает его), в то время как сценарий
РНР будет продолжать выполняться. В этом случае результат вызова системней
команды необходимо перенаправить в отдельный файл, а не сохранять в переменной
сценария.
Рассмотрим теперь различные методы вызова команд операционной системы из РНР fio-
лее подробно.
Использование одинарных кавычек
Самый простой способ вызвать системную команду из РНР •— поместить ее в обрати »ге
одинарные кавычки. Например:
$ r e s u l t .= "dir c:\php4;
Переменная $ r e s u l t будет содержать результат выполнения команды d i r , т.е. информацию
о содержимом каталога с: \php:
Volume in drive C has no label.
Volume Serial Number is 394E-15E5
Directory of c:\php
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
02/25/2004
10:
10:
04:
04:
04:
04:
04:
04:
04:
04:
04:
04:
04
04
04;
04
04;
04
04
04
04
04
04
04
04
04
04
04
04
04
04
04
04
48a
48a
30p
30p
:3 0p
:3 0p
:3 0p
:3 0p
:30p
:3 0p
:3 0p
:3 0p
:3 0p
:30p
:30p
:30p
:3 0p
:30p
:30p
:30p
:30p
:30p
:30p
:30p
:3 0p
:3 0p
:30p
:30p
:30p
:30p
:30p
:3 0p
:3 0p
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
417,792
90,112
346,624
70
32,081
876,544
47,027
165,643
233,472
3,208
57,344
18,151
278,800
53,248
28,672
28,672
3,872
39,284
40,899
40,960
36,864
36,864
53,248
503,320
•28,672
28,672
3,452,92 8 php5
dev
ext
extras
fdftk.dll
fribidi.dll
gds32.dll
go-pear.bat
install.txt
libeay32.dll
libintl-l.dll
libmhash.dll
libmysql.dll
license.txt
msql.dll
news.txt
ntwdblib.dll
PEAR
php-cgi.exe
php-win.exe
php.exe
php.gi f
php.ini-dist
php.ini-recommended
php5activescript.dll
php5apache.dll
php5apache2.dll
php5apache_hooks.dll
php5embed.lib
php5isapi.dll
php5nsapi.dll
ts.dll
238 Часть IV. Стандартные PHP-приложен ля
04:30р 1,224 snapshot.txt
04:30р 159,744 ssleay32.dll
04:30р 49,152 php_mysql.dll
30 F i l e ( s ) 7,153,163 bytes
6 Dir(s) 251,727,872 bytes free
Обратные одинарные кавычки можно использовать в том случае, когда режим
safe_mode отключен, т.е. соответствующая переменная имеет значение Off
(это значение используется по умолчанию при установке РНР).
Использование функции system()
Функция system () выполняет системную команду, выводит результат, ее выполнения на
экран и возвращает последнюю строку вывода. Рассмотрим следующий пример:
$result = system("dir c:\php");
В результате вызова функции system() отобразится содержимое каталога c:\php,
а переменная $ r e s u l t будет содержать последнюю строку вывода:
11 Dir(s) 566,263,808 bytes free
Использование функции exec ()
Функция exec () выполняет системную команду, но при этом не выводит результат выполнения
на экран. Однако он может быть сохранен в массиве, значения элементов которого
— строки, сформированные в результате вызова команды операционной системы. Как
и функция system (), exec () возвращает последнюю строку.
Пусть, например, необходимо узнать, сколько файлов и свободного дискового пространства
содержится в каталоге. Для этого можно воспользоваться функцией exec () следующего вида:
$result = exec("dir c:\php" );
После выполнения этой функции на экран ничего не будет выведено, а переменная
$ r e s u l t будет содержать последнюю строку результата вызова системной команды d i r:
11 Dir(s) 566,263,808 bytes free
Если же необходимо сохранить весь результат выполнения команды d i r , следует воспользоваться
следующим форматом функции exec ():
$result = exec("dir c:\php", $dirout);
В результате выполнения этой функции в массив $dirout будут помещены строки с информацией
о содержимом каталога с : \php. Для вывода всех элементов массива воспользуемся
следующим фрагментом кода:
foreach($dirout as $line)
{
echo "$line\n";
}
В результате получим следующую информацию:
Volume in drive D has no label.
Volume Serial Number is 3 94E-15E5
Directory of d:\php
02/25/2004 10:48a <DIR>
02/25/2004 10:48a <DIR>
Глава 13. PHP и операционная система 239
02/25/2004
02/25/2004
02/25/2004
02/25/2004 04:30p <DIR> dev
02/25/2004 04:30p <DIR> ext
02/25/2004 04:30p <DIR> extras
02/25/2004 04:30p 417,792 f d f t k . d ll
Для вывода значений определенных элементов массива $ d i r o u t можно воспользоваться
следующим фрагментом кода:
echo $dirout'[3] ,-
echo $ d i r o u t [ 7 ];
В результате будут выведены такие строки:
Directory of C:\PHP
02/25/2004 04:30р <DIR> • dev
Использование функции passthru ()
Функция p a s s t h r u () предназначена для вызова системной команды и отображения результата
ее выполнения на экране. Например:
p a s s t h r u ( " d i r c:\php"),-
Она просто выводит результат на экран и ничего не возвращает.
При этом результат выполнения системной команды никак этой функцией не обрабатьп а-
ется и поэтому может использоваться для вывода двоичных строк.
Вопросы безопасности
Вызывая системную команду, вы позволяете пользователю выполнять определенные действия
на вашем компьютере. Например, системная команда d i r с : \ p h p вполне безобидна,
в то время как вызов команды rm / b i n / * или d e l с: \ * . * может привести к непопра! и-
мым последствиям. Поэтому следует быть осторожным при использовании функций, позго-
ляющих выполнять команды операционной системы.
Когда вы создаете сценарий РНР, в котором сами выполняете команды типа d i r и пи
I s , — ситуация под контролем. Но если для вызова системных команд используются данные,
полученные от пользователей, необходимо соблюдать особую осторожность. Рассмотрим "а-
кой пример. Предположим, имеется приложение, которое на основе введенного имени пользователя
создает соответствующий каталог. Пусть пользователь в поле d i r e c t o r y N a m e некоторой
формы ввел свое имя Smith. Для обработки введенной информации можно
воспользоваться следующим фрагментом кода:
$directoryName = $_POST['directoryName'];
exec("mkdir $directoryName");
Поскольку переменная $directoryName имеет значение Smith, то в результате выполнения
команды e x e c ("mkdir $directoryName") будет создан каталог с именем Smith.
Казалось бы, все нормально.
Однако предположим, что пользователь ввел в поле формы следующую строку: Smitn;
rm *. В этом случае $directoryName = Smith; rm * и будет выполнен такой набор
команд: mkdir Smith; rm *. Во многих операционных системах, таких как Unix/Lin JX,
символ точки с запятой используется для разделения команд в одной строке, т.е. выражение
mkdir Smith; rm * эквивалентно
mkdir Smith
rm *
А вот это действительно проблема. Сначала будет создан каталог с именем Smith, но потом
все файлы в текущем каталоге будут уничтожены!
240 Часть IV. Стандартные РНР-приложения
Все это говорит о том, что следует быть крайне осторожным при вызове команд, содержащих
параметры. Необходимо четко понимать, откуда поступает такая команда. Если это
данные, полученные от пользователя, их необходимо проверить на корректность. Так,
в предшествующем примере можно было бы проверить значение поля формы, чтобы оно содержало
только буквы и числа.
использование nftofflo/сола &TJ*
Передача файлов с одного компьютера на другой — обычное явление в Internet. Если необходимо,
чтобы ваш партнер, который находится на значительном расстоянии от вас, получил
некоторый файл, это не составит проблем. Этот процесс займет всего несколько секунд.
Файл можно переслать, используя Web-сервер или протокол FTP. Способ передачи файлов
с помощью Web-сервера описывался в главе 11. В этом разделе речь пойдет о протоколе FTP.
Протокол FTP не зависит от Web. Это значит, что передачу файла можно осуществить
в сценарии, написанном на РНР для Web, или в любом другом сценарии. Протокол FTP позволяет
получить содержимое каталога на удаленном компьютере и передать в том или ином
направлении один или несколько файлов.
Протокол FTP основан на архитектуре клиент/сервер, т.е. для передачи файлов между вашим
и удаленным компьютером необходимо сначала подключиться к серверу FTP, а потом
передать запрос.
Язык РНР позволяет обмениваться файлами с помощью протокола FTP. В случае использования
операционной системы Windows поддержка FTP включена по умолчанию. При установке
РНР в операционных системах Unix/Linux/Mac следует воспользоваться параметром
—enable-ftp
В приложении А содержится более подробная информация об установочных параметрах РНР.
Подключение к серверу FTP
Для подключения к компьютеру, на котором установлен сервер FTP и с которым будет
осуществляться обмен файлами, предназначена функция f tp_connect {).
$connect = ftp_connect("janet.valade.com") ;
В качестве аргумента этой функции можно также использовать ГР-адрес сервера FTP.
$connect = ftp_connect("172.17.204.2");
После установки соединения с сервером FTP на нем необходимо зарегистрироваться. Для
этого потребуется ввести идентификатор пользователя и пароль. При этом можно воспользоваться
своими персональными данными либо же использовать общий для всех идентификатор
и пароль. Многие Web-узлы именно так и поступают, предоставляя в качестве идентификатора
пользователя значение anonymous, а в качестве пароля — адрес электронной почты.
В общем случае данные пользователя следует хранить в отдельном файле и подключать его
по мере необходимости. (О работе с файлами см. в главе 8.)
Для регистрации на сервере FTP в языке РНР предусмотрена функция f t p _ l o g in (). При
этом предполагается, что у пользователя имеются соответствующие идентификатор и пароль.
$login_result = ftp_login($connect, $userid, $passwd);
Если же соединение с сервером FTP не было установлено предварительно, будет выведено
следующее предупреждающее сообщение:
Warning: ftp_login() expects parameter 1 to be resource, boolean given in
d : \ t e s t l \ t e s t l 3 . p h p on l i n e 9
Глава 13. PHP и операционная система 241
Однако следует заметить, что сценарий РНР в данном случае не остановится и будет щ о-
должать выполняться. Скорее всего, это не то, что вам нужно, поскольку последующий кэд
может использовать соединение FTP. Во избежании данной проблемы можно воспользоваться
следующей конструкцией:
$connect = ftp_connect("janet.valade.com")
or die("He удалось подключиться к серверу");
$login_result = ftp_login($connect,$userid,$passwd)
or die("He удалось зарегистрироваться на сервере");
Функция d i e () позволяет остановить выполнение сценария в случае наличия ошибки.
После регистрации на сервере FTP ему можно передавать запросы различного вида, например
на получение содержимого каталога или загрузку файлов. Все эти возможности рассматриваются
в следующих разделах.
Получение содержимого каталога
При использовании протокола FTP одной из основных задач является получение содержимого
каталога. Для этого в РНР предусмотрена функция f t p _ n l i s t (), которая возвращает
массив имен файлов. Ее синтаксис имеет такой вид:
$filesArr = ftp_nlist($connect, "data");
Второй параметр функции f t p _ n l i s t () служит для указания имени каталога. Если ке
оно неизвестно, можно получить список файлов текущего каталога:
$directory_name = ftp_pwd($connect);
$filesArr = ftp_nlist($connect, $directory_name);
Для отображения всех файлов каталога можно воспользоваться следующим фрагментом код; t
foreach($filesArr as $value)
{
echo $value\n;
}
Передача файлов с помощью протокола FTP
Для получения файла с удаленного компьютера с помощью протокола FTP в РНР пред] ta-
значена функция f tp_get (). Ее синтаксис имеет следующий вид:
ftp_get($connect, "newfile.txt", "data.txt", FTP_ASCII);
Аргумент n e w f i l e . t x t соответствует имени файла, которое он будет иметь после >а-
грузки на пользовательский компьютер, a d a t a . t x t — имя существующего файла, находящегося
на сервере FTP.
Четвертый параметр означает тип загружаемого файла: FTP_ASCII (файл в формате ASCII)
или FTP_BINARY (двоичный файл). Чтобы определить тип файла, достаточно проанализировать
его содержимое. Если он состоит из читаемых символов, то это файл в формате ASCII,
в противном случае он является двоичным. Например, двоичными являются графические файлы
Для загрузки файла с пользовательского компьютера на удаленный узел в языке РЛР
предназначена функция f tp_put (). Ее синтаксис имеет следующий вид:
ftp_put($connect, "newfile.txt", "data.txt", FTP_ASCII) ,-
Параметр n e w f i l e . t x t соответствует имени файла, которое он будет иметь после ja-
грузки на удаленный компьютер, a d a t a . t x t определяет имя существующего файла, который
необходимо отправить на сервер FTP.
После завершения работы с соединением FTP его можно закрыть с помощью функции
f t p _ c l o s e ( ) :
ftp_close($connect);
242 Часть IV. Стандартные РНР-приложенчя
В качестве примера рассмотрим приведенный в листинге 13.2 сценарий РНР, который позволяет
получить из заданного каталога все файлы с расширением . t x t . Передача файлов
осуществляется с использованием протокола FTP.
Листинг 13.2. Сценарий, позволяющий загружать файлы с использованием протокола FTP
<?php
/* Имя сценария: downloadFiles
* Описание: загружает все файлы каталога
* с расширением .txt
*/
$dir_name = "data/";
$connect = ftp_connect("janet.valade.com")
or die("He удалось подключиться к FTP-серверу");
$login_result' = ftp_login($connect, $userID, $passwd)
or die("He удалось зарегистрироваться на FTP-сервере");
$filesArr = ftp_nlist($connect,$dir_name);
foreach($filesArr as $value)
{
if(ereg("\.txt$'\ $value))
{
i f ( ! f i l e _ e x i s t s ( $ v a l u e ))
{
ftp_get($connect, $value, $dir_name.$value, FTP_ASCII);
}
else
{
echo "Файл $value уже существует!\п";
}
}
} .. ' .
ftp_close($connect);
?>
В данном сценарии сначала происходит получение списка файлов из каталога на удаленном
компьютере, который сохраняется в массиве $filesArr. Цикл foreach используется
для прохода по всем элементам этого массива и проверки, имеет ли файл расширение . t x t .
Если это так, сценарий проверяет, существует ли файл с указанным именем. Если файл уже
был загружен с сервера, выводится соответствующее сообщение, в противном случае файл
передается на компьютер пользователя.
Другие функции для работы с протоколом FTP
В РНР имеются и другие функции для работы с протоколом FTP, которые позволяют, например,
перейти к другому каталогу на удаленном компьютере или создать новый каталог.
Некоторые из них приведены в табл. 13.2.
Таблица 13.2. Функции для работы с протоколом FTP
Функция
ftp_cdup($connect)
ftp_chdir($connect,
ftp_close($connect)
"имя_каталога")
Описание
Осуществляет переход к каталогу верхнего уровня по
отношению к текущему
Изменяет каталог на удаленном компьютере
Закрывает соединение с сервером FTP
Глава 13. РНР и операционная система 243
Окончание табл. li'.l
Функция Описание
f tp_connect ("имя_серверз")
f tp_delete ($connect, " путь/имя_файла")
ftp_exec ($ connect, "команда")
ftp_fget($connect,
$fh, " d a t a . t x t " , FTP_ASCII)
ftp_fput($connect, "new.txt",
$fh, FTP_ASCII)
ftp_get($connect, "d.txt",
"sr.txt", FTP_ASCII)
f t p _ l o g in
($connect, $userID, $password)
ftp_mdtm($connect, "filename.txt")
ftp_mkdir
($ connec t , " имя_каталога • )
ftp_nlist
( S c o n n e c t , "имя_каталога")
ftp_put($connect, " d . t x t ",
" s r . t x t " , FTP_ASCII)
ftp_pwd(Sconnect)
ftp_rename
( $ c o n n e c t , "старое_имя", "новое_имя")
ftp_rmdir ($connect, "имя_каталога")
ftp_size($connect, "filename.txt")
ftp_systype($connect)
Инициирует подключение к компьютеру. В качестве
параметра шя_сервера можно использовать доменное
имя или IP-адрес
Удаляет файл на удаленном компьютере
Выполняет системную команду на удаленном компьютере
Загружает содержимое файла, находящегося на удаленном
компьютере, в открытый файл с дескриптором $ f h .
(Подробнее об обработке файлов см. в главе 12.)
Загружает содержимое открытого на стороне пользовате/я
файла с дескриптором $ f h на сервер FTP
Загружает файл, находящийся на удаленном компьютере,
s r . t x t — это имя файла, загружаемого с сервера;
d . t x t — имя результирующего файла на компьютере
пользователя
Обеспечивает регистрацию на сервере FP
Возвращает время последнего изменения файла
Создает новый каталог на удаленном компьютере
Возвращает массив, элементами которого являются име«
файлов, находящихся в удаленном каталоге
Загружает файл на удаленный компьютер, s r . t x t —
имя загружаемого файла; d . t x t — имя файла после
загрузки на удаленный компьютер
Возвращает имя текущего каталога на удаленном
компьютере
Переименовывает файл, находящийся на удаленном
компьютере
Удаляет каталог, находящийся на удаленном компьютере
Определяет размер файла, находящегося на удаленном
компьютере
Возвращает тип операционной системы, используемой
файловым сервером, например Unix
использование элемп/юнной поч,(ни
Электронная почта повсеместно используется в Internet и в приложениях РНР в частности.
Электронные сообщения служат для разных целей. Например, Web-приложение может передать
покупателю по электронной почте уведомление о сделанном заказе. Или в случае, ко гда
пользователь создает на Web-узле новую учетную запись, электронное сообщение испол1зу-
ется для верификации данных. Если же клиент забыл свой пароль, он может щелкнуть на
кнопке I forgot my password (Я забыл свой пароль) и по электронной почте ему будет
выслана вся необходимая информация. Электронную почту можно использовать для отправки
ежемесячных сообщений подписчикам и т.д.
244 Часть IV. Стандартные РНР-приложеьия
Язык РНР предоставляет обширный набор функций для работы с электронной почтой.
Следующий раздел посвящен вопросам, связанным с отправкой электронных сообщений из
сценариев РНР.
Настройка РНР для работы с электронной почтой
Электронное сообщение передается сервером исходящей почты, и для отправки сообщений
из сценария РНР он должен знать имя сервера, чтобы иметь к нему доступ.
В большинстве случае сервер исходящей почты использует SMTP (Simple Mail
Transfer Protocol — простой протокол передачи электронной почты). При этом не
так важно, чем вы пользуетесь: локальной сетью на работе, кабельным модемом
дома или услугами провайдера Internet, — все электронные сообщения отправляются
сервером SMTP. Причем для доступа к серверу пользователь должен знать
его параметры.
Чтобы узнать параметры сервера исходящей почты, можно воспользоваться настройками
соответствующего программного обеспечения, которое применяется для отправки электронных
сообщений.
Если же вам не удалось определить параметры сервера исходящей почты, следует обратиться
к администратору сети, а в случае использования услуг провайдера Internet — к соответствующей
компании. Имя почтового сервера может выглядеть следующим образом:
mail.ispname.net
При использовании операционной системы Linux/Unix именем почтового сервера может
быть sendmail.
Определившись с параметрами сервера исходящей электронной почты, следует внести
соответствующие изменения в конфигурационный файл p h p . i n i . Для этого необходимо
найти в нем следующие строки:
[mail function]
; Только для операционной системы Win32.
SMTP = localhost
; Только для операционной системы Win32.
;sendmail_from = me@localhost.com
; Только для операционной системы Unix.
;Можно также установить дополнительные параметры
; (по умолчанию: "sendmail -t -i")-
;sendmail_path =
Пользователи операционной системы Windows должны изменить первые два значения.
Первое из них соответствует имени сервера исходящей почты. Например:
SMTP = mail.ispname.com
Второй параметр указывает адрес электронной почты, от имени которого будут отправляться
сообщения. Например:
sendmail_from = Janet@Valade.com
Третий параметр предназначен для пользователей операционной системы Unix. В большинстве
случаев используемое по умолчанию значение является корректным. Однако, если
что-либо не так, следует обратиться к администратору сети и узнать точные параметры.
Глава 13. РНР и операционная система 245
Для пользователей операционной системы Unix. Иногда путь к почтовому
серверу sendmail может иметь вид / u s r / s b i n / s e n d m a i l или / u s r / l i o /
s e n d m a i l . Если же ваша система не использует s e n d m a i l , то в качестве почтового
сервера применяется некоторая программная оболочка. Например, программа
Qmail может находиться по адресу / v a r / q m a i l / b i n / s e n d m a i l *ли
/ v a r / q m a i l / b i n / q m a i l - i n j e c t .
Для того чтобы внесенные в файл p h p . i n i изменения вступили в силу, необходимо
перезапустить Web-сервер.
Отправка электронных сообщений
Для отправки электронного сообщения из сценария РНР предусмотрена функция m a i l ).
Ее синтаксис имеет следующий вид:
mail{адрес, тема, сообщение, заголовки);
Функция m a i l () имеет следующие параметры:
•S адрес (электронный адрес получателя);
•S тема (строка, соответствующая теме электронного сообщения);
•S сообщение (содержимое электронного сообщения);
•/ заголовки (строка, содержащая переменные заголовка электроннс го
сообщения).
Рассмотрим такой пример:
$ t o = "janet@valade.com";
$subj = "Тест";
$mess = "Это проверка работы электронной почты";
$headers = "bcc:techsupport@mycompany.com\r\n";
$mailsend = m a i l ( $ t o , $subj, $mess, $ h e a d e r s );
В данном фрагменте кода электронное сообщение передается пользователю, адрес котор< iro
содержится в переменной $to. Причем сообщения можно отправлять нескольким адресатам:
$to= "janet@valade.com,me@mycompany.com";
Переменная $ h e a d e r s в этом примере отправляет скрытую копию сообщения на адрес
технической поддержки techsupport@mycompany.com. В одном сообщении можно использовать
несколько заголовков:
$header = "ее:tech@mycompany.com\r\nbcc:sales@mycompany.com";
Первые три параметра функции m a i l () являются обязательными, в то время как четвертый,
содержащий заголовок, — нет.
Функция m a i l () возвращает значение TRUE, если сообщение было отправлено успешно,
и FALSE — в противном случае. Однако следует заметить, что значение TRUE не гарантирует
того, что сообщение обязательно дойдет до адресата.
Отправка почтовых вложений
Зачастую для обмена информацией пользователи используют вложения электронных сообщений.
Например, если необходимо отправить всем клиентам контракт о сервисном обслуживании
на тридцати страницах, куда эффективнее использовать вложение, чем помещать
текст контракта в тело сообщения.
246 Часть IV. Стандартные РНР-приложения
^SSSfc
'^SpP
Для отправки вложения следует использовать заголовок специального формата. Например:
Content-disposition: attachment; filename=test.txt
В этом случае заголовок указывает почтовому серверу, что сообщение будет передано
вместе с файлом t e s t . t x t . В следующем примере показано, как отправить короткое сообщение
в качестве вложения (хотя вряд ли вам когда-то придется делать это):
$to = "janet@valade.com";
$subj = "Проверка использования вложения";
$mess = <<< END
Это тестовое сообщение,
отправляемое в виде вложения.
Проверьте это на практике.
END;
$headers = "Content-disposition: attachment;
filename=test.txt\n";
$headers .= "cc:sales@mycompany.com\n";
$mailsend = mail($to,$subj,$mess,$headers);
Сформированное сообщение имеет два заголовка: C o n t e n t - d i s p o s i t i o n и ее. Причем
оба они содержатся в переменной $headers и заканчиваются символом \п. Для некоторых
программ электронной почты следует использовать символы \ г \ п .
При отправке электронных сообщений с вложением часто приходится передавать содержимое
некоторого файла. Для этого следует считать содержимое файла в переменную, значение
которой будет передано в сообщении. Более подробно о работе с файлами см. в главе 12.
При отправке электронного сообщения содержимое файла можно поместить в одну длинную
текстовую строку. Это можно сделать с помощью функции f i l e _ g e t _ c o n t e n t s ():
$mess = file_get_contents("имя_файла");
В листинге 13.3 приведен сценарий, передающий в качестве вложения текстовый файл.
Листинг 13.3. Сценарий, отправляющий текстовый файл в качестве вложения
электронного сообщения
<?php
/* Имя сценария: mailTest
* Описание: передает текстовый файл в качестве
* вложения электронного сообщения.
*/
$filename = "mydata.txt";
$mess = file_get_contents($filename);
$to = "janet@valade.com";
$subj = "Отправка данных в качестве вложения";
$headers = "Content-disposition: attachment; filename=mydata.txt\n";
if(!$mailsend = mail($to, $subj, $mess, $headers))
{
echo "Почта не отправлена\п";
}
else
{ echo "Почта отправлена\п";
}
?>
В приведенном сценарии с помощью функции f i l e _ g e t _ c o n t e n t s () содержимое
файла считывается в текстовую строку $mess. Заголовок сообщения помещается в переменную
$headers. Отправка сообщения по электронной почте осуществляется с использованием
Глава 13. РНР и операционная система 247
функции mail (). При этом, если не удалось отправить письмо, пользователь получит соэт-
ветствующее сообщение.
Чтобы отправить во вложении не только текстовые файлы, в заголовке Content-type
электронного сообщения следует указать соответствующий тип:
Content-type: тип_содержимого
Так, для простого текстового файла в качестве значения тип_содержимого используется
t e x t / p l a i n (в большинстве случаев это значение используется по умолчанию). Для файла
HTML нужно указывать заголовок t e x t /html.
Зачастую приходится отправлять двоичные файлы, к которым относятся изображения, аудио-
и видеоинформация. Для некоторых из них можно использовать следующие значения заголовка
Content-type:
image/gif
image/jpeg
audio/x-wav
audio/vnd.rn-realaudio
video/mpeg
video/avi
Файлы, создаваемые другими приложениями, также могут быть как текстовыми, гак
и двоичными. Например, файлы в формате RTF являются текстовыми, а файлы Word пли
Excel— двоичными. В общем случае неизвестно, каким программным обеспечением сгенерирован
двоичный файл, поэтому в качестве заголовка Content-type лучше использовать
значение a p p l i c a t i o n / o c t e t - s t r e a m.
Для того чтобы двоичные файлы дошли по электронной почте в целости и сохранное ги,
их следует зашифровать. Для этого в РНР предназначена функция
$mess = chunk_split(base64_encode($string));
Переменная $ s t r i n g инкапсулирует содержимое двоичного файла, полученное с использованием
функции f r e ad ().
Кроме того, при передаче закодированного файла в электронном сообщении необходимого
указать это, используя заголовок
Content-Transfer-Encoding: base64
В листинге 13.4 приведен сценарий РНР, позволяющий отправлять графические фа{лы
(двоичные и закодированные) в качестве вложений электронных сообщений.
Листинг 13.4. Сценарий РНР для передачи графических файлов в качестве вложений
электронных сообщений
<?php
/* Имя сценария: mailGraphic
* Описание: передает графические файлы в качестве
* вложений электронных сообщений.
*/
$filename = "logo.gif";
$fh = fopen($filename,
$fileContent = fread($fh,
fclose($fh) ,-
$mess = chunk_split(base64_encode($fileContent));
$to = "janet@valade.com";
$subj = "Отправка изображения в качестве вложения";
$headers = "Content-disposition: attachment; filename=logo.gif\n";
$headers .= "Content-type: image/gif\n";
$headers .= "Content-Transfer-Encoding: base64\n",-
"rb");
filesize($filename));
248 Часть IV. Стандартные PHP-приложения
if(!$mailsend = mail($to, $subj, $mess, $headers))
{
echo "Почта не отправлена\n";
}
else
{ echo "Почта отправлена\n";
}
?>
В приведенном сценарии закодированное содержимое файла сохраняется в переменной
$mess. Кроме того, в сообщение включено несколько заголовков, необходимых для передачи
такого рода файлов в качестве вложений.
Глава 13. РНР и операционная система 249
Глава 14
Расширения РНР
В э>н.ой главе...
> Что такое расширения РНР
> Установка модуля PEAR
> Использование пакетов модуля PEAR
рхитектура РНР состоит из ядра (core), которое определяет базовую функциональность
этого языка, к расширений (extension).
Следует заметить, что значительная гибкость и мощь языка РНР обеспечивается за счет
использования как встроенных функций, так и функций, доступных в разнообразных расширениях.
Многие из них не раз встречались в этой книге, а в приложении Б приведен спи :ок
наиболее популярных функций.
Большинство полезных функций РНР содержится в расширениях, которые значител.но
увеличивают возможности языка. Часть базовых расширений поставляется и устанавливается
по умолчанию. Остальные также включаются в дистрибутив РНР, однако для последующей
работы их нужно установить дополнительно. Например, для взаимодействия с различными
базами данных необходимо подключить соответствующие расширения (см. главу 12). Кроме
того, на данный момент имеется множество расширений, написанных отдельными разраб от-
чиками, среди которых, в первую очередь, следует выделить модуль PEAR (PHP Extension
and Application Repository — набор расширений и приложений РНР).
В данной главе изложены основные принципы использования расширений РНР для создания
приложений.
Основные fiacutufteuusL PHJ*
В базовом комплекте РНР имеется несколько расширений, которые по умолчашю
встроены в модуль РНР, а их функции доступны для использования. При этом нет необходимости
что-либо знать об этих расширениях или предпринимать дополнительные усилия пля
их активизации— нужно просто пользоваться их функциональностью. (Но, если все же они
вам не нужны, их можно деактивизировать, как описывается в приложении А.) Многие функции,
которые доступны в различных расширениях, встречаются во всей данной книге.
Для того чтобы определить, какие расширения установлены, можно воспользоваться
функцией phpinf о (). Сначала она выводит параметры ядра РНР, а потом всевозможных
расширений. Ниже приведен список расширений, которые устанавливаются по умолчанию.
•S BCMath. Математическая библиотека, обеспечивающая большую точность,
нежели стандартные числа РНР с плавающей точкой.
•S calendar. Библиотека, предоставляющая функции для преобразования дат из
одного календарного формата (например, юлианский, григорианский, Французской
республики и т.д.) в другой.
S СОМ. Библиотека, обеспечивающая доступ к объектам СОМ.
Л
•S ctype. Библиотека, предоставляющая функции для проверки типа символов
(например, является ли символ буквой или знаком пунктуации).
•S ftp. Предоставляет функции для подключения и отправки запросов серверу
FTP. Эта библиотека позволяет передавать файлы между компьютерами.
•S odbc. Библиотека, предоставляющая функции для работы с интерфейсом ODBC.
•/ рсге. Это расширение предоставляет функции для работы с регулярными выражениями
в формате PCRE.
S session. Предоставляет функции для работы с сеансами РНР.
•S SQLite. Предоставляет функции для хранения информации в текстовых файлах
с использованием структурированного языка запросов SQL.
•S tokenizer. Предоставляет функции, которые предназначены для анализа кода,
написанного на языке РНР.
S wddx. Предоставляет функции, предназначенные для работы со стандартом
WDDX, который основан на XML и используется для обмена информацией
между различными приложениями.
•/ xml. Библиотека, использующаяся для обработки документов XML.
•S zlib. Библиотека, позволяющая считывать и записывать файлы, заархивированные
в формате gzip.
Приведенный выше список содержит расширения, которые на данный момент устанавливаются
при инсталляции РНР по умолчанию. Однако, очевидно, что со временем этот перечень
может измениться.
Если для установки РНР под управлением операционной системы Windows используются
двоичные файлы, приведенные расширения скомпилированы в соответствующие двоичные
файлы. В случае установки РНР в операционной системе Unix или Linux эти расширения будут
подключены по умолчанию во время компиляции. Тогда же их можно и деактивизировать. Например,
если нет необходимости использовать расширение, обеспечивающее поддержку сеансов РНР,
следует воспользоваться специальным параметром установки, как описывается в приложении А.
—disable-session
В основном встроенные расширения обеспечивают ту функциональность, которая всегда
будет востребована разработчиками РНР. Поэтому их приходится отключать очень редко.
В большинстве случаев язык программирования РНР поставляется вместе с дистрибутивом
операционной системы Linux, а также входит в комплект поставки программного обеспечения
многих компьютеров, использующих ее. Если вы пользуетесь услугами Web-хостинговой компании,
то не устанавливаете РНР сами, а поэтому не можете знать, какие именно расширения
были подключены во время компиляции. Обычно расширения, приведенные в данной главе, активизированы,
но в общем случае нет никакой гарантии. Документацию по этим расширениям
можно найти на официальном Web-узле РНР по адресу www. php. net.
Многие расширения РНР поставляются вместе с дистрибутивом, однако не все активизи- ,
руются по умолчанию, т.е. у вас имеются все необходимые файлы, но поддержка тех или
иных модулей не обеспечена. Для того чтобы иметь возможность использовать разнообразные
функции из расширений, их следует подключить. Как правило, дополнительные расширения
используются не так часто, как базовые. Разработчики РНР обеспечивают всю их
функциональность, однако не компилируют по умолчанию для экономии ресурсов.
Глава 14. Расширения РНР 251
Активизация расширений РНР — задача несложная. Если РНР компилируется при установке,
то в этом случае необходимо добавить соответствующий параметр для расширения. (Спис еж
таких параметров приведен в приложении А.) Большинство разработчиков, использующих га-
кие операционные системы, как Linux, Unix и Mac, при установке компилируют модуль РНР.
И только немногие выполняют ее при использовании операционной системы Windows.
Если имеется набор двоичных файлов РНР, подключить расширение можно следующем
образом (без выполнения компиляции).
1. Скопируйте необходимый файл с расширением . d l l из подкаталога ext в основной
каталог.
Подкаталог ext может находиться по адресу с : \php\ext.
2. Откройте конфигурационный файл p h p . i n i и отыщите строку наподобие
следующей:
;extension=php_gd2.dll I
3. Удалите точку с запятой в начале строки.
Ниже приведен список наиболее популярных расширений, используемых в РНР.
•S Расширения для работы с базами данных. Многие разработчики использ>ют
эти расширения для взаимодействия сценария РНР с различными базами данн >гх.
Как уже упоминалось ранее, расширение для работы с интерфейсом ODBC вю точено
по умолчанию. (О расширениях для работы с базами данных см. в главе 12)
•S Библиотека GD. Эта библиотека является одной из самых популярных, поскольку
предоставляет функции для вывода изображений (как и файлов
HTML). Библиотека GD позволяет работать с изображениями в различных
форматах, таких как JPEG, GIF, PNG и многих других.
Начиная с версии РНР 4.3.0, в комплект поставки модуля РНР входит встроенная
версия библиотеки GD, которую использовать предпочтительнее. При этом пет
необходимости подключать внешнюю библиотеку — достаточно скомпилиров 1гь
РНР с установочным параметром with-gd2, как показано в приложении А, и не
указывать путь (т.е. не использовать выражение =DIR).
•S Расширение PDF. Эта библиотека предоставляет набор функций, позволяющих
создавать документы в формате PDF, устанавливать шрифты, записыв ль
текст в документ, а также добавлять графику.
•S Расширение cURL. Эта библиотека позволяет взаимодействовать с серверами
с использованием различных протоколов, таких как H'l'l'FS, Telnet, FTP, LDAP и д р.
Назначение большинства расширений— обеспечение взаимодействия РНР с разнь ми
программными продуктами. Например, расширения для работы с базами данных предоставляют
набор функций для взаимодействия с базами данных в различных форматах. Очевидно,
что программное обеспечение, с которым вы планируете работать, должно быть предварительно
установлено. (Например, расширение для работы с базой данных Oracle будет функционировать
корректно только в том случае, если Oracle будет установлен у вас на компьютере
или в сети.) Иногда библиотеки для работы с тем или иным программным обеспечением
уже установлены. В противном случае их необходимо предварительно загрузить и установить.
При этом сперва следует обратиться к соответствующей документации, находящейся на
официальном Web-узле РНР, и убедиться, что это именно то, что вам нужно. Многие расширения
поставляются вместе с дистрибутивом РНР, так что нет необходимости отыскивать их
252 Часть IV. Стандартные РНР-приложемя
и загружать дополнительно. Такие библиотеки находятся в основном каталоге, где установлен
модуль РНР. Например, для поддержки базы данных MySQL требуется наличие файлов
libmysql. d l l (для версий MySQL 4.0 и ниже) и libmysqli . d l l (для версий MySQL 4.1
и выше). Эти файлы помещаются в основной каталог РНР, тем самым обеспечивая корректность
работы функций mysql () и mysql i ().
В табл. 14.1 приведен практически полный список расширений, используемых в РНР, за
исключением расширений для работы с базами данных, которые рассматривались в главе 12.
В данной таблице все имена файлов с расширением . d l l , которые находятся в каталоге
php/ext, начинаются с символов php_. Параметр DIR указывает путь к каталогу, где установлена
библиотека. Если же он опущен, используется значение по умолчанию.
Таблица 14.1. Расширения РНР
Название расширения
bzip2 Compression
ClibPDF
Crack
cURL
Domxml
FDF
GD
gettext
iconv
IMAP
JAVA
LDAP
Multi-byte String
Mcrypt Encryption
Mhash
Назначение
Считывает/записывает
файлы в формате bzip2
Создает документы
в формате PDF
Проверяет пароль на
устойчивость
Обеспечивает работу с
различными
протоколами
Обрабатывает
документы XML
Обрабатывает данные
формы документа PDF
Работает
с изображениями
Поддерживает
естественный язык
Преобразует тип
кодировки символов
строки
Поддерживает функции
для работы с почтовым
сервером IMAP
Поддерживает язык Java
Поддерживает функции
для работы со службой
каталогов LDAP
Поддерживает японские|
умолчанию) и другие •
символы
Шифрует данные
Используется для
вычисления контрольных
сумм и т.д.
Имя файла dll
_ b z 2 . d l l
_ c p d f . d l l
_ c r a c k . d l l
_ c u r l . d l l
_domxml.dll
_ f d f . d l l
_ g d 2 . d l l
_ g e t t e x t . d l l
_ i c o n v . d l l
_ i m a p . d l l
_ j a v a . d l l
_ l d a p . d l l
|nO_mbstring. d l l
_ m c r y p t . d l l
_mhash.dll
Установочный параметр
- - w i t h - b z 2 = D IR
— w i t h - c p d f l i b = D IR
- - w i t h - c r a c k = D IR
- - w i t h - c u r l = D IR
--with-dom=DIR
- - w i t h - f d f tk=DIR
- - w i t h - g d2
- - w i t h - g e t t e x t = D IR
- - w i t h - i c o n v = D IR
- - w i t h - i m a p = D IR
- - w i t h - j a v a = D IR
- - w i t h - l d a p = D IR
--with-mbstring=LANG
- - w i th-mcrypt=DIR
--with-mhash=DIR
Глава 14. Расширения РНР 253
Окончание табл. 14.1
Название расширения
Mime type
Ming for Flash
OpenSSL
PDF
Printer
Shared Memory
SNMP
Sockets
XML-RPC
XSLT
Zip Files
Назначение
Определяет тип
содержимого документа
Создает анимацию
в формате Flash
Предоставляет
безопасный протокол
передачи данных
Создает документы
в формате PDF
Отправляет данные
на печать (только для
операционной системы
Windows)
Считывает/записывает
разделяемые сегменты
памяти
Управляет объектами
SNMP
Интерфейс нижнего
уровня для взаимодействия
с сокетами
Создает серверы
и клиенты XML-RPC
Работет с языком XSLT
Считывает файлы
в формате zip
Имя файла dll
_mime_magic.dll
_ m i n g . d l l
_ o p e n s s l . d l l
_ p d f . d l l
_ p r i n t e r . d l l
_shmop.dll
_snmp.dll
_ s o c k e t s . d l l
_ x m l r p c . d l l
_ x s l t . d l l
_ z i p . d l l
Установочный параметр
--with-mime_magic
- - w i t h - m i ng
- - w i t h - o p e n s s l = D IR
- - w i t h - p d f l i b = D IR
Отсутствует
--enable-shmop
--with-snmp=DIR
- - e n a b l e - s o c k e ts
- - w i t h - x m l r p c = D IR
- - e n a b l e - x s l t
- - w i t h - z i p . d l l
Очевидно, что в любой момент эти расширения могут быть исключены из этого спи:ка
и добавлены новые.
использование uioqtfUSL !РС*АЛ
Модуль PEAR (PHP Extension and Application Repository— набор расширений и приложений
PHP) представляет собой структурированную библиотеку программ с открытым кодом.
Дело в том, что сам программный код поставляется отдельными разработчиками (вне
PEAR), а консорциум разработчиков PEAR управляет его содержимым и распространение! \.
Консорциум разработчиков PEAR создал метод распространения кода в так называемых пакетах
(package). Разработчик, желающий создать расширение или приложение, должен придерживаться
определенных стандартов. Например, пакет должен содержать такие компоненты, как документацию,
специальные функции для обработки ошибок, а сам программный код долкен
отвечать требованиям PEAR. Использование стандартизированной структуры кода позволяет сделать
его поддержку на протяжении значительного периода времени более эффективной. Действительно,
если разработчик PEAR выиграл в лотерею и улетел на отдых на Таити, то любой др)гой
программист может взяться за поддержку "покинутого" кода, поскольку его структура прозрачна.
Прежде чем некоторый проект будет добавлен в расширение PEAR, его принимают на рассмотрение.
В PEAR добавляют только код, написанный на высоком профессиональном уро ше,
который удовлетворяет всем стандартам. При этом разработчик, желающий видеть свое
254 Часть IV. Стандартные РНР-приложеиия
"творение" в модуле PEAR, должен поддерживать программный код и предоставлять соответствующую
документацию. После рассмотрения разработчиками PEAR предоставленного проекта
он добавляется в расширение PEAR, а его автор назначается ответственным за его поддержку.
Где можно найти модуль PEAR
По данным официального Web-узла PEAR ( h t t p : / / p e a r . p h p . n e t ) этот модуль содержит
263 пакета, шесть из которых включены в дистрибутив РНР по умолчанию. К ним относятся
следующие.
•f DB. Представляет абстрактный уровень для работы с различными базами
данных, используя один и тот же набор функций.
•S Net_Socket. Представляет собой интерфейс Net Socket для работы с сокетами TCP.
•S Net_SMTP. Представляет реализацию протокола SMTP (Simple Mail Transfer
Protocol — простой протокол передачи почты) на основе интерфейса Net_Socket.
•S Mail. Предоставляет набор различных функций для проверки и отправки
электронной почты.
•S XML_Parser. Представляет собой анализатор документов XML, который основан
на использовании встроенного в РНР расширения XML.
S PHPUnit. Предназначен для проверки функций и классов, написанных на РНР.
Эти пакеты устанавливаются в каталог PEAR/packages либо же в PEAR/go-pearbundle,
расположенный в главном каталоге РНР. Причем все файлы заархивированы с помощью
архиватора ZIP. Для установки необходимых пакетов можно воспользоваться установочной
программой PEAR, которая описана в следующем разделе.
Описание всех пакетов PEAR можно найти на официальном Web-узле PEAR
(pear. php. n e t ) . При этом нужные пакеты можно выбрать из соответствующих категорий
или отыскать в базе данных.
Обратите внимание на две гиперссылки в левой части главной страницы: List Packages
(Перечень пакетов) и Search Packages (Поиск пакетов). После щелчка на ссылке List
Packages отобразится следующий список категорий.
Authentication
Benchmarking
Caching
Configuration
Console
Database
Date and Time
Encryption
File Formats
File System
Gtk Components
HTML
HTTP
Images
Internationalization
Logging
Mail
Math
Networking
Numbers
Payment
PEAR
PHP
Processing
Science
Streams
Structures
Text
Tools and Utilities
Web Services
XML
Глава 14. Расширения PHP 255
После щелчка на одной из категорий появится список относящихся к ней пакетов. В ев зю
очередь, после щелчка на пакете отобразится страница с разнообразной информацией о ном.
Так, раздел Dependencies (Зависимости) содержит перечень пакетов, которые необходимо
иметь для установки выбранного вами. Раздел Download (Загрузка) содержит информацш
о том, откуда можно загрузить данный пакет. Однако не стоит делать это вручную, поскольку
установочная программа PEAR сделает все автоматически.
После щелчка на ссылке Search Packages появится форма, позволяющая выполнять поиск
пакетов по названию, категории, по данным о разработчике и дате. В результате поиска отоб разится
страница со ссылками на пакеты, удовлетворяющие заданному запросу. После щелчка на
одной из них появится информация о найденном пакете. Если ее окажется недостаточно, мон:но
обратиться к руководству по использованию. Для этого необходимо щелкнуть на ссылке
Manual, находящейся на левой панели страницы в разделе Documentation (Документация). После
выбора языка появится содержание руководства. Раздел IV. Packages (Пакеты) содержит
ссылки на категории, а те, в свою очередь, — на пакеты, содержащиеся в них. Щелчок на ссылке
с именем пакета приведет к отображению страницы с полной информацией о нем.
Для того чтобы перейти с любой страницы Web-узла PEAR на главную, щелкнете
на ссылке PEAR в левом верхнем углу страницы.
Определившись с набором необходимых пакетов, можно перейти к их установке.
Установка модуля PEAR
Для каждого пакета PEAR существует менеджер пакета (package manager), обеспечивающий
его администрирование и включенный в комплект поставки РНР. Установочная программа
PEAR может устанавливать, удалять или обновлять пакеты. Поскольку она содержит все даш ше
о пакетах, то позволяет выводить информацию о доступных пакетах, проверять ее, проверять
зависимости между пакетами и выполнять другие действия по их администрированию.
Установка модуля PEAR при компиляции РНР
При компиляции РНР модуль PEAR и упомянутые выше шесть пакетов устанавливаю гея
автоматически. Чтобы проверить работоспособность установочной программы PEAR, моя с но
запустить файл pear . php из корневого каталога РНР. Для этого наберите в командной строке
pear, чтобы отобразился список возможных параметров. Для того чтобы вывести спи :ок
всех доступных пакетов, введите pear l i s t - a l l . (Этот процесс может занять нескол>ко
минут, поскольку список загружает из Internet.)
Для версий РНР ниже 4.3.0 установочная программа PEAR не добавляется автоматически
при компиляции РНР. Однако на Web-узле go-pear.net находится сценарий,
позволяющий выполнять загрузку и установку компонентов модуля РЕАБ..
Установка модуля PEAR в операционной системе Windows
При установке модуля РНР с помощью установочной программы или файлов ZIP модуль
PEAR автоматически не добавляется. Для установки этого расширения в операционной < ис-
теме Windows необходимо выполнить следующие действия.
1. Загрузите компоненты PEAR. Для установки вручную загрузите файлы ZIP, прех назначенные
для операционной системы Windows, как описано в приложении А. Затем
разархивируйте эти файлы в корневой каталог РНР, например с : \php\pear. Если вы
использовали инструкции по установке, описанные в приложении А, все необходимые
256 Часть IV. Стандартные РНР-приложения
компоненты модуля PEAR будут помещены именно туда. При этом устанавливать что-
либо дополнительно не придется.
2. Добавьте путь к каталогу PEAR в конфигурационном файле. Откройте файл
php. i n i и найдите следующую строку:
include_path = " . ; c : \ p h p \ i n c l u d e s ; c:\php\pear"
Если эта строка не содержит путь к каталогу, где установлен модуль PEAR, его следует
добавить.
3. Загрузите и установите установочную программу PEAR. Запустите файл go-pear .php
(или go-pear. bat) в каталоге, где установлен модуль РНР. В результате выполнения
этого сценария появится окно командной строки со следующим содержимым:
Welcome t o go-pear!
Go-pear will i n s t a l l the 'pear' command and a l l the f i l es
needed by i t . This command i s your tool for PEAR i n s t a l l a t i on
and maintenance.
Go-pear a l s o l e t s you download and i n s t a l l the PEAR packages
bundled with PHP: DB, Net_Socket, Net_SM.PT, Mail, XML_Parser,
PHPUnit.
If you wish to abort, press Control-C now, or press Enter:
(Добро пожаловать в go-pear!
Go-pear установит команду 'pear' и все необходимые файлы. Команда
'pear' является основным средством для установки и поддержки
пакета PEAR.
Go-pear также позволяет загрузить и установить пакеты PEAR для
РНР: DB, Net_Socket, Net_SMPT, Mail, XML_Parser, PHPUnit.
Для отмены нажмите комбинацию клавиш <Ctrl-C> или клавишу Enter:)
Вам предстоит ответить на несколько вопросов, и установочная программа PEAR будет
установлена. При этом предоставляется возможность установить шесть пакетов, которые
включены в дистрибутив по умолчанию.
Код сценария g o - p e a r . b a t содержит строку, в которой указывается путь к интерфейсу
РНР CLI. В предыдущих версиях РНР этот интерфейс размещался в каталоге
/ c l i . Если же строка содержит старый путь,
Set PHP_BIN = cli/php.exe
сценарий go-pear работать не будет. В этом случае необходимо изменить это
значение на корректное.
После инсталляции установочной программы PEAR (и шести пакетов PEAR) в корневом
каталоге РНР появится файл p e a r . b a t . Для проверки его работоспособности наберите
в командной строке pear, чтобы появился список возможных параметров. Для того чтобы
вывести список всех доступных пакетов, введите pear l i s t - a l l . (Этот процесс может занять
несколько минут, поскольку список загружается из Internet.)
Глава 14. Расширения РНР 257
Параметр l i s t - a l l позволяет получить доступ ко всем пакетам PEAR. При этом необходимо
помнить точное название пакета, чтобы установить именно ту программу, кот з-
рую вы хотели.
Установка пакета PEAR
Для установки нового пакета PEAR можно воспользоваться установочной программой
PEAR (см. предыдущий раздел). Для получения полного списка всех доступных пакетов следует
использовать параметр l i s t - a l l при запуске файла p e a r . b a t . В данном разделе будет
показано, как добавлять пакеты, используя установочную программу PEAR.
Для установки пакета PEAR введите в командной строке следующее (в корневом каталоге
РНР с: \php):
pear i n s t a l l имя_пакета
Установочная программа PEAR автоматически загрузит необходимые файлы пакет
с официального Web-узла PEAR и установит его. Например, чтобы добавить пакет Mail, в л-
полните команду
pear i n s t a l l Mail
При этом отобразится следующая информация:
downloading Mail-1.О.2.tgz ...
...done: 12,287 bytes
requires package 'Net_SMTP'
Mail: dependencies failed
(загрузка Mail-1.0.2.tgz ...
...завершено: 12,287 байт
требуется пакет 'Net_SMTP'
Mail: требуемые пакеты не. найдены)
В этом сообщении говорится о том, что пакет Mail был успешно загружен. Однако для е го
функционирования требуется наличие пакета Net_SMTP, который не установлен. Соответственно
пакет Mail также не будет установлен. Сначала следует добавить в модуль PEAR пакет
Net_SMTP, а только потом можно устанавливать Mail.
Если выполнить требования PEAR и корректно установить пакет Mail, а затем попытаться
добавить его еще раз, отобразится сообщение
Mail already i n s t a l l ed
(Пакет Mail уже установлен)
Для того чтобы вывести список всех установленных пакетов, необходимо воспользоваться
такой командой:
pear l i st
Для обновления пакета предназначена команда
pear update Mail
В этом случае отобразится следующая информация:
downloading Mail-1.О.2.tgz . ..
. . . d o n e : 12,287 bytes
upgrade to a newer version (1.0.2 is not newer that 1.0.2)
(загрузка Mail-1.0.2.tgz ...
...завершено: 12,287 байт
установка новой версии (1.0.2 не является более
новой' версией) )
258 Часть IV. Стандартные РНР-приложекия
\
Если попытаться установить пакет PEAR без установки соединения с сетью Internet, отобразится
строка следующего вида:
Connection to pear.php.net:80 failed
(Не удается установить соединение с сервером pear.php.net:80)
Для удаления пакета из модуля PEAR используется команда
pear u n i n s t a l l Mail
В результате отобразится такое сообщение:
u n i n s t a l l ok: Mail
(удаление пакета Mail завершено)
Использование пакетов PEAR
После добавления пакета в модуль PEAR можно использовать его функции и методы.
Доступ к пакету PEAR
После установки пакета в корневом каталоге PEAR появится файл с расширением . php,
имя которого соответствует названию пакета. Например, при добавлении пакета Mail будет
создан файл Mai 1. php. Для того чтобы воспользоваться функциональностью пакета, в своем
сценарии необходимо подключить этот файл. Рассмотрим следующий пример:
reqiure_once("Mail.php");
В данной строке кода функция reqiure_once () используется по двум причинам. Во-
первых, файл Mail .php будет подключен к сценарию только один раз. Во-вторых, если он
не будет найден, выполнение сценария прекратится.
Более подробное описание пакетов PEAR можно найти на официальном Web-узле PEAR.
Пакет DB является одним из наиболее популярных в расширении PEAR. Поэтому в качестве
примера демонстрации возможностей PEAR в последующих разделах будет описан
именно он. Автор не претендует на полноту изложения информации о данном пакете — будут
продемонстрированы лишь основные принципы создания сценариев для взаимодействия
с базами данных с помощью DB.
Пример пакета: PEAR - DB
Пакет DB предназначен для взаимодействия с различными базами данных с помощью одних
и тех же функций. В главе 12 было показано, что для работы с каждой базой данных
в РНР предусмотрен свой набор функций, например mysql_connect () или pg_connect ().
Вроде бы все просто.
Однако проблемы возникают при смене базы данных. Предположим, что ваше приложение
взаимодействует с базой данных MySQL. Однажды утром к вам заходит начальник и говорит:
"Я только что приобрел новую базу данных Oracle, и все данные необходимо переместить
туда". При этом вам понадобится не только переместить данные, но и найти в сценарии
РНР все функции, которые предназначены для работы с MySQL, а затем заменить их на соответствующие
функции для Oracle. Причем одни из этих функций будут иметь иные названия,
а другие — отличный список аргументов. Вот это — настоящая проблема.
Если у вас есть стопроцентная уверенность в том, что замена базы данных никогда не
произойдет, то можно об этом и не волноваться. В противном случае следует использовать
функции, которые будут работать независимо от имеющейся базы данных.
Глава 14. Расширения РНР 259
Взаимодействие с базой данных
Для обеспечения взаимодействия с базой данных с помощью пакета PEAR DB выпол ы-
ются те же действия, которые описаны в главе 12.
1. Подключение к базе данных.
2. Отправка запросов для выполнения тех или иных действий.
3. Обработка информации, полученной в результате выполнения запроса.
Для подключения к базе данных используется такая информация, как имя учетной записи,
пароль, тип базы данных и т.д. Эта информация, помещенная в строку определенного формата,
составляет имя источника данных DSN (Data Source Name). Используя его, DB осуществляет
подключение к базе данных. Рассмотрим следующий пример:
$host = "localhost";
$dbuser = "admin";
Sdbpasswd = "secret";
$dbname = "Sales";
$dbtype • "mysql";
$dsn = "$dbtype: /7$dbuser:$dbpasswd9$host/$dbname";
В переменной $dsn содержится список параметров, необходимых для корректного подключения
к базе данных.
$db = DB::connect($dsn);
После установки соединения с базой данных к ней можно обращаться с SQL-запроса ми.
Например:
$sql = "SELECT * from Sales";
$result • $db->query($sql);
Если в результате выполнения SQL-запроса будет получена некоторая информация, зля
доступа к ней следует воспользоваться функцией
$row = $result->fetchRow(DB_FETCHMODE_ASSOC);
В этом фрагменте кода метод fetchRowO помещает строку результата выполнешя
SQL-запроса в ассоциативный массив, ключами которого являются имена полей.
При этом очевидно, что при изменении базы данных вам придется лишь изменить значение
переменной $dbtype. Вносить какие-либо другие изменения в сценарий не потребуемся.
Таким образом, немного дополнительных усилий при написании сценария позволят избежать
больших хлопот, связанных с переходом к новой СУБД. На данный момент пакет PEAR DB
поддерживает следующие типы баз данных.
V mysql (MySQL)
* pgsql (PostgreSQL)
•S ibase (InterBase)
S msql (Mini SQL)
•S mssql (Microsoft SQL Server)
/ oci8 (Oracle версий 7, 8, 81)
• odbc(ODBC)
•S sybase (Sybase)
S i f x (Informix)
S fbsql (FrontBase)
Например, для перехода от СУБД MySQL к Sybase следует заменить строку $dbtyp«; =
"mysql"; на$dbtype = "sybase";.
260 Часть IV. Стандартные РНР-приложения
Обработка ошибок
В главе 12 уже обсуждались ошибки, связанные с взаимодействием с базами данных. Например,
СУБД может оказаться недоступной при попытке подключения к ней из сценария. В этом
случае необходимо, чтобы сценарий остановился и вывел соответствующее сообщение об ошибке.
В пакете DB существует метод обработки ошибок i s E r r o r O . Он проверяет значение
переменной: либо оно равно TRUE, либо переменная содержит ошибку. В этом случае для
вывода сообщения об ошибке можно воспользоваться методом getMessage (). Рассмотрим
следующий пример:
$db = DB::connect($dsn);
i f (DB::isError($db))
{
die($db->getMessage() ) ;
}
В данном фрагменте кода метод i s E r r o r () используется для проверки значения переменной
$db. Если оно равно TRUE, т.е. подключение к базе данных прошло успешно, блок
инструкций оператора i f не выполняется. Если же переменная $db содержит ошибку, будет
вызвана функция d i e (), которая остановит выполнение сценария и выведет сообщение, сгенерированное
методом i s E r r o r (). Например, если ошибка содержится в имени источника
данных DSN, отобразится сообщение следующего вида:
DB Error: no such database
(Ошибка DB: база данных не существует)
Собирая все вместе
В листинге 14.1 приведен сценарий, предназначенный для вывода списка покупателей,
информация о которых хранится в базе данных. Этот сценарий уже был реализован в главе 12
с использованием стандартного набора функций РНР для работы с базой данных PostgreSQL.
В данном случае будут задействованы функции из пакета PEAR DB.
Листинг 14.1. Сценарий, выводящий список покупателей
<?php
/* Имя сценария: DisplayCustomers
* Описание: этот сценарий извлекает из базы данных
* информацию о покупателях и выводит ее
* на Web-странице.
*/
require_once("DB.php"); #подключает классы пакета PEAR DB
$host = "localhost";
$dbuser = "admin";
$dbpasswd = "secret";
$dbname = "Sales";
$dbtype = "pgsql";
$dsn = "$dbtype://$dbuser:$dbpasswd@$host/$dbname";
$db = DB::connect($dsn);
if (DB::isError($db))
{
die($db->getMessage());
}
$sql = "SELECT * from Customer";
$result = $db->query($sql);
if (DB::isError($result))
{
die($result->getMessage());
Глава 14. Расширения PHP 261
}
echo "<html>
<head><title>CnncoK покупателей/tit lex/head>
<body>
<table width=\"100%\" border=\"0\">\n";
while($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
{
if (DB::isError($row))
{
die($row->getMessage());
}
echo "<tr>";
echo "<td>{$row['lastname']}, {$row['firstname']}</td>
<td>{$row['phone']}</td>";
echo "</tr>\n";
}
echo "</tablex/bodyx/html>" ,-
?>
В результате выполнения этого сценария будет выведен список покупателей в следующем
формате:
Фамилия, имя номер телефона
Безусловным преимуществом использования пакетов PEAR является простота доступ!
к ним. Программа установки PEAR инсталлирует все необходимые пакеты, которые мопт
быть подключены в любой сценарий с помощью функции require_once (). Однако необходимо
заметить, что каждый пакет PEAR имеет свой уникальный набор классов и функщ й
для решения тех или иных задач. Изучение нового пакета в какой-то мере равносильно изучению
нового языка программирования. При этом ранее накопленные знания о РНР мопт
в этом не помочь. И хотя многие пакеты PEAR имеют достаточно полную документацию, н ;-
которые из них описаны не в полной мере.
262 Часть IV. Стандартные РНР-приложенуя
Часть V
Великолепные десятки
'У *\t$A никогйА Hi боьникдло млкого ч^ВДм&Д,
HtwO ?W\Olw WpOiKM & ЛЮООи /ЛОМ1НЫ MOXiWv КАК
60Sp0tfUWM??*, toAK u V\piKp*toU»Ab tBOi
oju^itto&o&uHuil'
в э/пой шапи...
ащиеся в данной части, позволят вам расширить знания
о языке РНР. Здесь будут даны рекомендации и предостережения для про-,
граммистов на этом языке. Также будет рассказано о Web-узлах, посетив
которые можно найти много полезной информации о РНР. РНР — быстро
развивающийся и расширяемый язык программирования, поэтому вам,
как программисту на РНР, следует не отставать от темпов его развития.
Глава 15
Десять правил, которых следует
придерживаться при разработке
сценариев на РНР
В Шбй главе...
> Описание наиболее распространенных ошибок, возникающих при написании сценариев РНР
> Анализ сообщений об ошибках
аверное, все те ошибки, которые описываются в данной главе, так или иначе допускали
и вы. Невозможно написать сценарий, не допустив при этом никаких ошибок.
Однако, чтобы это не происходило слишком часто, сначала следует научиться их выявлять,
а затем, взглянув на код сценария, быстро исправить. Наверняка вам часто доводилось получать
подобное сообщение:
Parse error: parse error in c:\test.php on line 7
В этом случае интерпретатор РНР указывает, что строка кода содержит ошибку. При этом
выводится имя сценария и номер строки, где произошла ошибка, что очень помогает при их
устранении. Однако, как вы узнаете позже, интерпретатор РНР не всегда реагирует на ошибки
путем вывода соответствующих сообщений.
В данной главе рассматриваются наиболее распространенные типы ошибок при создании
сценариев на РНР и приводятся рекомендации по их предотвращению.
Otnciftnan?ue /ночки с запяйгой
Каждый оператор РНР должен завершаться символом точки с запятой (;). Интерпретатор
РНР считывает содержимое строк до тех пор, пока не встретит этот символ. Рассмотрим следующий
пример:
$test = 1
echo $test;
Приведенный фрагмент кода не имеет смысла, поскольку содержимое двух строк на языке
РНР будет интерпретироваться как один оператор, что приведет к выводу следующего сообщения
об ошибке:
Parse error: parse error in c:\test.php on line 2
Ошибка, связанная с отсутствием точки с запятой, является достаточно распространенной.
Н
Нес/ос1псипоч,ное количеапво знаков
[ъавен&пЯа
При сравнении двух величин необходимо использовать два расположенных подряд символа
равенства (==). Одна из наиболее распространенных ошибок— использование одного
такого символа. Эта ошибка легко объяснима: еще с первого класса вы научились использовать
один знак равенства для таких выражений, как 2+2=4. Эту ошибку не так уж легко выявить,
поскольку РНР никаких сообщений об этом не выводит. Единственное, что при этом
наблюдается, — это странное поведение сценария (например, наличие бесконечных цикл эв
или невыполнение инструкций условного оператора if). Можно долго наслаждаться выполнением
следующего фрагмента кода, который содержит бесконечный цикл:
$test = 0;
while ($test = 0)
{
$test++;
}
Опеч,а*пка в имени nefieuieHHOU
Это еще один тип ошибок, который не приводит к выводу никаких сообщений. Ее ни
в имени переменной сделана опечатка, то интерпретатор РНР воспринимает переменную как
только что созданную и выполняет с ней все необходимые действия. Ниже приведен еще
один пример бесконечного цикла.
$test = 0;
while ($test = 0)
{
$Test++;
}
Помните, что в языке РНР переменные с именами $Test и $ t e s t различаются.
OfftctffncfH€ue символа qoMiafia
Часто забывают о символе доллара ($) в имени переменной. Но в этом случае РНР подскажет
вам, где следует искать ошибку:
Parse error: parse error in test.php on l i n e 7
OUIUJKU, евзезанные с кавычками
Ошибки, связанные с кавычками, могут быть обусловлены их количеством или неверным
типом. Например, в следующем примере их слишком много:
$test = "<table width="100%">" ,-
В этом случае вторые двойные кавычки (перед числом 100) будут интерпретироваться
РНР как закрывающие. Соответственно РНР будет воспринимать символ 1 в качестве one] затора,
что, конечно же, не будет иметь никакого смысла. Существуют два способа исправления
ошибок такого рода:
$test = "<table width= ' 100% ' >" ,-
266 Часть V. Великолепные деапкч
и
$test = "<table width=\"100%\">";
В следующем примере кавычек уже слишком мало:
$test = "<table width='100%'>;
Интерпретатор PHP будет считывать последующие строки сценария как часть текстовой
строки до тех пор, пока не встретит символ закрывающей двойной кавычки ("). В этом случае
номер строки, который будет выведен в сообщении об ошибке, не будет соответствовать
строке сценария, которая в действительности содержит ошибку (пропущенный символ ").
Ошибки также возможны и в тех случаях, когда вместо одинарных кавычек используются
двойные и наоборот. В главе 5 подробно рассматривалось различие в использовании
этих символов.
/Зывос/ невидимых символов
Некоторые функции, такие как header (), необходимо вызывать перед любыми операторами
вывода. После операторов вывода такого рода функции будут работать некорректно.
Рассмотрим следующий пример:
<html>
<?php
header("Location: http://company.com");
?>
Дескриптор <html > размещен вне фрагмента PHP и соответственно отправляется в качестве
HTML-вывода. Это значит, что приведенный сценарий не сработает. А вот в этом случае
все уже корректно:
<?php
header ( "Location: http://company.com") ,-
?>
<html>
Рассмотрим еще один пример, ошибку в котором не так уж легко заметить:
<?php
header("Location: http://company.com");
?>
Дело в том, что приведенный фрагмент кода содержит символ пробела перед открывающим
дескриптором РНР. Естественно, он будет выведен на экран, хотя пользователь этого
и не заметит. Таким образом, функция header () не будет выполнена корректно, поскольку
перед ее вызовом уже была выведена информация. Это достаточно распространенная ошибка,
выявить которую — задача не из легких.
Яцме/гацил элементов массива
В языке РНР нумерация элементов массива начинается с нуля (0), хотя некоторые пользователи
предполагают, что с единицы (1). Это фундаментальное отличие обусловливает разную
интерпретацию кода сценария разработчиком и самим интерпретатором РНР. Рассмотрим
такой пример:
$test = 1;
while ($test <= 3)
{
$array[]=$test;
Глава 15. Десять правил, которых следует придерживаться при разработке... 267
$test++;
}
echo $array[3];
В результате выполнения сценария ничего выведено не будет (в том числе не появится
и сообщение об ошибке). Разработчик может предположить, что что-то не так. Но на самом
деле все верно. Просто РНР создаст массив
$аггау[0] = 1
$array[l] m 2
$аггау[2] = 3
т.е. элемент $аггау [ 3 ] не будет существовать.
включение onefiatnofioe PHJ*
При подключении файла в сценарий РНР с помощью функции include () предполагается,
что его содержимое будет интерпретироваться как код РНР, т.е. на место подключения из
файла будет вставлен фрагмент кода на языке РНР. Однако на самом деле все обстоит немного
иначе. Рассмотрим файл f i l e l . inc, содержащий следующий набор инструкций:
i f ($test == 1)
echo "Привет";
Вставим его содержимое в другой файл.
<?php
$test = 1;
include("filel.inc");
?>
Разработчик ожидает, что в результате выполнения этого сценария отобразится строка
Привет. Однако на Web-странице отобразится
if ($test == 1) echo "Привет";
т.е. содержимое файла f i l e l . inc будет интерпретироваться как код HTML. Чтобы изм;-
нить ситуацию, в этот файл следует добавить дескрипторы РНР:
<?php
i f ($test == 1)
echo "Привет";
?>
Неуоапакнцая па/га
В РНР круглые и фигурные скобки всегда должны содержать как открывающую, так и закрывающую
части. Отсутствие одной из них приведет к ошибке. Рассмотрим следующий пример:
if ( i s s e t ( $ t e s t)
В этом выражении недостает одной закрывающей круглой скобки. Надо сказать, что не
так уж легко проследить за тем, чтобы все блоки инструкций содержали закрывающие элементы,
особенно при использовании вложенных конструкций. В качестве примера рассмотрим
следующий:
while ($test<=3)
{
if ($test2 != "да")
{
if ($test3 > 4)
268 Часть V. Великолепные десятгм
{
echo "вперед";
}
}
Нетрудно заметить, что открывающих фигурных скобок — три, а закрывающих — две.
А если представить себе, что таких строк кода может быть около ста? В этом случае достаточно
непросто определить, в чем же проблема, особенно, если программист считает, что последняя
закрывающая фигурная скобка соответствует циклу while, а на самом деле она относится
к оператору if. В больших сценариях очень трудно проследить за ошибками такого рода.
В этих случаях очень полезно использовать отступы и комментарии:
while ($test<=3)
{
if ($test2 != "да")
{
i f ($test3 > 4)
{
echo "вперед";
} #закрывающая скобка оператора if, содержащего переменную
$test3
} #закрывающая скобка оператора if, содержащего переменную $test2
} #закрывающая скобка цикла while
J[lffnaHUl4,a С ICfllfZMrtJlU U CpUZCfflHtxlMU
скобками
Автор не уверен, является ли эта проблема существенной только для него, или от нее
страдают и другие программисты. Интерпретатор РНР без проблем отличает круглые скобки
от фигурных, но человеку, особенно после десяти часов программирования, это становится
делать все сложнее. Не составляет труда перепутать ( и {. В этом случае РНР выведет соответствующее
сообщение об ошибке.
Глава 15. Десять правил, которых следует придерживаться при разработке... 269
Глава 16
Десять жизненно необходимых
Web-ресурсов
В э/Яой uaie...
> Где найти статьи и учебные пособия по языку РНР
> Где взять библиотеки кода на языке РНР
зык программирования РНР поддерживается большим сообществом разработчиков.
Поэтому в Internet можно найти множество соответствующих ресурсов. В данной паве
приводятся наиболее полезные из них. Помните, что вы не одиноки.
Официальный Web-i/зел PMJ*
На официальном Web-узле РНР можно найти последние версии РНР и полное справочное
руководство, а также все, что необходимо знать о РНР.
www.php.net
Списки fiaccbtuicu THJ*
Если на протяжении нескольких дней вам не удается найти ошибку в сценарии, котор ый
с завидным постоянством не хочет запускаться, — обратитесь к спискам рассылки РНР (РНР Lis :s).
Их постоянно посещают сотни разработчиков, которые знают о РНР практически все. Только
оставьте там свое сообщение с вопросом, и вы сразу же получите на него ответ, не успев даже
убрать руки с клавиатуры. При этом существуют разные категории списков рассылки РНР, например
php-general (посвящен общим вопросам, связанным с РНР), php-db (посвяиен
вопросам взаимодействия РНР с базами данных), p h p - i n s t a l l (посвящен вопросам установки
РНР), php-windows (посвящен работе РНР под управлением операционной системы
Windows) и т.д. Существует возможность подписаться на такие списки рассылки.
Однако получение информации по подписке может оказаться достаточно трудоемким.
В этом случае можно получать по сто сообщений в день. Но, если вы только начинаете программировать
на РНР, анализ вопросов и предлагаемых решений может значительно вам помочь
в изучении РНР. В крайнем случае можно просто подписаться на сообщения о выпуске
новых версий РНР, что происходит не так часто.
www.php.net/mailing-lists.php
<&,qfio Zend
Ядро Zend является основой РНР. На этом Web-узле можно найти много интересной информации
о РНР, а также статьи, последние новости, списки проводимых семинаров и даже
предложения о работе.
http://zend.com
Л
Web-fieciffic THJ* Suilder
Этот Web-узел содержит множество ссылок на ресурсы для программистов РНР. Здесь
можно узнать о последних новостях РНР и найти полезные статьи. Кроме того, Web-узел РНР
Builder содержит примеры программ на РНР, которые разделены на следующие категории:
базы данных, календари, игры, изображения и т.д.
www.phpbuilder.com
Web-fieci/fic Black Beans
Если бы можно было пользоваться только одним Web-узлом, то Web-ресурс Black Beans слыл
бы достойным кандидатом на эту роль. Здесь содержится множество полезных статей о РНР, разнообразные
форумы, группы новостей, средства для создания сценариев РНР и многое другое.
www.black-beans.com.br/php_home_eng.htm
qua начинающих
Этот Web-узел будет особенно полезен для начинающих разработчиков
www.phpbeginner.com
Web-ftect/fic PHJ* 2)eu Center
На этом Web-узле содержатся очень полезные статьи и обучающие программы по РНР
как для новичков, так и для опытных разработчиков.
www.onlamp.com/php
Web-i/зел РНРМас .cont
Этот Web-узел ориентирован на использование языка РНР на платформе Мае. Подобного
рода информацию найти намного сложнее, чем, например, статьи об использовании РНР под
управлением операционных систем Windows или Linux/Unix.
www.phpmac.com
Tec/atafLofiM PHJ*
Этот Web-узел предоставляет набор редакторов и интегрированных средств разработки
(IDE — Integrated Development Environment) для создания приложений на РНР. На данный
момент он насчитывает около 105 наименований как бесплатных, так и коммерческих программных
продуктов. На узле также содержатся комментарии и замечания пользователей.
http://phpeditors.linuxbackup.co.uk
Web-fieciffic Sourceforge .net
Этот Web-узел является самым большим хранилищем приложений открытого кода и приложений
для Internet. Чтобы найти сценарии, написанные непосредственно на языке РНР,
следует выполнить такие действия.
Глава 16. Десять жизненно необходимых Web-ресурсов 271
1. Щелкните на вкладке Software Map основной страницы Web-узла.
2. В колонке справа выберите ссылку Programming Languages.
3. В колонке слева появится список языков программирования, из которого нужно
выбрать элемент РНР.
На данный момент узел насчитывает около 7000 проектов, связанных с языком РНР.
www.sourceforge.net
ftechuatfLnbte УУеЬ-хоапинговме цслцш
Данный Web-узел содержит список Web-хостинговых компаний, предоставляющих бесплатные
услуги по поддержке РНР. При этом каждая компания имеет свой рейтинг.
www.oinko.net/freephp
Web-tf3CA a?fflofta на&полщей книги
Существует Web-узел, который обеспечивает поддержку данной книги. Здесь можно наш и
примеры программного кода из книги, а также список исправленных ошибок. На этом Web-уз/ е
автор предлагает последние новости о РНР, а также список наиболее полезных Web-ресурсов.
http://janet.valade.com
272 Часть V. Великолепные десятки
Часть VI
Приложения
WOMOIMJM. Но ЙЛЙ тго'?
& sitLou чаани":•.
В приложениях вы найдете инструкции по установке модуля РНР в различных
операционных системах, а также исчерпывающий список наиболее
важных функций. Приложение Б написано таким образом, что вам не"
составит труда найти нужную функцию, в том числе те вопросы, которые
не рассматривались в данной книге.
НИ
Приложение А
Установка РНР
данном приложении содержатся рекомендации по установке РНР в операционных
системах Windows, Unix/Linux и Mac как для разработки Web-приложений, так и для
использования интерфейса командной строки CLI (Command Line Interface). Несмотря на то
что модуль РНР можно использовать совместно с различными Web-серверами, в данном приложении
основное внимание уделяется Web-серверам Apache и US (Microsoft Internet
Information Server), которые используются на 90% Web-узлов. Информацию об использовании
языка РНР под управлением других операционных систем или Web-серверов можно найти
на официальном Web-узле www. php. net.
В этом приложении рассматривается процесс установки РНР 5. Имейте в виду, что рекомендации
по установке более ранних версий могут несколько отличаться. Поэтому более
полную информацию по этому вопросу лучше поискать в файле i n s t a l l . t x t , который
входит в комплект поставки РНР.
Установка aioqifusi ?№Р в сиапемах
Unix/Clnux
Модуль РНР может использоваться либо в качестве модуля Web-сервера Apache для разработки
Web-приложений, либо в качестве автономного независимого модуля. Для получения
полной функциональности необходимо установить две разные версии РНР (для работы с сервером
Apache и РНР CLI). Ниже содержатся рекомендации по установке обеих версий.
Для установки РНР нужно загрузить исходные файлы, скомпилировать их, а затем установить
скомпилированные модули. Этот процесс не такой уж и сложный, как кажется на первый
взгляд. В последующих нескольких разделах содержатся подробные пошаговые инструкции,
которые могут существенно упростить весь процесс установки. При этом все
предварительные этапы лучше выполнить заранее, поскольку чем лучше вы подготовлены,
тем легче и быстрее пройдет весь процесс в целом.
Для пользователей операционной системы Linux. При установке большинства
версий системы Linux Web-сервер Apache и модуль РНР устанавливаются автоматически,
что позволяет избежать множества потенциальных проблем. Кроме
того, вместе с системой Linux поставляются как исходные файлы РНР, так и файлы
в формате RPM. (Их можно найти на установочном компакт-диске.) Но если
модуль РНР автоматически установлен вместе с операционной системой или путем
установки файлов RPM, то вы не сможете управлять его конфигурацией. Например,
очень часто версия РНР CLI автоматически не устанавливается, или
в файлах RPM отсутствует поддержка требуемой для работы баз данных. Кроме
того, при автоматической установке зачастую используются параметры, которые
в действительности могут никогда вам не понадобиться. Учитывайте также тот
/3
4!S2&
'<Ж^
*а«а.
факт, что в состав установочного комплекта системы Linux и файлов RPM, к ж
правило, входит не самая новая версия РНР. Поэтому самый эффективный способ
установки РНР заключается в использовании соответствующих исходных файле в.
Именно этим вопросам и посвящаются последующие разделы.
Перед установкой модуля РНР в системах Unix/Linux
Перед использованием модуля РНР и Web-сервера Apache для создания и поддержки
Web-узлов его нужно предварительно установить. Во многих версиях систем Unix/Linux сервер
Apache устанавливается по умолчанию. Однако перед установкой модуля РНР удостэ-
верьтесь в следующем.
S Используется версия Web-сервера Apache 1.3.0 или более новая. Для проверь
используемой версии Web-сервера Apache воспользуйтесь следующей командой:
h t t p d -v
Перед использованием этой команды перейдите в каталог, в котором находится
файл httpd.
С точки зрения обеспечения безопасности лучше всего использовать вереи ю
Apache 1.3.27 или выше.
В настоящее время совместное использование модуля РНР и сервера Apache
версии 2 возможно лишь в экспериментальном режиме. Поэтому для поддержим
коммерческих Web-приложений лучше использовать сервер Apache 1.3.
Установлен модуль Apache mod_so. В большинстве случаев это именно так.
Для получения списка всех подключенных модулей Apache выполните сл;-
дующую команду:
h t t p d -1
Как и в предыдущем случае, перед выполнением этой команды нужно перейти
в соответствующий каталог. В результате выполнения будет выведен достаточно
длинный список модулей, основным из которых (для модуля РНР)
является mod_so. Если этот модуль отсутствует, Web-сервер Apache необходимо
переустановить с использованием параметра --enable-module=so.
Установлена утилита apxs (или apxs2 для Apache 2). Как правило, утилита
apxs устанавливается вместе с Web-сервером Apache автоматически. Удостоверьтесь
в наличии файла apxs (который может находиться в каталоге
/ u s r / s b i n / a p x s ) . Если его удалось найти, значит, утилита apxs устанон-
лена. Если установка Apache осуществлялась с использованием RPM-файло >,
то утилита apxs, скорее всего, по умолчанию будет отсутствовать. Дело
в том, что файлы RPM обычно поставляются в двух версиях. Одна из них определяет
базовую функциональность сервера Apache, а вторая предоставляет
дополнительные средства разработки. Возможно, для установки утилиты
apxs придется воспользоваться второй версией.
Установка модуля РНР в системах Unix/Linux
Для установки модуля РНР версии 5 в системе Unix/Linux выполните следующие действия.
1. Зайдите на официальный Web-узел РНР www. php. net.
2. Перейдите в раздел Downloads.
276 Часть VI. Приложения
3. Выберите файл с исходным кодом последней версии РНР. На момент написания
данной книги такой версией была 5.0.0.
Откроется диалоговое окно.
4. Выберите режим сохранения файла.
Откроется диалоговое окно, в котором можно указать путь сохранения файла.
5. Выберите каталог, в котором нужно сохранить файл с исходным кодом
(например, / u s r / s r c ) . Затем щелкните на кнопке Save.
6. После завершения загрузки файла перейдите в каталог, в котором он был сохранен
(например, с помощью команды cd- / u s r / s r c ).
Вы увидите файл, имя которого начинается с символов php-, после которых указана
версия РНР. Файл имеет расширение t a r . gz и представляет собой архив. В нем содержится
много других файлов, заархивированных с помощью команды t a r . (Такие
файлы называются также tarball.)
7. Распакуйте загруженный файл.
Это можно сделать с помощью команды
gunzip -с php-5.0.0.tar.gz | tar -xf -
В результате будет создан каталог с именем php-5 . 0 . 0.
8. Перейдите в каталог, который был создан в результате распаковывания файла.
Для этого воспользуйтесь командой
cd php-5.0.0
9. Введите команду configure.
Для этого введите в командной строке команду . / c o n f i g u r e с необходимым набором
параметров. Если модуль РНР устанавливается для совместного использования
с Web-сервером Apache, введите следующую команду:
./configure --with-apxs
При этом на экран будет выведено множество строк. Подождите завершения команды
configure (это может занять несколько минут).
Наряду с приведенным параметром можно использовать и многие другие, позволяющие
подключить поддержку баз данных или изменить рабочие каталоги РНР. Параметры
команды configure более подробно описываются ниже, в разделе
"Параметры установки для операционных систем Unix/Linux/Mac".
Если путь к папке, где установлена утилита apxs, не найден, отобразится соответствующее
сообщение об ошибке. В этом случае необходимо определить точное
месторасположение утилиты apxs (например, с помощью команды f i nd /
-name apxs) и добавить соответствующий путь к параметру with-apxs.
В этом случае команда configure может выглядеть следующим образом:
. / c o n f i g u r e --with-apxs=/usr/sbin/apxs
При использовании Web-сервера Apache версии 2 необходимо использовать утилиту
apxs 2.
10. Введите команду make.
Приложение А. Установка РНР 277
При этом будет выведено большое количество строк. Подождите завершения выполнения
команды make. Это может занять несколько минут.
По умолчанию устанавливаются обе версии PHP, CGI и СЫ. Взаимодействие модуля I HP
с Web-сервером Apache обеспечивается файлом libphp5. so. В свою очередь, основным
файлом для версии PHPCLI является php, расположенный в каталоге РНР (например,
user/local/php). Если какую-либо из версий РНР устанавливать нет необходимости,
измените настроечные параметры команды configure, которые описываются ниже,
в разделе "Параметры установки для операционных систем Unix/Linux/Mac".
11. Введите команду make i n s t a l l.
В результате выполнения этой команды все необходимые файлы переместятся в соответствующие
каталоги. Например, версия РНР для Web будет установлена в катал эге
Apache (например, / u s r / l o c a l / a p a c h e / l i b e x e c / l i b p h p 5 . so).
Альтернативный метод установки вместе с сервером Apache
Иногда установить модуль РНР с использованием утилиты apxs не удается. В этом счу-
чае следует воспользоваться альтернативным методом установки, который и описывается
в данном разделе. Несмотря на то что утилита apxs в большинстве случаев работает к эр-
ректно и позволяет быстро установить модуль РНР, альтернативный способ иногда окаже гея
совсем нелишним. Ниже приведены соответствующие пошаговые инструкции.
1. Зайдите на официальный Web-узел РНР www. php .net.
2. Перейдите в раздел Downloads.
3. Выберите файл с исходным кодом последней версии РНР. На момент написания
данной книги это была версия 5.0.0.
Откроется диалоговое окно.
4. Выберите режим сохранения файла.
Откроется диалоговое окно, в котором можно указать путь, по которому сохранен фаЙ1.
5. Укажите каталог, в котором нужно сохранить файл с исходным кодам
(например, / u s r / s r c / p h p ) . Затем щелкните на кнопке Save.
6. После завершения загрузки файла перейдите в каталог, в котором он был сохранен
(например, с помощью команды cd- /usr/src/php).
Загруженный файл начинается с символов php-, после которых следует номер версии
РНР. Файл имеет расширение t a r . gz.
7. Распакуйте загруженный файл.
Это можно сделать с помощью команды
gunzip -с php-5.0.0.tar.gz | tar -xf -
В результате будет создан каталог с именем p h p - 5 . 0 . 0 c несколькими подкаталогами.
8. Повторите шаги 1-5 еще раз, однако на этот раз для загрузки файла с исходным
кодом Web-сервера Apache. Загрузите этот файл в каталог, где ранее был разар-
хивирован файл с исходным кодом РНР.
Исходный код сервера Apache можно найти по адресу h t t p d . apache. org.
Ниже в качестве примера рассматривается установка сервера Apache версии 1.3.27. На
момент написания данной книги это была его последняя версия.
278 Часть VI. Приложения
В настоящее время использовать РНР совместно с Web-сервером Apache 2 не рекомендуется.
Для того чтобы проверить, изменились ли соответствующие рекомендации,
посетите официальный Web-узел РНР.
9. Распакуйте архив с исходным кодом сервера Apache. Для этого воспользуйтесь
командой
gunzip a p a c h e _ l . 3 . 2 7 . t a r . gz | t a r -xf -
В результате выполнения всех предыдущих действия должно быть создано два каталога
php-5 . О . О и apache_l . 3 . 2 7 с набором подкаталогов.
10. Введите команду cd apache_l. 3 . 27.
11. Введите команду . /configure.
В данном случае входные параметры команды ни на что не влияют. Дело в том, что
так выполняется предварительная настройка Web-сервера Apache, которую нужно выполнить
перед настройкой модуля РНР. Позже эта команда будет использоваться повторно
с указанием соответствующих параметров. Дождитесь завершения выполнения
команды . /configure.
12. Введите команду cd . . /php-5 . 0 . 5 .
13. Введите команду
. / c o n f i g u r e --with-apache=../apache_l.3.27
Если для набора этой команды необходимо воспользоваться двумя строками, то в конце
первой из них следует поставить обратную косую черту (\).
Кроме приведенного выше параметра, при запуске команды configure можно использовать
и другие опции включения поддержки баз данных Или изменения рабочих
каталогов РНР. Более подробно они описываются ниже, в разделе "Параметры установки
для операционных систем Unix/Linux/Mac".
14. Введите команду make.
Отобразится подробный листинг. Дождитесь завершения выполнения команды make
(это может занять несколько минут).
15. Введите команду make i n s t a l l.
Ожидание ее завершения много времени не потребует.
16. Введите команду cd . . /apache_l .3.27 для возврата в корневой каталог сервера
Apache.
17. Для повторной настройки Web-сервера Apache введите команду
. / c o n f i g u r e --prefix=/www --activate-module=src/modules/php5/
l i b p h p 5 .a
Если эту команду нужно набрать в двух строках, в конце первой из них поставьте обратную
косую черту. Также обязательным является наличие символа пробела. Между
двумя параметрами не забудьте поставить как минимум один пробел.
18. Введите команду make.
Отобразится подробный листинг. Дождитесь завершения команды make (для этого
может потребоваться несколько минут).
Последний шаг, который нужно выполнить, зависит от того, был ли сервер Apache ранее
установлен, или это его первая установка.
Приложение А. Установка РНР 279
19. При первой установке Web-сервера Apache выполните команду make i n s t a l l ..
Если же сервер Apache ранее был уже установлен и запущен, выполните следующие
действия.
• Завершите выполнение сервера Apache.
Для этого можно запустить специальный сценарий, созданный при установке с ;р-
вера. Обычно он называется apachectl и содержится в подкаталоге b in основного
каталога Apache, например / u s r / local /apache/bin, /sbin или /usr/sb:.n.
Этот файл может также находиться в каталоге со сценариями автозагрузки
(например, / e t c / r e d / i n i t . d ) . Для завершения работы сервера Apache введите
команду apachectl stop.
• Найдите новый файл h t t p d , который был создан при выполнении п. 18.
Скорее всего, этот файл будет находиться в одном из подкаталогов основного каталога
apache, например / u s r / s r c / p h p / a p a c h e _ l . 3 . 2 7 / b i n / h t t p d.
• Найдите старый файл h t t p d , который существовал до установки.
Этот файл можно найти в каталоге / u s r / l o c a l / a p a c h e / b i n , /sbin иои
/ u s r / s b i n .
• Замените старый файл новым.
Перед копированием сделайте резервную копию старого файла httpd.
Если вы хотите обновить используемую версию РНР до более новой версии, а. е-
дует воспользоваться именно этим методом. При первой установке его при\е-
нять нельзя.
Уапановка мостил сианелв lA&ac
После выхода РНР 4.3 использовать модуль РНР в системе Мае стало так же просто, к ж
и в системах Unix/Linux. При этом модуль РНР может использоваться как совместно с Web-
сервером Apache (для поддержки Web-приложений), так и в качестве независимого интерпретатора.
Для обеспечения полной функциональности необходимо установить две отдельные
версии РНР, РНР для Web и РНР CLI. Ниже даны инструкции по установке обеих из них.
Для установки РНР нужно загрузить исходные файлы, скомпилировать их, а затем устан в-
вить скомпилированные модули. Этот процесс не такой уж и сложный, как кажется на первый
взгляд. В следующих разделах содержатся подробные пошаговые инструкции, которые
могут существенно упростить весь процесс установки. При этом все предварительные этаг ы
лучше выполнить заранее, поскольку чем лучше вы подготовлены, тем легче и быстрее про й-
дет весь процесс в целом.
Перед установкой модуля РНР в системе Мае
Перед использованием модуля РНР и Web-сервера Apache для создания и поддержки
Web-узлов его нужно предварительно установить. Во многих версиях системы Мае сервер
Apache устанавливается по умолчанию. Однако перед установкой модуля РНР удостоверьтесь
в следующем.
280 Часть VI. Приложения
•S Используется версия Web-сервера Apache 1.3.0 или более новая. Для проверки
используемой версии Web-сервера Apache воспользуйтесь командой
h t t p d -v
Перед использованием этой команды перейдите в каталог, в котором находится
файл h t tpd.
С точки зрения обеспечения безопасности лучше всего использовать версию
Apache 1.3.27 или выше.
В настоящее время совместное использование модуля РНР и сервера Apache
версии 2 возможно лишь в экспериментальном режиме. Поэтому для поддержки
коммерческих Web-приложений лучше использовать сервер Apache 1.3.
•/ Установлен модуль Apache mod_so. В большинстве случаев это именно так.
Для получения списка всех подключенных модулей Apache выполните команду
h t t p d -1
Как и в предыдущем случае, перед выполнением этой команды нужно перейти
в соответствующий каталог. В результате выполнения будет выведен достаточно
длинный список модулей, основным из которых (для модуля РНР)
является mod_so. Если этот модуль отсутствует, Web-сервер Apache необходимо
переустановить с использованием параметра --enable-module=so.
•S Установлена утилита apxs. В большинстве случаев утилита apxs устанавливается
вместе с Web-сервером Apache автоматически. Удостоверьтесь в наличии
файла с именем apxs (который может находиться в каталоге / u s r/
sbin/apxs). Если его удалось найти, значит, утилита apxs установлена.
S Установлены файлы с компакт-диска со средствами разработки. Обычно
этот вспомогательный компакт-диск входит в основной комплект поставки операционной
системы Mac OS X. Если его найти не удалось, все необходимые
средства можно загрузить с Web-узла developer.apple.com/tools/
macosxtools.html.
Установка модуля РНР в системе Мае
Для установки модуля РНР в операционной системе Мае выполните следующие действия.
1. Зайдите на официальный Web-узел РНР (www. php. net).
2. Перейдите в раздел Downloads.
3. Выберите файл с исходным кодом последней версии РНР. На момент написания
данной книги такой версией была 5.0.0.
Откроется диалоговое окно.
4. Выберите режим сохранения файла.
В появившемся диалоговом окне нужно указать путь, где будет сохранен файл.
5. Перейдите в каталог, в котором нужно сохранить файл с исходным кодом
(например, / u s r / s r c ) , а затем щелкните на кнопке Save.
6. После завершения загрузки файла перейдите в каталог, в котором он был сохранен
(например, с помощью команды cd- / u s r / s r c ).
Вы увидите файл, имя которого начинается с символов php-, после которых указана
версия РНР. Файл имеет расширение t a r . gz и представляет собой архив, который
может быть автоматически распакован программой Stuffit Expander. При этом появится
каталог php- 5.O.O. Если все именно так и произошло, можно сразу перейти к шагу 8.
Приложение А. Установка РНР 281
7. Распакуйте загруженный файл.
Это можно сделать с помощью команды
t a r xvfz php-5.О.О.tar. gz
При этом будет создан каталог с именем php-5 . О . О и несколькими подкаталогами.
8. Перейдите в новый каталог, который был создан при разархивировании файла.
Для этого можно воспользоваться, например, командой
cd php-5.0.0
9. Введите команду configure.
Для этого следует ввести команду . / c o n f i g u r e с набором необходимых параметров,
среди которых обязательными являются следующие.
Параметры местоположения. Поскольку в системе Мае файлы размещаются
в каталогах, которые отличаются от используемых модулем РНР по умолчанн ю,
их следует указать вручную. Воспользуйтесь следующим набором параметров:
--prefix=/usr
--sysconfdir=/etc
--localstatedir=/var
--mandir=/usr/share/man
Параметр z l i b : - - w i t h - z l i b.
Параметр Apache. Если модуль РНР устанавливается для совместного использования
с Web-сервером Apache, укажите также параметр —with-apxs.
Таким образом, для корректной настройки нужно воспользоваться командой
configure со следующими параметрами:
. / c o n f i g u r e - - p r e f i x = / u s r --sysconfdir=/etc
- - l o c a l s t a t e d i r = / v a r --mandir=/usr/share/man
—with-apxs
Если для набора этой команды требуются две строки, в конце первой из них i ю-
ставьте обратную косую черту (\).
Эта команда предоставляет подробный листинг. Дождитесь завершения ее исполнения
(это может занять несколько минут).
Если путь к папке, где установлена утилита apxs, не найден, то будет выведено
соответствующее сообщение об ошибке. В этом случае необходимо определить
точное месторасположение утилиты apxs (например, с помощью команды f i nd
/ -name apxs) и добавить соответствующий путь к параметру with-apxs (-
-with-apxs=/usr/sbin/apxs).
Если вы используете Web-сервера Apache 2, воспользуйтесь командой apxs 2.
Наряду с приведенными опциями можно использовать и другие, предназнач ;н-
ные для активизации поддержки баз данных или изменения различных устанонок
РНР. Более подробно они описаны ниже, в разделе "Параметры установки для
операционных систем Unix/Linux/Mac".
10. Введите команду make.
Эта команда предоставит подробный листинг. Дождитесь завершения этой команды
(на это может уйти несколько минут).
•
•
J0*
282 Часть VI. Приложения
По умолчанию устанавливаются обе версии PHP, CGI и CLI. Взаимодействие модуля
РНР с Web-сервером Apache обеспечивается файлом libphp5.so. В свою очередь,
основным файлом для версии РНР CLI является php, расположенный в каталоге РНР
(например, user / l o c a l /php). Если какую-либо из версий РНР устанавливать не
нужно, измените параметры настройки команды configure, которые описаны ниже,
в разделе "Параметры установки для операционных систем Unix/Linux/Mac".
11. Введите команду sudo make i n s t a l l.
jLaficutefnfibi цапанов&и qusi
операционных cuctfieui Unix/?inux/,Mac
В предыдущих разделах описывался пошаговый процесс установки модуля РНР в системах
Unix/Linux/Mac. Однако следует заметить, что при установке этого модуля можно использовать
различные параметры командной строки, а некоторые из них могут пригодиться
и вам. Например, вам может понадобиться поддержка различных баз данных, таких как
MySQL или Oracle, или вы захотите установить отдельные компоненты РНР в каталоги, отличные
от используемых по умолчанию. Кроме того, может возникнуть потребность и в использовании
дополнительного программного обеспечения.
Для активизации всех перечисленных возможностей в процессе установки РНР нужно
указать соответствующие параметры командной строки. Просто добавьте их при вызове команды
configure в п. 13 для систем Unix/Linux или при выполнении п. 9 для системы Мае.
При этом порядок этих параметров не играет никакой роли. В табл. АЛ приведены параметры
командной строки, которые в процессе установки модуля РНР используются чаще всего.
Для того чтобы получить полный перечень параметров, перейдите в каталог, в котором установлен
модуль РНР, и введите команду configure -help.
Таблица А.1. Параметры командной строки для настройки модуля РНР в системах Unix/Linux
Параметр Назначение
pref ix=PRFF/X Устанавливает PREFIX в качестве основного каталога РНР.
По умолчанию PflEF/X=/usr/local
i n f odir=D№? Устанавливает документацию в каталог О/Я. По умолчанию
DIR=PREFIX/ i n fo
mandir=D/fl Устанавливает файлы справочного руководства в каталог О/Я.
По умолчанию DIR=PREFIX/man
with-conf i g - f ile-path=D/fl Задает путь О/Я, в котором будет размещаться конфигурационный файл
php. i n i . Этот файл требуется для корректного функционирования
модуля РНР. По умолчанию D//?=/usr/local/lib
disabie-cgi Отменяет установку двоичных файлов РНР CGI
disable-cli Отменяет установку двоичных файлов РНР CU
disable-libxml Отключает поддержку XML
enable-debugger Включает поддержку отладчика
enable- ftp Включает поддержку протокола FTP
enable-url-include Позволяет с помощью функции include () извлекать файлы из
каталогов HTTP и FTP, а также из каталога include
Приложение А. Установка РНР 283
Окончание табл 4.1
Параметр Назначение
with-msql=DW
with-mysql=D/f?
with-mysqli=D/R
with-openssl=DOT
with-oracle=D/fl
with-pgsql =DIR
with-servlet=D/fl
with-xml
Включает поддержку mSQL. DIR — это исходный каталог mSQL, которо лу
по умолчанию соответствует каталог / u s r / l o c a l / H u g h es
Включает поддержку MySQL версии 4.0 или ниже. Параметр DIR — этс
исходный каталог MySQL, которому по умолчанию соответствует кататсг
/ u s r / l o c a l / H u g h es
Включает поддержку MySQL версии 4.1 или выше. Параметр DIR
определяет путь к файлу m y s q l _ c o n f i g , установленному вместе
с MySQL. Для него путь по умолчанию не задан
Включает поддержку протокола OpenSSL для безопасного сервера.
Требуется установленная версия OpenSSL 0.9.5 или выше
Включает поддержку Oracle. Параметру DIR по умолчанию соответствует
каталог, заданный в переменной окружения ORACLE_HOME
Включает поддержку баз данных PostgreSQL Параметр DIR задает
исходный каталог PostgreSQL. По умолчанию используется каталог
/ u s r / l o c a l / p g s q l
Включает поддержку сервлетов. Параметр DIR определяет основной
каталог JSDK. При этом расширение Java должно быть подключено кг к
dll-библиотека
Включает поддержку XML
Настройка сервера Apache и модуля РНР в системах
Unix/Linux/Mac
Модуль РНР использует конфигурационный файл php. i n i , в котором определены различные
параметры настройки, которые в случае необходимости можно изменить. Этот оайл
считывается каждый раз при загрузке модуля РНР и по умолчанию размещается в ката ноге
/ u s r / l o c a l / l i b / p h p . i n i . Однако, как уже упоминалось в предыдущем разделе, в прогессе
установки этот путь можно изменить с помощью соответствующего параметра. Если в ук; данном
каталоге файл php. i n i не найден, используются значения, установленные по умолчанию.
Файл php. i n i необходимо скопировать в требуемый каталог вручную. Исходный конфигурационный
файл php. i n i - d i s t (с параметрами по умолчанию) можно найти в корневом
каталоге РНР. Для того чтобы скопировать файл php. i n i - d i s t в требуемый катшог,
воспользуйтесь командой
ср p h p . i n i - d i s t / u s r / l o c a l / l i b / p h p . i ni
sudo cp p h p . i n i - d i s t / u s r / l o c a l / l i b / p h p . i ni
в операционной системе Mac.
После этого в файл php. i n i можно вносить необходимые изменения, хотя значеню:, установленные
по умолчанию, также обеспечат корректное функционирование модуля ?НР.
Многие параметры и соответствующие им значения рассматриваются в различных раз,гелах
данной книги, материал которых имеет к ним непосредственное отношение. Например, ложно
изменить значения параметров в файле php. i n i и таким образом модифицировать процедуру
обработки ошибок и отображения соответствующих сообщений. Эти вопросы подробно
рассматривались в главе 4.
284 Часть VI. Приложения
Если модуль PHP используется совместно с Web-сервером Apache, то его нужно настроить
на корректное распознавание файлов с расширением .php. Для этого выполните следующие
действия.
1. Найдите конфигурационный файл сервера Apache httpd. conf.
Он может находиться в каталоге / e t c или /usr/local/apache/conf. В операционной
системе Мае этот файл можно поискать в каталоге /etc/httpd. Для корректного
функционирования модуля РНР в файл httpd. conf Web-сервера Apache нужно
внести соответствующие изменения.
2. Добавьте в файл httpd. conf строку, обеспечивающую загрузку модуля РНР.
Для этого найдите строку с директивой LoadModule и модифицируйте ее следующим
образом:
LoadModule php5_module libexec/libphp5.so
Удостоверьтесь в том, что такая строка имеется в файле httpd. conf. Если ее в нем
нет, нужно внести соответствующие изменения. Если в начале строки с директивой
LoadModule содержится символ решетки (#), удалите его.
3. Добавьте в файл httpd.conf строку с расширениями файлов, которые могут
содержать код на языке РНР.
Сначала найдите строки с директивой AddType. Таких строк может быть несколько.
(Каждая из них может использоваться различным программным обеспечением.) В частности,
для модуля РНР нужно добавить строку
AddType application/x-httpd-php .php
Удостоверьтесь в том, что такая строка имеется в файле httpd. conf. Если в начале
строки содержится символ решетки, удалите его. Директива AddType указывает серверу,
в файлах с каким расширением (. php) следует искать код РНР. По мере необходимости
можно добавить и другие расширения. При работе в операционной системе
Мае эту строку необходимо добавить в конец файла h t t p d . conf.
4. Только для пользователей операционной системы Мае. Если ранее уже был установлен
модуль РНР, входящий в комплект поставки системы Мае, закомментируйте
следующие строки:
LoadModule hfs_apple_module
libexec/httpd/mod_hfs_apple.so
AddModule mod_hfs_apple.с
Для этого в начало каждой строки достаточно добавить символ решетки (#).
5. Запустите или перезапустите заново Web-сервер Apache.
Для запуска или перезапуска Web-сервера Apache можно воспользоваться специальным
сценарием, который устанавливается при его установке. Он может называться
apachectl или httpd. apache и содержаться в каталоге /bin или
/ u s r / l o c a l / a p a c h e / b i n . Например, если сценарий называется apachectl, то
для запуска сервера Apache введите команду apachectl s t a r t , для его перезапуска—
команду apachectl r e s t a r t , а для останова—команду apachectl stop.
При работе в операционной системе Мае нужно воспользоваться также дополнительной
командой sudo, например sudo apachectl r e s t a r t . Иногда при перезапуске
сервера Apache новые параметры не вступают в силу. В этом случае остановите работу
сервера, а затем запустите его заново. Зачастую сервер Apache запускается сразу
же при включении компьютера. Поэтому при возникновении любых проблем можно
просто выключить компьютер, а затем включить его заново.
Приложение А. Установка РНР 285
дои!!*/
(ш После любых изменений в конфигурационном файле p h p . i n i Web-cepeip
Apache необходимо перезапустить.
Установка РН? в cuaneuie Windows
Модуль РНР можно использовать также в системах Windows 98/Ме (хотя это и не рекоме и-
дуется) и Windows NT/2000/XP. Его можно установить для использования совместно с Web-
сервером (версия РНР CGI) для поддержки Web-узлов или для создания независимых сценаригв
(PHPCLI). Для функционирования двух этих различных версий языка РНР требуются разние
исполняемые файлы. Можно установить одновременно обе версии либо только одну из них.
В системе Windows модуль РНР можно установить двумя способами: автоматически,
с помощью программы установки, или вручную, воспользовавшись архивным файлом .zip.
Конкретный способ установки зависит от того, для чего вы планируете применять язык РНР.
При выборе метода установки руководствуйтесь следующими рекомендациями.
•S Автоматическая программа установки позволяет установить только версию
РНР CGI. При этом можно указать, какие компоненты РНР вам требуются.
Например, интерфейс ODBC предназначен для взаимодействия с базами
данных (такими как MS Access) или с расширением SQlite, которэе
используется для хранения данных в текстовых файлах. (Вопросы взаимодействия
РНР с базами данных подробно рассматривались в главе 12.)
Можно также подключить расширения для работы с языком XML, протоколом
FTP и объектами СОМ. Однако данный метод установки не позволяет
инсталлировать версию РНР CLI.
Этот простой и быстрый метод установки нужно использовать в следующих
случаях.
• Модуль РНР планируется использовать только для разработки и поддер к-
ки Web-приложений, а версия РНР CLI не требуется.
• Модуль РНР используется для генерации кода HTML или обработки данных
HTML-форм.
• Вам не требуется взаимодействие с базами данных или вполне достаточ ю
интерфейса ODBC.
• Все поставленные задачи позволяет решить встроенная функциональность
модуля РНР.
S Установка вручную. Все установочные файлы содержатся в архивном файле
. zip. Этот файл нужно загрузить, разархивировать, а затем разместить порученные
файлы в соответствующих каталогах.
При установке вручную модуль РНР обладает большей функциональностью.
Если вам понадобился некоторый компонент РНР (например, интерфейс
РНР CLI или расширение для работы с базой данных), то его придется установить
вручную. При этом все необходимые файлы можно найти в загружс н-
ном архивном файле . zip. Различные расширения языка РНР подробно рассматривались
в главе 14.
286 Часть VI. Приложения
Автоматическая установка PHP CGI
Приведенная ниже последовательность действий позволит установить модуль РНР в системе
Windows, предназначенный для разработки Web-приложений. Не забывайте о том, что
при этом версия PHP CLI не устанавливается.
1. Введите в браузере URL-адрес www. php. net.
2. Перейдите в раздел Downloads.
3. Перейдите в раздел Windows Binaries. Щелкните на соответствующей ссылке,
чтобы загрузить программу установки последней версии РНР (на момент написания
книги — 5.0.0).
4. В результате будет выведен список зеркальных Web-узлов, с которых можно загрузить
требуемый файл. Выберите Web-узел, расположенный к вам ближе всего.
Откроется диалоговое окно.
5. Выберите режим сохранения файла.
В открывшемся диалоговом окне укажите путь к каталогу, в котором будет сохранен
загружаемый файл.
6. Перейдите в каталог, в котором нужно сохранить программу установки РНР,
а затем щелкните на кнопке Save.
После окончания загрузки файла перейдите в каталог, в котором он был сохранен. Имя
загруженного файла должно содержать символы php, номер версии РНР и строку
- i n s t a l l e r . e x e , например p h p 5 . 0 . 0 - i n s t a l l e r . e x e .
7. Если используемый Web-сервер запущен (кроме серверов IIS (Internet Information
Server) или PWS (Personal Web Server)), завершите его работу.
8. Перейдите в каталог с загруженным файлом и дважды щелкните на его имени
(php5 . 0 . О-installer. ехе).
Появится окно, показанное на рис. АЛ.
, и | ' Wefc©metoPHP4.3.1 Setupprogram. IHs
i t i b * program wiS instait PHP 4.ЯТ on your computet.
You may need to stop jkiut web serve» bete*
and PWS ф not need to be stopped
ClickCancel to qrjtSetib and then stop your webserver "i
necessary.' Ock.NeW .toicpntbue with the Setup program.-
WARHiNp: This program is protected by copyright taw and
international treaties.
sion number 1.СП8
Рис. А. 1. Окно мастера установки PHP
9. Щелкните на кнопке Next.
В новом диалоговом окне появится текст с лицензией.
10. Щелкните на кнопке I agree.
Появится диалоговое окно, в котором можно выбрать тип установки.
Приложение А. Установка РНР 287
11. Выберите тип Standard и щелкните на кнопке Next.
В появившемся окне можно выбрать каталог, в который будет установлен модуль РНР.
12. Если вас вполне устраивает установка РНР в каталог по умолчанию (с: \php),
щелкните на кнопке Next. В противном случае щелкните на кнопке Browse,
укажите подходящий каталог и после этого также щелкните на кнопке Next.
В появившемся диалоговом окне можно выбрать параметры электронной почты.
13. В диалоговом окне настройки электронной почты содержатся два поля, в которые
можно ввести адрес используемого сервера SMTP или адрес электронной
почты, который будет использоваться при отправке почтовых сообщений из
сценариев РНР. Если эти данные вам неизвестны, оставьте в этих полях значения,
установленные по умолчанию.
Позднее эти изменения можно внести и в конфигурационный файл модуля РНР.
Щелкните на кнопке Next.
В появившемся диалоговом окне (рис. А.2) содержится список Web-серверов, совместно
с которыми можно использовать модуль РНР.
14
Plea» seteet tf» type of blip «w vw you «eh to oonftpure to
run pl^.' ',•--,.
Г МиокЛ PWS on Windows 9*or ME
Г MiaotoftPWSonNTWotklHlion
Г Meroioll IIS 3 or tower
(•" Microsoft IIS I or higher
f~ Apache
Г Ktemi
f~ None (or other server]-1 wa* configure the web server manually
<Back 1 ^ ' < ;
Рис. А.2. В диалоговом окне Server Type программы
установки РНР можно выбрать используемый Web-сервер
15. Выберите используемый Web-сервер. Если в списке такого сервера нет, выберите
значение None.
16. Щелкните на кнопке Next.
Появится диалоговое окно Ready. Это свидетельствует о том, что программа установки
готова к инсталляции модуля РНР.
17. Для запуска процесса установки щелкните на кнопке Next.
После завершения установки модуля РНР 5.0.0 появится диалоговое окно со всей необходимой
информацией. Внимательно прочтите это сообщение. Если понадобит:я,
перезапустите Web-сервер. Например, при использовании Web-сервера Apache диалоговое
окно будет иметь вид, как на рис. А.З.
Получение этого сообщения вовсе не означает, что сервер Apache не установлен. Просто
для обеспечения его корректного взаимодействия с модулем РНР все настроьки
необходимо выполнить вручную. Как это сделать, вы узнаете из последующих раздел зв.
288 Часть VI. Приложения
Возможно, в скором будущем программа установки РНР будет вносить изменения
в конфигурационный файл сервера Apache автоматически, тем самым избавляя разработчиков
от лишних хлопот.
Л|>лс1ю ('iiiilic|in.itiiiii
So«y. the sollwate to «utomabcafe» contiguie
the Apache httpdcont Ш has not yet been
written. You will have to configure Apache
manually. See the php teadme tile tot nwe
OK
Рис. A3. Сообщение после завершения установки
РНР в случае использования Web-
сервера Apache
Установка модуля РНР вручную
Для того чтобы вручную установить модуль РНР 5 в системе Windows, выполните следующие
действия.
1. Зайдите на Web-узел www. php. n e t .
2. Перейдите в раздел Downloads.
3. Перейдите в раздел Windows Binaries и щелкните на ссылке для загрузки архивного
файла . zip последней версии РНР (на момент написания книги — 5.0.0).
dZ&z^ib. Если вам известен формат сжатия файлов . bz и вы знаете, как с ним работать,
у Ехэ Л можно загрузить именно такой файл. Он имеет меньший размер и соответственно
J/JjLx загрузится гораздо быстрее. Однако учитывайте тот факт, что такой формат сжа-
* > О Б Н О < ^ тия поддерживается не всем программным обеспечением.
4. В результате будет выведен список зеркальных Web-узлов, с которых можно загрузить
требуемый файл. Выберите Web-узел, расположенный к вам ближе всего.
Откроется диалоговое окно.
5. Выберите режим сохранения файла.
В открывшемся диалоговом окне можно указать путь к каталогу, в котором будет сохранен
загружаемый файл.
6. Перейдите в каталог, в котором нужно сохранить загружаемый файл, а затем
щелкните на кнопке Save.
После окончания загрузки файла зайдите в выбранный каталог и найдите там загруженный
файл. Его имя начинается с символов php, после них следует номер версии
РНР и строка -Win32 . zip, например php-5 . 0 . 0-win32 . zip.
7. Разархивируйте загруженный zip-файл в каталог, в который вы хотите установить
модуль РНР, например с: \php.
После двойного щелчка на имени zip-файла появится диалоговое окно программы,
которая используется для работы с архивными файлами, например WinZip или Pkzip.
Выберите режим разархивирования файла и каталог, в котором нужно разместить установочные
файлы.
Приложение А. Установка РНР 289
Вполне возможно, что при разархивировании zip-файла будет создан катале г
php-5 . О . О-Win32. В этом случае его имя можно заменить на более просто:,
например php. Тогда после установки файлов РНР на диск с: \ они будут размещены
в каталоге с : \php. Такой выбор удобен тем, что во многих конфигурационных
файлах необходимо указывать путь к каталогу, где установлен модуль PHP,
а в большинстве случаев по умолчанию используется именно каталог с: \php.
Не стоит устанавливать РНР в каталог, в имени которого содержится пробел, например
Program Files/PHP. Иногда из-за этого могут возникать проблемы.
После выполнения всех перечисленных выше шагов на вашем жестком диске будет
содержаться каталог со всеми необходимыми для работы файлами РНР.
8. В корневом каталоге РНР содержится файл php.ехе, предназначенный для работы
с интерфейсом командной строки PHPCLI. В случае необходимости его
можно переместить в любой другой каталог.
Настройка модуля РНР и Web-сервера в системе Windows
Для настройки работы модуля РНР предназначен специальный конфигурационный фай].
Кроме того, для того чтобы Web-сервер корректно обрабатывал сценарии РНР, необходим)
внести соответствующие изменения и в конфигурационный файл Web-сервера. Эти вопросы
и рассматриваются в данном разделе.
Настройка РНР в системе Windows
Модуль РНР использует конфигурационный файл php. i n i , в котором можно задать pas-
личные параметры настройки. Он считывается каждый раз при запуске РНР. Если использовалась
программа автоматической установки РНР, то этот файл создается автоматическ-i.
В противном случае файл php. i n i необходимо скопировать в требуемый каталог вручнуп.
Исходный конфигурационный файл php. i n i - d i s t (с параметрами по умолчанию) можно
найти в корневом каталоге РНР. В зависимости от используемой операционной системы его
необходимо переписать в один из следующих каталогов.
•S windows (в системах Windows 98/Ме/ХР)
•S winnt (в системах Windows NT/2000)
Если ранее был установлен модуль РНР (например, версии 4.3), сделайте резер з-
ную копию старого конфигурационного файла p h p . i n i , а используемые HJ-
стройки перенесите в новый файл.
При использовании Web-сервера US одно из значений по умолчанию необходимо измг-
нить. Для этого найдите в файле php. i n i следующую строку:
; c g i . f o r c e _ r e d i r e c t = 1
В этой строке укажите значение 0 и уберите символ комментариев (;) в ее начале:
cgi.force_redirect = 0
В большинстве случаев используемые по умолчанию параметры (кроме упомянутого выше)
обеспечивают корректную работу модуля РНР. Однако по мере необходимости их можно
изменить. Большинство параметров конфигурационного файла php. i n i рассматривались на
протяжении всей книги. Например, рекомендации по настройке режима вывода сообщений
об ошибках см. в главе 4.
290 Часть VI. Приложения
Настройка Web-сервера для работы с РНР
Для того чтобы Web-сервер корректно обрабатывал сценарии РНР, необходимо внести изменения
в его конфигурационный файл и обеспечить корректное распознавание файлов сценариев
РНР. Если модуль РНР бьш установлен с использованием автоматической программы инсталляции
и в системе установлен Web-сервер US или PWS (кроме IIS 6), то вся настройка выполняется
автоматически. Если же вы используете Web-сервер Apache или модуль РНР бьш установлен
вручную, то все изменения в конфигурационный файл придется внести самостоятельно.
Настройка Web-сервера Apache
Для настройки Web-сервера Apache выполните следующие действия.
1. Найдите конфигурационный файл Web-сервера h t t p d . conf.
2. Для этого выберите команду StartoPrograms1^Apach HTTP Serven=>Configure
Apache Server* Edit Configuration (Пуск^Программы* Apache HTTP
Serven=>Configure Apache ServeroEdit Configuration).
3. Если по каким-то причинам требуемая команда в меню отсутствует, то конфигурационный
файл можно поискать на жестком диске. Обычно этот файл содержится в подкаталоге
conf корневого каталога Apache (например, с: \Program Files\Apache
group\Apache\conf). Откройте его в любом текстовом редакторе, таком как
Notepad или WordPad.
4. Укажите в конфигурационном файле httpd.conf, чтобы файлы с кодом на
языке РНР передавались интерпретатору РНР. Для этого измените значения двух
следующих директив.
• ScriptAlias. Директива ScriptAlias позволяет задать имя-псевдоним полного
пути к каталогу, где установлен модуль РНР. Для этого найдите в файле h t t p d . conf
строку с директивой ScriptAlias. Таких строк может быть несколько, каждая из
которых предназначена для различных программных продуктов. Найдите строку,
относящуюся к модулю РНР (по необходимости эту строку нужно добавить):
ScriptAlias /php/ "c:/php/"
Первый аргумент определяет псевдоним (/php/), а второй— путь к модулю
РНР (с: /php/).
• Action. Директива Action используется для связывания всех файлов с типом
a p p l i c a t i o n / x - h t t p d - p h p с интерпретатором php-cgi.exe. В соответствующей
строке укажите следующее значение (если такая строка отсутствует, ее
нужно создать):
Action a p p l i c a t i o n / x - h t t p d - p h p "/php/php-cgi.exe"
Обратите внимание, что в приведенной строке используется имя-псевдоним, определяемое
директивой S c r i p t A l i a s . При изменении значения директивы
ScriptAlias сервер Apache будет искать файл php-cgi. exe в другом каталоге.
При указании путей лучше использовать косую черту (/). Web-сервер Apache
сможет обрабатывать их без особых проблем.
5. В конфигурационном файле h t t p d . conf укажите, в каких файлах может содержаться
код РНР.
Приложение А. Установка РНР 291
Для этого найдите в файле httpd.conf строку с директивой AddType. (Этих строк
тоже может быть несколько.) Найдите нужную строку, а при ее отсутствии — создайте.
AddType a p p l i c a t i o n / x - h t t p d - p h p .php
Посмотрите на эту строку. Если в ее начале содержится символ решетки (#), удалите ею.
Теперь для обработки файлов с расширением . php Web-сервер Apache будет обращен ь-
ся к интерпретатору РНР. По необходимости можно задать несколько таких расширений.
6. Запустите или перезапустите заново Web-сервер.
Для этого в системе Windows NT/2000/XP выберите команду Starts Programs1* Apach
HTTP Server=J>Control Apache Server (Пуск^Программы1*Apache HTTP Servers
Control Apache Server) и запустите Web-сервер как службу.
В системе Windows 98/Ме выберите команду Starts Programs1* Apach Web Servers
Management (Пуск^Программы"* Apach Web Server^Management).
Иногда после перезапуска сервера новые параметры не вступают в силу. В таком случае
завершите работу сервера Apache, а затем запустите его заново. Зачастую серв ;р
запускается при включении компьютера. Поэтому при возникновении каких-либо проблем
выключите компьютер, а затем включите.
Настройка сервера IIS вручную
Если модуль РНР был установлен с помощью программы автоматической инсталляцк и,
то при использовании IIS-сервера версии 5 и ниже все необходимые настройки также в л-
полняются автоматически. При установке модуля РНР вручную дело обстоит иначе: US-
сервер придется настраивать самостоятельно. Кроме того, ручная настройка версии
IIS 6/Windows Server 2003 понадобится в любом случае.
Для настройки IIS-сервера на использование модуля РНР выполните следующие действия.
1. Откройте управляющую консоль сервера IIS.
Для этого выберите команду Starts Programs'* Administrative Tools'* I nterret
Services Manager (ПускоПрограммы^Средства администратора^Управленне
службами Internet) или StartoSettingsoControl Panel*Administrative Tools*Internet
Services Manager (ПускОУстановки^Панель управления*>Средства администратора1*
Управление службами Internet).
2. Щелкните правой кнопкой мыши на вашем Web-узле.
3. В контекстном меню выберите команду Properties (Свойства).
4. Перейдите во вкладку Home Directory (Домашний каталог).
5. Щелкните на кнопке Configuration (Настроить).
6. Перейдите во вкладку Арр Mappings.
7. Щелкните на кнопке Add (Добавить).
8. В поле Executable введите путь к интерпретатору РНР, например
c : \ p h p \ p h p - c h i . e x e .
9. В поле Extension (Расширение) введите расширение . php.
Файлы с этим расширением будут обрабатываться интерпретатором РНР.
10. Установите флажок Script Engine.
11. Щелкните на кнопке ОК.
Повторите шаги 6-10, если необходимо добавить другие расширения файлов, которые (>у-
дут ассоциироваться с интерпретатором РНР, например .phtml.
292 Часть VI. Приложения
Приложение Б
Встроенные функции РНР
ся мощь языка РНР обусловлена множеством предоставляемых им функций, наиболее
полезные из которых приведены в данном приложении.
Некоторые из функций уже рассматривались в данной книге. В этом случае вы увидите
ссылку на соответствующую главу, в которой та или иная функция рассматривалась более
подробно.
Функции с/ля fiatfoffibi с массивами
В этом разделе рассматриваются функции для работы с массивами.
array О
Создает новый массив (см. главу 6).
Синтаксис: $array = array{ключ=>значение, ключ=>значение,
ключ=>значение, .. .) ;
array_count_values()
Возвращает массив, содержащий количество повторений значений в исходном массиве.
Синтаксис: $array_out = array_coun.t_values ($orig_array) ;
Например, если в массиве $orig_array содержатся значения
$orig_array[a] = Джон
$orig_array[b] = Мэри
$orig_array[cJ = Джон
$orig_array[d] = Джоуэ
то в возвращаемом функцией array_count_values () массиве $array_out будут содержаться
следующие элементы:
$array_out[Джон] = 2
$array_out[Мэри] = 1
$array_out[Джоуз] = 1
array_diff()
Возвращает массив элементов из исходного массива $массив1, которые не содержатся
в остальных массивах $массив2, $массивЗ и т.д. (см. главу 6).
Синтаксис:$array_out = array_diff($массив1, $массив2, $массивЗ, ...);
array_intersect()
Возвращает массив с элементами, которые присутствуют в двух или более массивах.
Синтаксис:$simArarray = a r r a y _ i n t e r s e c t($массив1, $массив2, . . . );
В
лггау_кеув ()
Возвращает массив ключей исходного массива $orig_array. Если указан параметр
ключ_поиска, то в результирующий массив будут включены только те значения, которые
соответствуют выражению ключ_поиска.
Синтаксис: $array_out = array_keys($orig_array, "ключ_поиска");
Например, если в массиве $orig_array содержатся значения
$orig_array[a] = СА
$orig_array[b] = OR
$orig_array[с] = TX
то в возвращаемом массиве $array_out будут содержаться следующие элементы:
$array_out[0] = а
$array_out[1] = b
$array_out[2] = с
Если же значение параметра ключ_поиска равно OR, т.е. функция array_keys () в л-
зывается следующим образом:
$array_out = array_keys($orig_array, OR);
то массив $array_out будет содержать элементы
$array_out[0] = b
array_merge ( )
Объединяет два или более массивов. Если несколько элементов имеют один и тот же нечисловой
ключ, то в результирующий массив будет добавлен лишь последний из них
(см. главу 6).
Синтаксис: $bigArray = аггау_тегде($массив1, $массив2, ...);
array_merge_recursive О
Объединяет два или более массивов. Если несколько элементов имеют один и тот же нечисловой
ключ, то в результирующем массиве будет содержаться массив со всеми этими элементами
(см. главу 6).
Синтаксис: $bigArray = array_merge_recursive {$массив1, $массив2, . . . I ;
аггау_рор()
Возвращает и удаляет последний элемент массива.
Синтаксис: $element = array_pop($orig_array);
array_push()
Добавляет указанные элементы в конец массива и возвращает его новый размер.
Синтаксис: $new_size = array_push($orig_array, "эл2", "эл2", "элЗ");
array_reverse()
Меняет на обратный порядок следования элементов массива $orig_array.
Синтаксис: $array_out = a r r a y „ r e v e r s e ( $ o r i g _ a r r a y );
array_search()
Производит поиск значения в массиве $orig_array и, если оно найдено, возвращает гго
ключ, в противном случае — значение FALSE.
Синтаксис: $key = array_search("значение", $orig_array);
294 Часть VI. Приложения
array_slice()
Создает новый массив $subArray с количеством элементов массива $orig_array,
начиная с позиции начало (см. главу 6).
Синтаксис: $subArray = a r r a y _ s l i c e ( $ o r i g _ a r r a y , начало, количество);
array_sum()
Возвращает сумму элементов исходного массива (см. главу 6).
Синтаксис: $ sum = array_sum($orig_array) ;
array_unique()
Удаляет из исходного массива повторяющиеся элементы (см. главу 6).
Синтаксис: $array_out = array_unique($orig_array);
arsortO
Сортирует массив $orig_array по значениям в обратном порядке с сохранением индексных
связей (см. главу 6).
Синтаксис: a r s o r t ($orig_array) ;
asort()
Сортирует массив $orig_array по значениям с сохранением индексных связей (см. главу 6).
Синтаксис: a s o r t ($orig_array) ;
compact()
Создает массив из заданных значений ($varl, $var2 и т.д.). Этими значениями могут
быть как текстовые строки, так и отдельные массивы.
Синтаксис: $array_out = compact($varl, $var2, ...);
count()
Возвращает число элементов в массиве $orig_array (см. главу 6).
Синтаксис:$size = count($orig_array);
current ()
Возвращает текущий элемент массива $аггау (см. главу 6).
Синтаксис: $value = c u r r e n t ( $ a r r a y );
end ()
Перемещает внутренний указатель массива $ a r r a y на последний элемент (См. главу 6.)
Синтаксис: $value = end($array);
explode ()
Создает массив подстрок исходной строки. При разбиении используется символ-
разделитель sep (зачастую в качестве такого символа используется запятая или символ табуляции)
(см. главу 6).
Синтаксис: $array_out = explode ("sep", $string) ;
extract()
Создает набор переменных по одной для каждого элемента исходного массива. В качестве
имени переменной используется ключ элемента (см. главу 6).
Синтаксис: e x t r a c t ($array) ;
Приложение Б. Встроенные функции РНР 295
implode()
Возвращает строку, содержащую значения элементов массива, разделенных символом-
разделителем sep (см. главу 6).
Синтаксис: $ s t r i n g • explode($array, "sep");
in_array()
Производит поиск значения в массиве $аггау. Если оно найдено, возвращается значение
TRUE, в противном случае — FALSE.
Синтаксис: $bool = in_array("значение", $array);
key ()
Возвращает ключ текущего элемента массива $ a r r a y .
Синтаксис: $key = key ($array) ,-
key_exists()
Производит поиск элемента с ключом в массиве $аггау. Если такой элемент найден, возвращается
значение TRUE, в противном случае — FALSE.
Синтаксис: $bool = key_exists("ключ", $array);
ksortО, krsort()
Сортируют исходный массив по ключам. Функция k s o r t () обеспечивает сортировку
в прямом порядке, в k r s o r t () — в обратном порядке (см. главу 6).
Синтаксис:ksort($array); k r s o r t ( $ a r r a y );
паtsort(), natcasesort()
Сортируют исходный массив по значениям в "естественном" порядке. Например, результатом
сортировки может быть nl, п2, п12, п25, а не n l , п12, п2, п25, как при обычной
сортировке. Функция n a t c a s e s o r t () выполняет сортировку с учетом регистра символен.
Синтаксис: n a t s o r t ( $ a r r a y ) ; n a t c a s e s o r t ( $ a r r a y );
next ()
Перемещает внутренний указатель массива $аггау к следующему элементу (см. главу 6).
Синтаксис: next ($array) ;
prev()
Перемещает внутренний указатель массива $аггау к предыдущему элементу (см. главу ().
Синтаксис: p r e v ( $ a r r a y ) ;
range ()
Создает массив с элементами из указанного диапазона. Диапазон может быть число! 1ым
(например, 1-10) или символьным (а-т или т-а).
Синтаксис:$array_out = range[начало, конец);
reset()
Устанавливает внутренний указатель массива $аггау на его первый элемент (см. главу 6).
Синтаксис: r e s e t ($array) ;
sizeofO
Возвращает число элементов массива $аггау (см. главу 6).
Синтаксис:$size = s i z e o f ( $ a r r a y );
296 Часть VI. Приложения
sort (), rsort ()
Сортируют исходный массив по значениям. Функция s o r t () сортирует элементы по
возрастанию, a r s o r t О — по убыванию (см. главу 6).
Синтаксис:sort($array); r s o r t ( $ a r r a y );
Функции с/лл ftarfotnu с осиной и в/ьеменем
В этом разделе содержатся функции для работы с датой и временем.
check.da.te ( )
Возвращает значение TRUE, если дата задана корректно, и FALSE — в противном случае.
Синтаксис:checkdate(месяц, день, год);
date О, gmdate()
Возвращает строку, соответствующую временной метке $timestamp в формате Unix,
которая отформатирована в соответствии со строкой формат. Функция gmdate () возвращает
среднее время по Гринвичу.
Синтаксис: $formatted_date = d a t e ("формат", $timestamp);
getdatei)
Создает массив с такими элементами, как секунды, минуты, месяцы, дни и т.д., которые
соответствуют заданной временной метке $timestamp в формате Unix.
Синтаксис: $array_date = getdate($timestamp);
localtime()
Создает массив с такими элементами, как секунды, минуты, месяцы, дни и т.д., которые
соответствуют местному времени.
Синтаксис: $array_date = localtime($timestamp);
microtime()
Возвращает время в секундах и микросекундах, прошедшее с 1 января 1970 года.
Синтаксис: $time_out = microtimeO;
mktimeO, gmmktime()
Возвращает временную метку Unix для заданной даты. Функция gmmktime () возвращает
среднее время по Гринвичу (см. главу 5).
Синтаксис: $timestamp = mktime(4acbi, минуты, секунды, месяц, день, год);
time С;
Возвращает временную метку Unix для текущего времени (см. главу 5).
Синтаксис: $ times tamp = time О;
(ptfMJcuuu аил fiaJotnbi с файловой сиапемой
В этом разделе рассматриваются функции для работы с файловой системой.
basename()
Извлекает полное имя файла из указанного пути (см. главу 13).
Синтаксис: $filename = basename ("путь") ;
Приложение Б. Встроенные функции РНР 297
cbdirO
Изменяет текущий каталог на путь_к_каталогу (см. главу 13).
Синтаксис: c h d i r (" путь_к_каталогу") ;
chgrpl)
Изменяет группу, которой принадлежит файл.
Синтаксис: chgrp (" путь_к_файлу", " группа") ;
cbmod()
Изменяет уровень доступа к файлу.
Синтаксис: chmod("путь_к_файлу", "восьмеричное_число") ;
cbownO
Изменяет владельца файла.
Синтаксис: chown (" путь_к_файлу", " новый_владелец") ;
closedirO
Закрывает каталог с дескриптором $dh (см. главу 13).
Синтаксис: c l o s e d i r ($dh) ;
copy ()
Создает копию файла (см. главу 13).
Синтаксис: сору (" старый_файл", " новый_файл") ;
dirnaiae ( )
Извлекает из заданного пути имя каталога (см. главу 13).
Синтаксис: $directory_name = dirname("путь") ;
d i s _ t o t a l _ s p a c e ( )
Возвращает общий объем диска в байтах.
Синтаксис: $space = d i s _ t o t a l _ s p a c e ("путь") ;
diek_free_space()
Возвращает объем свободного дискового пространства в байтах.
Синтаксис: $f гее = disk_free_space ("путь") ;
fсlose()
Закрывает открытый файл с дескриптором $fh (см. главу 12).
Синтаксис: fclose($fh) ;
feofO
Возвращает значение TRUE при достижении конца файла с идентификатором $ f h (см. главу II).
Синтаксис: feof ($fh) ;
fgetc()
Возвращает один символ (текущий) из файла с дескриптором $f h и перемещает указа-:ель
на следующий символ.
Синтаксис: $ char = fgetc($fh);
fgetcsv()
Считывает строку не больше заданной длины символов из файла, разбивает ее с учетом
символа-разделителя sep и возвращает массив с полученными подстроками (см. главу 12).
Синтаксис: $array_out = fgetcsv($fh, длина, "sep");
298 Часть VI. Приложения
fgets(), fgetssO
Считывает из файла с идентификатором $fh строку длиной не больше заданного
значения. Кроме того, функция f g e t s s () удаляет дескрипторы (см. главу 12).
Синтаксис: $ l i n e = fgets($fh, длина); $line = fgetss($fh, длина);
file ()
Возвращает массив, каждый элемент которого содержит отдельные строки заданного
файла (см. главу 12).
Синтаксис: a r r a y _ l i n e s = f i l e ( $ f h );
file_exists()
Проверяет существование файла (см. главу 13).
Синтаксис: $bool = f ile_exists("путь_к_файлу") ;
fileatimeO
Возвращает время последнего доступа к файлу (см. главу 13).
Синтаксис: $timestamp = f i l e a t i m e ("путь_к_файлу") ;
filectimeO
Возвращает время создания файла (см. главу 13).
Синтаксис: $timestamp = filectime("путь_к_файлу");
filemtimeO
Возвращает время последней модификации файла (см. главу 13).
Синтаксис: $timestamp = f ilemtime(" путь_к_файлу") ;
flleownerO
Возвращает идентификатор пользователя-владельца файла (см. главу 13).
Синтаксис: $userID = f ileowner ("путь_к_файлу") ;
fПерепав ( )
Возвращает разрешения, связанные с файлом.
Синтаксис: $perms = f ileperms (" путь_к_файлу") ;
fllesizeO
Возвращает размер файла в байтах (см. главу 13).
Синтаксис: $ s i z e = filesize("путь_к_файлу");
filetypeO
Возвращает тип файла, например файл или каталог (см. главу 13).
Синтаксис:$type = filetype("путь_к-файлу");
flock ()
Блокирует файл (см. главу 12).
Синтаксис: f ilelock("путь_к_файлу") ;
fopen ()
Открывает файл в заданном режиме и возвращает его дескриптор (см. главу 12).
Синтаксис: $fh = fopen (" путь_к_файлу", режим);
fput в ()
Записывает строку в файл. Возвращает количество записанных байт или значение FALSE,
если возникла ошибка (см. главу 12).
Синтаксис: $ r e s u l t = fputs($fh, "текст", длина);
Приложение Б. Встроенные функции РНР 299
fremdO
Считывает из файла заданное количество байт, если раньше не будет достигнут его конец
(см. главу 13).
Синтаксис:$file_content = fread($fh, количество);
fscant()
Считывает содержимое файла и возвращает отформатированную строку. (О способах
форматирования см. в главе 13.)
Синтаксис:$string = fscanf($fh, "формат", $vl, $v2, . . . ) ;
?seek()
Перемещает указатель в файле с идентификатором $f h на заданное число байт. Парамехр
режим может принимать следующие значения: SEEK_SET (смещение осуществляется от га-
чала файла), SEEK_CUR (с текущей позиции) и SEEK_END (от конца файла к его началу).
Синтаксис: f seek ($fh, число, режим);
fwriteO
Записывает строку текста в файл с дескриптором $f h. Параметр длина является необязательным
(см. главу 12).
Синтаксис: $bytes_written = fwrite($fh, "текст", длина);
getcwdO
Возвращает полный путь, соответствующий текущему каталогу.
Синтаксис: $ c u r r e n t _ d i r e c t o r y = getcwdO;
getlastmodO
Возвращает дату последней модификации текущего сценария.
Синтаксис: $timestamp = getlastmodO;
is_dir()
Возвращает значение TRUE, если путь задает каталог, и FALSE— в противном случае
(см. главу 13).
Синтаксис: $bool = i s _ d i r ( "путь") ;
is_file()
Возвращает значение TRUE, если путь определяет обычный файл, и FALSE — в противном
случае (см. главу 13).
Синтаксис: $bool = i s _ f i l e ( "путь") ;
is_readable()
Возвращает значение TRUE, если путь определяет доступный для чтения файл,
и FALSE — в противном случае (см. главу 13).
Синтаксис: $bool = i s _ r e a d a b l e ("путь_к_файлу") ;
is_uploaded()
Проверяет, был ли файл загружен через Web с использованием форм.
Синтаксис:$bool = is_uploaded("путь_к_файлу");
is_writable()
Возвращает значение TRUE, если путь_к_файлу задает доступный для записи фа{ л,
и FALSE — в противном случае (см. главу 13).
Синтаксис: $bool = i s _ w r i t a b l e ( " путь_к_файлу") ;
300 Часть VI. Приложения
mkdlrO
Создает новый каталог, Режим в восьмеричном формате определяет связываемые с ним
разрешения.
Синтаксис: mkdir (" путь_к_новому_каталогу", режим) ;
movm_\iploadmd_?lle()
Перемещает загруженный файл из временного каталога в постоянный (см. главу 11).
Синтаксис: move_uploaded_f i l e ( "имя_файла", "путь");
opendir()
Открывает каталог и возвращает соответствующий дескриптор (см. главу 13).
Синтаксис: $dh = opendir (" путь_к_каталогу");
paasthru()
Вызывает системную команду и выводит результат (см. главу 13).
Синтаксис: p a s s t h r u (" системная_команда") ;
pathinfoO
Возвращает ассоциативный массив с информацией о пути, В этом массиве содержатся три
элемента: dirname (каталог), basename (полное имя файла) и extension (расширение).
Синтаксис: $array_dir = pathinfof "путь") ;
readdirO
Считывает одно имя файла из открытого каталога (см. главу 13).
Синтаксис: $filename = r e a d d i r ($dh) ,-
readfilm()
Считывает файл и выводит его содержимое на стандартное устройство вывода. Возвращает
количество прочитанных байтов. Эта функция позволяет использовать и адреса URL.
Синтаксис:$numberOfBytesRead = readfile("путь_к_файлу");
rename О
Переименовывает файл.
Синтаксис:rename("старое_имя", "новое_имя");
rewind О
Перемещает указатель файла с дескриптором $f h на его начало.
Синтаксис: rewind($fh) ;
rmdirO
Удаляет каталог (см. главу 13).
Синтаксис: rmdir (" путь_к_каталогу");
tmpfileO
Создает временный файл с уникальным именем, открывает его с правом записи и возвращает
соответствующий дескриптор.
Синтаксис: $fh = t m p f i l e O;
touch()
Устанавливает время модификации файла. Если время не задано, используется текущее
время. Если файл не существует, создается новый файл.
Синтаксис: $bool = touch (" путь_к_файлу", время);
Приложение Б. Встроенные функции РНР 301
unmask ()
Изменяет разрешения, заданные по умолчанию, в соответствии с заданной маской и возвращает
старое значение. По завершении работы сценария старые значения восстанавливаются.
Синтаксис: $old_mask= unmask (маска) ;
unlink()
Удаляет файл (см. главу 13).
Синтаксис: unl ink (" путь_к_файлу") ;
Функции с/ля. fraJbifUrt с и/инноколом
HJT?
В этом разделе рассматриваются функции для работы с протоколом HTTP и электронной
почтой.
дв tjbrowser ( )
Позволяет получить информацию о текущем клиентском браузере или о браузере с заданным
именем.
Синтаксис: $ s t r i n g = get_browser("имя") ;
get_meta_tags ()
Создает массив, в элементах которого содержатся имена атрибутов всех дескрипторов
<meta>, обнаруженных в заданном файле.
Синтаксис:$array_tags = get_meta_tags("путь_к_файлу");
header()
Отправляет заголовок HTTP Web-серверу (см. главу 10).
Синтаксис: header (" заголовок_НТТР") ;
mail()
Отправляет сообщение по электронной почте из сценария РНР (см. главу 13).
Синтаксис: $success = mail ("кому", " тема_сообщения", "сообщение",
" заголовки") ;
parse_url()
Возвращает массив, в элементах которого содержатся различные элементы URL-адрсса,
такие как имя узла, путь, порт, имя пользователя и т.д.
Синтаксис: $array_url = parse_url("aMpec_URL");
setcookie()
Устанавливает данные cookie (см. главу 10).
Синтаксис: setcookie ("имя", "значение", время_жизни, "путь",
"домен", уровень_безопасности);
Uia/neyiariiuHecteue фцнщии
В этом разделе приведены основные математические функции. Такие функции, как cos
(косинус), t an (тангенс) или p i (значение числа я), в данном разделе не представлены.
302 Часть VI. Приложения
aba ()
Возвращает абсолютную величину числа.
Синтаксис: $absolute = abs (число) ;
blndecO
Преобразует двоичное число в десятичное.
Синтаксис: $number_decimal = bindec (двоичное_число) ;
ехр()
Возвращает значение константы е, возведенное в степень.
Синтаксис: $number = ехр (степень) ;
floorO
Округляет число до ближайшего меньшего целого.
Синтаксис: $ i n t = floor {число) ;
bexdecO
Преобразует шестнадцатеричное число в десятичное.
Синтаксис: $number_decimal = hexdec(число);
log()
Возвращает натуральный логарифм от заданного числа.
Синтаксис: $ log = log {число);
loglOO
Возвращает логарифм по основанию 10 от заданного числа.
Синтаксис: $logl0 = loglO {число) ;
max ()
Возвращает максимальное число из заданного множества. В качестве входного параметра
этой функции можно передать массив.
Синтаксис: $num_large = max($array) ; или $num_large = max(число1,
число2, . . . );
join с;
Возвращает минимальное число из заданного множества. В качестве входного параметра
этой функции можно передать массив.
Синтаксис: $num_min = min($array) ; или $num_min = min{число1,
число!, ...) ;
number^format ()
Форматирует число на основе заданного десятичного символа-разделителя и разделителя
тысяч. По умолчанию используются десятичная точка (.) и запятая (,) (см. главу 5).
Синтаксис: $formatted = number_format{число, "десятичный_символ",
"разделитель_тысяч");
octdecO
Преобразует восьмеричное число в десятичное представление.
Синтаксис:$number_decimal = octdec(число);
POw()
Возвращает число, возведенное в степень.
Синтаксис:$result = pow(число, степень);
Приложение Б. Встроенные функции РНР 303
rand ()
Генерирует случайную величину из заданного диапазона.
Синтаксис: $number_rand = rand(минимум, максимум);
round()
Округляет число с точностью до заданного количества десятичных цифр.
Синтаксис: $ r e s u l t = round{число, количество_цифр);
aqrt ()
Возвращает квадратный корень от заданного аргумента.
Синтаксис: $sguare_root = s g r t (число);
arand()
Инициализирует генератор случайных чисел с указанным начальным значением.
Синтаксис: srand(начальное_значение) ;
Функции qua fuzJoriibi с па/гам&н/гами
В этом разделе приведены функции для работы с параметрами РНР.
gmtmnvO
Возвращает значение переменной окружения.
Синтаксис: $environment_value = getenv("имя_переменной_окружения" I ;
gmtlaatmodO
Возвращает время последней модификации текущего сценария.
Синтаксис: $timestamp = getlastmod() ;
ini_gat ()
Возвращает значение конфигурационного параметра.
Синтаксис: $ s t r i n g = ini_get("параметр") ;
ini_set()
Устанавливает значение конфигурационного параметра (см. главу 4).
Синтаксис: i n i _ s e t ("параметр", " значение") ;
pbpinfoO
Предоставляет информацию о версии и параметрах модуля РНР (см. главу 4).
Синтаксис: phpinf о ( ) ;
phpvmraionO
Возвращает текущую версию РНР.
Синтаксис: $version = phpversionO ;
putenvf)
Добавляет переменную окружения. Обычно значение задается в виде
имя_переменной=зна чение.
Синтаксис: putenv (" значение") ;
304 Часть VI. Приложения
Стоковые функции
В этом разделе приведены функции для работы со строками.
addBlaeheeO
Возвращает строку без одинарных/двойных кавычек, обратной косой черты и символа \0.
Синтаксис:$string_escaped = addslashes("строка");
base64_encodeО, base64_decode()
Шифрует/декодирует строку с использованием алгоритма base64 (см. главу 13).
Синтаксис: $string_encoded = base64_encode("строка");
chop ()
Удаляет пробелы в конце строки.
Синтаксис:$chopped = chop("строка");
chr()
Возвращает символ ASCII, соответствующий заданному коду.
Синтаксис: $char = chr (KOUJUSCII) ;
count_chara()
Возвращает ассоциативный массив, ключами которого являются символы строки
$ s t r i n g , а значениями— их количество в заданной строке. Необязательный параметр
критерий позволяет выбрать символы только с нулевой или ненулевой частотой появления
и т.д. По умолчанию в ассоциативном массиве размещаются все символы строки $ s t r i n g.
Синтаксис:$array = c o u n t _ c h a r s ( $ s t r i n g , критерий);
mchoO
Выводит одну или более строк (см. главу 3).
Синтаксис: echo строка!, строка2, строкаЗ, ...;
eregO, eregiO
Выполняет поиск подстроки в строке $ s t r i n g , которая соответствует заданному шаблону.
При этом функция e r e g i () не учитывает регистр символов (см. главу 7).
Синтаксис: $bool • ereg("шаблон", $ s t r i n g );
ereg_replace(), eregi_replace()
Находит фрагмент строки $ s t r i n g , соответствующий указанному шаблону, и заменяет
его новой строкой. Функция ereg_replace() зависит от регистра символов, а функция
e r e g i _ r e p l a c e () — нет (см. главу 7).
Синтаксис: $new_string = ereg_replace(ereg_replace("шаблон",
"новая_строка", $string);
explode()
Создает массив, элементами которого являются части строки $ s t r i n g , отделенные друг
от друга символом-разделителем.
Синтаксис: $array_out = explode ("разделитель", $string) ;
htmlmntitima()
В строке $ o r i g _ s t r i n g переводит все объекты HTML в специальные символы.
Синтаксис: $string_out = h t m l e n t i t i e s ( $ o r i g _ s t r i n g );
Приложение 5. Встроенные функции РНР 305
htmlspecialcbara ()
В строке $ s t r i n g преобразует специальные символы в объекты HTML, как, например,
& — в &атр.
Синтаксис: $string_out = h t m l s p e c i a l c h a r s ( $ s t r i n g );
implode()
Объединяет элементы массива $аггау в одну строку и разделяет их с помощью разделите и.
Синтаксис: $string_out = implode ($array, "разделитель");
nl2br()
В заданной строке $ s t r i n g вставляет дескриптор <br /> перед каждым символом перевода
строки (\п).
Синтаксис:$string_out = n l 2 b r ( $ s t r i n g );
ord()
Возвращает ASCII-значение первого символа строки.
Синтаксис: $ i n t e g e t = ord(" строка") ;
parse_url ()
Создает ассоциированный массив, в элементах которого содержатся различные части
URL-адреса.
Синтаксис: $array = parse_url("anpec_URL");
print()
Выводит строку, число или значение переменной.
Синтаксис: p r i n t параметр;
printfO
Выводит строку в заданном формате (см. главу 5).
Синтаксис: p r i n t f ("формат", аргумент!, аргумент2, аргументЗ, . . .;
split О, splitiO
Создает массив, в элементах которого размещаются результаты разбиения строки
$ s t r i n g на отдельные фрагменты с учетом заданного регулярного выражения шаблон.
Функция s p l i t i () не учитывает регистр символов.
Синтаксис: $array = s p l i t ("шаблон", $string) ;
$array = s p l i t i ("шаблон", $string);
sprintf ( )
Возвращает строку, преобразованную в соответствии с заданным форматом (см. главу 5).
Синтаксис: $string = sprintf ("формат", аргумент1, аргумент2,
аргументЗ, . . .) ;
str_pad()
Удлиняет исходную строку $ s t r i n g до заданного размера.
Синтаксис: $ s t r i n g = s p r i n t f ( $ s t r i n g , длина, "заполнитель");
str_repeat()
Возвращает строку $ s t r i n g , продублированную заданное число раз.
Синтаксис: $string_out = s t r _ r e p e a t ( $ s t r i n g , число);
306 Часть VI. Приложения
str_repla.ce ()
Заменяет все вхождения старого_текста в строке $ s t r i n g на новый__текст.
Синтаксис: $string_out = str_replace("старый_текст", "новый_текст",
$ s t r i n g ) ;
strchrO, strrchar ()
Функция s t r c h rO возвращает часть строки $ s t r i n g , начиная с первого вхождения
символа и до ее конца, a s t r r c h a r () — начиная с заданного символа и до начала строки.
Синтаксис:$string_part = s t r c h r ( $ s t r i n g , "символ");
strcmpl), strcasecmp()
Эти функции выполняют сравнение двух строк. Если строка $ s t r l длиннее $ s t r 2 , возвращается
значение 1, в противном случае — значение - 1 . Если обе строки имеют одинаковую
длину, возвращается значение 0. Функция strcmp () учитывает регистр символов,
a strcasecmp () — нет.
Синтаксис: s t r c a s e c m p ( $ s t r l , $ s t r 2 );
strcapnO
Возвращает позицию первого вхождения заданного символа в строку $ s t r i n g.
Синтаксис: $ i n t = s t r c s p n ( $ s t r i n g , "символ");
strip_tasrs ( )
Удаляет из строки $ s t r i n g дескрипторы HTML и РНР. Необязательный параметр
разрешенные_дескрипторы позволяет задать символы, которые удаляться не будут
(см. главу 10).
Синтаксис: $ s t r i n g _ s t r i p p e d = s t r i p _ t a g s ( $ s t r i n g,
"разрешенные_дескрипторы");
strlenO
Возвращает длину строки $ s t r i n g в символах.
Синтаксис: $length = s t r l e n ( $ s t r i n g );
strposO, strrpos()
Функция s t r p o s () возвращает позицию первого вхождения заданного символа в строку
$ s t r i n g , a s t r r p o s () — последнего.
Синтаксис:$integer = s t r p o s ( $ s t r i n g , "символ");
$integer = s t r r p o s ( $ s t r i n g , "символ");
stratrO, stristri)
Возвращает часть строки $ s t r i n g , начиная с первого появления указанного символа и до
ее конца. Функция s t r s t r () учитывает регистр символов, а функция s t r i s t r () — нет.
Синтаксис:$str_part = s t r s t r ( $ s t r i n g , "символ");
$ s t r _ p a r t = s t r i s t r ( $ s t r i n g , "символ");
strtolower(), strtoupperO
Преобразуют строку $ s t r i n g в нижний и верхний регистр соответственно.
Синтаксис: $str_lower = s t r t o l o w e r ( $ s t r i n g ) ;
$str_upper = s t r t o u p p e r ( $ s t r i n g );
Приложение Б. Встроенные функции РНР 307
mtrtrl)
Эта функция заменяет в строке $ s t r i n g каждую подстроку старый_текст на подстроку
новый_текст.
Синтаксис: $string_out = s t r t r ( $ s t r i n g , "новый_текст",
"старый_текст");
subBtrO
Возвращает часть строки $ s t r i n g с заданной позиции и длин эй
количество_символов.
Синтаксис: $string_new = s u b s t r ( $ s t r i n g , начало,
количество_символов);
Bubatr_replace()
Заменяет часть строки $ s t r i n g новой_строкой с начальной позиции и длиной
количество_символов.
Синтаксис: $string_new = s u b s t r _ r e p l a c e ( $ s t r i n g , "новая_строки",
начало, количество_символов) ;
trlmO, ltrimO, rtrimO
Функция t r i m ( ) удаляет все пробелы в начале и в конце строки $ s t r i n g , l t r i m ( ) —
только в начале, a r t r im () — только в конце.
Синтаксис: $string_new = t r i m ( $ s t r i n g ) ;
ucfirst()
Переводит первый символ строки $ s t r i n g в верхний регистр.
Синтаксис: $string_new = u c f i r s t ( $ s t r i n g );
ucwordsO
Переводит в верхний регистр первые символы всех слов строки $ s t r i n g.
Синтаксис: $string_new = ucwords ( $ s t r i n g ) ;
wordwrap ()
Вставляет в строку $ s t r i n g символ перевода строки (\г\п) через указанное количество
символов и до конца строки.
Синтаксис:$string_new = wordwrap($string, количество_символов) ;
Функции сцлл fia^OfHH с переменными
В этом разделе приведены функции для работы с переменными.
empty ()
Определяет, присвоено ли переменной $varname какое-либо значение (см. главу 7).
Синтаксис: $bool = empty ($varname) ;
g-et__de? ined_classes ()
Создает массив с именами всех классов, используемых в сценарии (в том числе и в подключаемых
файлах).
Синтаксис: $ a r r a y _ c l a s s e s = get_def ined_classes () ;
gat_dafined_constant*()
Возвращает ассоциированный массив с именами всех констант.
308 Часть VI. Приложения
Синтаксис: $array_constants = get_defined_constants();
Sret_defined functions ()
Возвращает ассоциированный массив с именами всех функций.
Синтаксис: $array_functions = get_defined_functions();
get_defined_vare()
Возвращает массив с именами всех переменных.
Синтаксис:$array_vars • get_defined_vars();
issat ()
Проверяет, существует ли переменная $varname (см. главу 7).
Синтаксис: $bool = i s s e t ($varname) ;
print_r()
Выводит содержимое переменной $varname (см. главу 4).
Синтаксис: p r i n t _ r ($varname) ;
putenvO
Добавляет переменную окружения. Обычно параметр задается в виде имя_перемен-
ной=зяачение. *
Синтаксис: putenv (" параметр") ;
serialize()
Преобразует данные в двоичную строку. Эта функция оказывается полезной при сохранении
данных в файле или в базе данных. В качестве параметра $ v a r i a b l e можно использовать
любой тип данных, включая объект или функцию.
Синтаксис: $ s t r i n g _ s e r = s e r i a l i z e ( $ v a r i a b l e );
unserialize()
Восстанавливает сериализованные данные в первоначальном виде.
Синтаксис: $ v a r i a b l e = u n s e r i a l i z e ( $ s t r i n g _ s e r );
илs e t ()
Удаляет переменную с именем $varname (см. главу 4).
Синтаксис: unset ($varname) ;
var_dvmp()
Выводит содержимое переменной (см. главу 4).
Синтаксис: var_dump ($varname) ;
Приложение Б. Встроенные функции РНР 309
Предметный указатель
Access, 24
Apache, 34; 275
Arachnophilia, 41
ASCII-код, 115
Attribute, 149
Emacs, 41
Embedded scripting language, 25
Error message, 67
Exception, 27
Extension, 250
В
BBEdit, 41
BCMath, 250
C, 24; 60
Character string, 78
Class, 149
CLI, 39
Client-side language, 22
Command Line Interface (CLI), 46
Complex statement, 44
Concatenation, 81
Condition, 114
Conditional statement, 114; 121
Constructor, 154
cookie, 191
Core, 250
CSV, 213
ctype, 251
cURL, 252
File, 231
handle, 209
Transfer Protocol (FTP), 30
filePro, 24
Flat file, 27
Folder, 231
FrontBase, 24
FY?, 241
Function, 138
GET, 178
H
heredoc-механизм, 78
Hidden field, 195
HomeSite, 41
HTML-Kit, 41
HTML-форма, 170
Hypertext Preprocessing, 21
D
Data Source Name (DSN), 260
Database, 216
Management System (DBMS), 216
dBASE, 23
Directory, 231
handle, 235
Domain name, 33
Dreamweaver MX, 42
E
E_ALL, 66
EditPlus, 41
\
IBM DB2, 24
IIS, 275
Infinite loop, 131
Informix, 23
Ingres, 23
Inheritance, 150
Instantiation, 152; 157
Integrated Development Environment (IDE), A 0
InterBase, 24
Internet Information Server (IIS), 35
IPlanet, 35
IP-адрес, 33
J
Java, 60
JavaScript, 22; 205
К
Key, 89
Komodo, 42
L
localhost, 222
Loop, 114
M
Maguma, 42
Master class, 150
Method, 149
Microsoft SQL Server, 23
mSQL, 23
Multiple inheritance, 151
MySQL, 23; 259
N
Nesting, 124
Net_SMTP, 255
Netscape Enterprise Server, 35
Notice, 67
О
Object, 148
Open Database Connectivity (ODBC), 24; 216
Oracle, 23
Output statement, 49
P
Package manager, 256
Parent class, 150
Passing by reference, 144
PEAR (PHP Extension and Application
Repository), 250; 254
Perl, 24
Personal Home Page, 21
PHP
CGI, 39
CLI, 25; 27; 275
PHPEdit, 42
PHPUnit, 255
РНР-сценарий, 43; 113
Polymorphism, 151
POST, 178
PostgreSQL, 23
Property, 149
PWS, 291
Q
Query, 220
R
Regular expression, 116
Responsibility, 149
Returning value, 140
s
Secure Sockets Layer (SSL), 35; 170
Server-side language, 22
Session, 195; 207
ID, 195
Shell script, 24
Simple
Mail Transfer Protocol (SMTP), 245
statement, 43
SQLite, расширение, 27; 208; 229; 251
Structured Query Language (SQL), 220
Stuffit Expander, 281
Subclass, 150
Subdomain, 33
Sybase, 23
T
TextWrangler, 41
timestamp, 85
tokenizer, 251
TSV, 214
Type casting, 73
и
Uniform Resource Locator (URL), 25
V
Validating information, 179
Variable, 57
Предметный указатель 311
w Д
Warning message, 67
WDDX, 251
Web-окружение, 29
Web-приложение, 21
Web-сервер, 25; 26; 29
whois, 34
World Wide Web (WWW), 25
X
XML_Parser, 255
z
Zend, 27
Studio, 42
zlib, 251
A
Автоглобальный массив, 107
Автоматическая нумерация, 90
Архитектура PHP, 250
Атрибут, 149
maxlength, 174
Б
База данных, 23; 216; 259
Бесконечный цикл, 131
Блок, 44
Брандмауэр, 168
В
Включение файлов, 135
Вложение оператора, 124
Вложенный комментарий, 53
Возвращаемое значение, 140
Встроенная константа, 66
Встроенный
массив, 107; 177; 201
язык написания сценариев, 25
Г
Генерация исключения, 161
Глобальная переменная, 140
Двоичный файл, 248
Дескриптор
<form>, 189
PHP, 45
каталога, 235
файла, 209
Директива
include_path, 138
Indexes, 169
trans-sid, 196; 198
upload_tmp_dir, 201
Документирование сценариев, 52
Доменное имя, 32; 33
3
Загрузка файлов, 200
Запрос, 220
Значение по умолчанию, 143
И
Идентификатор, 57
группы, 232
сеанса, 195
Изменение порядка выполнения, 113
Именование переменных, 57
Индекс, 89
Инстанцирование, 152; 157
Интегрированная среда разработки, 40
основные возможности, 41
Интерпретатор, 25
Интерфейс CLI, 46
Исключение, 27; 161
К
Кавычки, 79
Каталог, 231
Класс, 149
Exception, 161
определение, 152
родительский, 150
Клиентский язык, 22
Ключ, 89
Ключевое слово, 64
Комментарий, 52; 53
Конкатенация, 81
312 Предметный указатель
Константа, 63
E_ALL, 68
встроенная, 66
Конструктор, 154
Копирование объектов, 161
Л
Логический тип, 72
Локальная переменная, 140
м
Массив, 56; 89
$_СООК1Е, 194
$_FILES, 201
$_GET, 192
$_SERVER, 107
$_SESSION, 196
встроенный, 107; 177
многомерный, 104
суперглобальный, 28
Менеджер пакета, 256
Метод, 149; 154
clone(), 161
_destruct(), 162
открытый, 158
передачи данных, 178
Многомерный массив, 104
Множественное наследование, 151
Модуль
mod_so, 276
PEAR, 254
н
Наследник, 150
Наследование, 150
Настройка Web-окружения, 34
О
Обработка
исключений, 27
кода РНР, 45
ошибок, 66; 147; 161
Обработчик ошибок, 71
Объединение
строк, 81
условий, 119
Объект, 148
Объектно-ориентированное программирование,
27; 148
Обязанность объекта, 149
Ограничение доступа, 159
Оператор, 43
break, 132
define, 63
echo, 43; 59; 62
foreach, 97
if, 121
switch, 124
вывода, 49
простой, 43
сложный, 44
условный, 114
Операционная система, 24; 236
Определение типа переменных, 72
Открытое программное обеспечение, 217
Открытый интерфейс доступа к базам данных, 24
п
Пакет
PEAR-DB, 259
подключение, 259
Папка, 231
Передача значений, 141
по ссылке, 144
Переменная, 57
$this, 154
переменной, 62
Переменная-счетчик, 126
Перемещение между страницами, 188
Персональная домашняя страница, 21
Повторное использование, 134
Поддомен, 33
Подкласс, 150
Полиморфизм, 151
Порядок выполнения операций, 75
Предупреждение, 67
Преобразование типов, 73
Приведение типов, 73
Проверка данных, 179
Простой тип, 72
Протокол
FTP, 30; 241
SMTP, 245
SSL, 35; 170
Предметный указатель 313
р ф
Расширение, 250
активизация, 252
файлов, 31
Регулярное выражение, 116; 180
Редактор кода, 41
Резервное копирование, 33
Родительский класс, 150
С
Свойство, 149
Сеанс, 191; 195; 207
Сервер, 22
Apache, 34
IIS, 35
iPlanet, 35
Серверный язык, 22
Символ, 78
специальный, 79
Система
регистрации доменных имен, 33
управления базами данных (СУБД), 216
Скрытое поле, 195; 199
Сложный оператор, 44
Сообщение об ошибке, 67
Сортировка массивов, 93
Специальный символ, 79; 117
Ссылка, 189
Строка, 72
Суперглобальный массив, 28; 107
Сценарий оболочки, 24; 47
т
Текстовая строка, 78; 117
Текстовый файл, 27; 208
Тип, 72
переменной, 116
У
Уведомление, 67
Удаление объектов, 162
Указатель массива, 96
Уровень проверки ошибок, 67
в сценарии, 68
Условие, 114
Условный оператор, 114; 121
Устранение ошибок, 265
Утилита сканирования, 168
314
Файл, 231
CSV, 213
httpd.conf, 38
php.ini, 38; 40; 48; 67
двоичный, 248
журнала, 69
текстовый, 229
Файловая система, 24
Форма, 23; 194
Форматирование
данных, 82
даты, 86
Функция, 138
date(), 86
die(), 71; 147
echoO, 73
emptyO, 179
ereg(), 119
exit(), 70
includeO, 135
mail(), 246
my_error_handler(), j \
number_format(), 77
print_r(), 59
printf(), 77
require(), 136
strtotimeO, 87
system(), 239
для обработки текстовых строк, 83
для работы
с HTTP и электронной почтой, 302
с датой и временем, 297
с массивами, 293
с параметрами РНР, 304
с переменными, 308
с файловой системой, 297
математическая, 302
передача значений, 141
сортировки массивов, 94
строковая, 305
X
Хостинговая компания, 31
ц
Целый тип, 72
Цикл, 114; 125
Предметный указатель
do..while, 130 a
for, 126
бесконечный, 131 Ядро, 250
Zend, 270
XT Язык
JavaScript, 22
Число с плавающей точкой, 72 серверный, 22
структурированных запросов, 220
э
Электронная
коммерция, 43
почта, 244
Предметный указатель 315
О I 0!
BESTSELL1NG
BOOK
SERIES
THT5
qjL& "чайников //TM
Специальные символы, используемые в шаблонах
СИМВОЛ Назначение Пример Соответствует шаблону
[ ]
П
Не
соот-
ветствует шаблону
Начало строки экзамен математический
экзамен
Конец строки н$ экзамен экзамены
Любой одиночный
символ
до, от а, 2
Более длинные слова
также соответствуют этому
шаблону, поскольку включают
текстовую строку из двух
символов
Предшествующий
символ является не
обязательным
ger?m germ, gem
( ) Группирует
буквенные символы в
последовательность,
которую в точности
должна содержать
строка
g(er)m germ
Включает набор
необязательных
символов
j[er]m gem,grm
Определяет все
символы, кроме
указанных
31 erjm gym, gum
Включает диапазон
всех символов,
заключенных между
двумя(ряд возможных
символов)
g[a-c]m gam, gbm, gem
geam
Gem, grem
germ, gel
gem, grem, germ
gdm, gxm, gal
\ +
4?*' *
• ^ * f n }
S. \
^ • 1 )
Один или
несколько наборов
предшествующих
символов
Один, ни одного или
несколько вхождений
предшествующего
символа
Повторение л раз
Определяет диапазон
повторений символа
(символов)
Определяет буквенный
символ
Набор альтернативных
строк
b l d g [ l - 3 ]4
ge*m
ge{5}m
а(2,5)
g\*m
(Сэм!
Салли)
bldg111,bldg132
gm, geeem
geeeeem
aa, aaa, aaaa, 145aaaaa
g*m
Салли
bldg,bldg555
germ,grm
geeeem, geeeeeem
1,a3
gem, germ
Сара, Салмон
BESTS ELUNG
BOOK
SERIES
Создание массивов
Метод создания массива
Использование пустых скобок
Использование ключей
Использование функции array
Использование функции array
Использование функции array
с ключами
Пример кода
Scolors[] » "красный"; •
Scolors [] = "синий";
Spaint ['house'] « "синий";
SpaintPbarn'] = "красный"
Scolors » аггау("синий",
"красный");
Scolors • array(5 •>
"синий", "красный");
Spaint = array("barn"
=> "красный", "house" •>
"зеленый");
Результат
Scolors[l) =
Scolors[2] -
Spaint[house
Spaint[barn)
Scolors[l] =
Scolors[2] =
Scolors[5] «
Scolors[6] «
Spaint[barn]
$paint[house
J ^ ^
красный;
синий; ^5
] • синий;
" красный; ^S
синий; J
красный; 3
синий; -д
красный; 4J
- красный; ^Я
] = зеленый; Ш
Многомерный массив S p a i n t P h o u s e ' H ' t a l l ' ] »
"желтый";
S p a i n t p b a r n ' j p t a l l ' ] =
"белый";
SpaintPhouse'] ["short') »
"синий";
SpaintPbarn'] [ ' s h o r t ' ] =
"красный";
$paint[house][tall] •
желтый;
$paint[barn][tall] =
белый;
$paint[house] [short] »
синий;
Spaint[barn] [short] =
красный;
One/iauuu сравнения
Операция
""
===
>
>=
<
<=
! =
!==
О
Описание
Равнозначны ли значения двух
переменных?
Одинаковы ли как значения, так и типы
двух переменных?
Больше ли первое значение, чем
второе?
Верно ли,что первое значение не
меньше второго?
Меньше ли первое значение, чем
второе?
Верно ли,что первое значение не
больше второго?
Не равны ли значения двух
переменных?
Не одинаковы ли значения или типы
данных двух переменных?
Не одинаковы ли значения или типы
данных двух переменных?
Лравила именования
nefieM?HHbix !PH!P
Должны начинаться с
символа доллара ($)
Могут быть любой длины
Могут включать буквы,
цифры и символы
подчеркивания
Должны начинаться с буквы
или символа подчеркивания,
но не цифры
Символы верхнего и нижнего
регистров различаются
Научно-популярное издание
Джанет Валейд
РНР 5 для "чайников"
В издании использованы карикатуры
американского художника Рича Теннанта
Литературный редактор
Верстка
Художественные редакторы
Корректоры
И.А. Попова
В. И. Бордюк
В.Г. Павлютин, Т. Тараброва
З.В. Александрова, Л.А. Гордиенко,
Л.В. Чернокозинская
Издательский дом "Вильяме".
101509, Москва, ул. Лесная, д. 43, стр. 1.
Подписано в печать 07.06.2005. Формат 70X100/16.
Гарнитура Times. Печать офсетная.
Усл. печ. л. 25,8. Уч.-изд. л. 18,72.
Тираж 3000 экз. Заказ № 1879.
Отпечатано с диапозитивов в ФГУП "Печатный двор"
Министерства РФ по делам печати, телерадиовещания
и средств массовых коммуникаций.
197110, Санкт-Петербург, Чкаловский пр., 15.