22-04-2003
Copyright © 1997, 1998, 1999, 2000, 2001, 2002, 2003 Группа Документирования PHP
Авторские права
Авторские права © Copyright 1997-2003 принадлежат Группе Документирования PHP. Члены этой группы перечислены на первой странице руководства.
Данное руководство может распространяться на условиях лицензии GNU General Public License, опубликованной Free Software Foundation; подразумевается 2 версия лицензии или (на ваше усмотрение) любая более поздняя версия.
Авторские права © 2000 на главу "Расширение возможностей PHP 4.0" принадлежат Zend Technologies, Ltd. Этот материал может распространяться только на условиях лицензии Open Publication License, 1 версии или любой более поздней версии (самая последняя версия доступна по адресу http://www.opencontent.org/openpub/).
PHP, что означает "PHP: Hypertext Preprocessor" ("PHP: Препроцессор гипертекста"), является широко используемым языком программирования общего назначения с открытым исходным кодом, внедряемым в HTML. Его синтаксис основан на синтаксисе языков C, Java и Perl и является легким для изучения. Главная цель языка состоит в предоставлении веб-разработчикам возможности быстро создавать динамически генерируемые веб-страницы. Кроме того, возможности PHP не ограничиваются только этим применением.
Главным образом, это руководство состоит из справочника по функциям, но также содержит руководство по языку, рассматривает наиболее заметные отличительные особенности PHP и разнообразные дополнительные сведения.
Вы можете загрузить это руководство в нескольких форматах по адресу http://www.php.net/docs.php. Файлы, доступные для загрузки по этому адресу, обновляются по мере внесения изменений в руководство. За более подробной информацией о том, каким образом ведется документирование, обратитесь к приложению 'Об этом руководстве'.
Обратитесь также к главе История PHP.
PHP (рекурсивный акроним словосочетания "PHP: Hypertext Preprocessor") - это широко используемый язык программирования общего назначения с открытым исходным кодом. PHP сконструирован специально для ведения Web-разработок и может внедряться в HTML-код.
Простой ответ, но что он может означать? Вот пример:
Обратите внимание на отличие этого скрипта от скриптов, написанных на других языках, например, на Perl или C - вместо того, чтобы создавать программу, которая занимается формированием HTML-кода и содержит бесчисленное множество предназначенных для этого команд, вы создаете HTML-код с несколькими внедренными командами PHP (в приведенном случае, предназначенными для вывода текста). Код PHP отделяется специальными начальным и конечным тегами, которые позволяют процессору PHP определять начало и конец участка HTML-кода, содержащего PHP-скрипт.
Значительным отличием PHP от какого-либо кода, выполняющегося на стороне клиента, например, JavaScript, является то, что PHP-скрипты выполняются на сервере. Если бы у вас на сервере был размещен скрипт, подобный вышеприведенному, клиент получил бы только результат выполнения скрипта, причем он не смог бы выяснить, какой именно код выполняется. Вы даже можете сконфигурировать свой сервер таким образом, чтобы HTML-файлы обрабатывались процессором PHP, так что клиенты даже не смогут узнать, получают ли они обычный HTML-файл или результат выполнения скрипта.
PHP крайне прост для освоения, но вместе с тем способен удовлетворить запросы профессиональных программистов. После того, как вы впервые услышали о PHP, и открыли это руководство, в течение нескольких часов вы уже сможете создавать простые PHP-скрипты.
Хотя PHP, главным образом, предназначен для работы в среде web-серверов, область его применения не ограничивается только этим. Читайте дальше и не пропустите главу Возможности PHP.
PHP может все. Главным образом, область применения PHP сфокусирована на написание скриптов, работающих на стороне сервера; таким образом, PHP способен выполнять всё то, что выполняет любая другая программа CGI, например, обрабатывать данных форм, генерировать динамические страницы или отсылать и принимать cookies. Но PHP способен выполнять и множество других задач.
Существуют три основных области, где используется PHP.
Создание скриптов для выполнения на стороне сервера. PHP наиболее широко используется именно таким образом. Все, что вам понадобится, это парсер PHP (в виде программы CGI или серверного модуля), вебсервер и броузер. Чтобы вы могли просматривать результаты выполнения PHP-скриптов в броузере, вам нужен работающий вебсервер и установленный PHP. За более подробными сведениями обратитесь к главе Советы по установке.
Создание скриптов для выполнения в командной строке. Вы можете создать PHP-скрипт, способный запускаться вне зависимости от вебсервера и броузера. Все, что вам потребуется - парсер PHP. Такой способ использования PHP идеально подходит для скриптов, которые должны выполняться регулярно, например, с помощью cron (на платформах *nix или Linux) или с помощью планировщика задач (Task Scheduler) на платформах Windows. Эти скрипты также могут быть использованы в задачах простой обработки текстов. За дополнительной информацией обращайтесь к главе Использование PHP в среде командной строки.
Создание приложений GUI, выполняющихся на стороне клиента. Возможно, PHP является не самым лучшим языком для создания подобных приложений, но, если вы очень хорошо знаете PHP и хотели бы использовать некоторые его возможности в своих клиент-приложениях, вы можете использовать PHP-GTK для создания таких приложений. Подобным образом вы можете создавать и кросс-платформенные приложения. PHP-GTK является расширением PHP и не поставляется вместе с дистрибутивом PHP. Если вы заинтересованы, посетите сайт PHP-GTK.
PHP доступен для большинства операционных систем, включая Linux, многие модификации Unix (такие, как HP-UX, Solaris и OpenBSD), Microsoft Windows, Mac OS X, RISC OS, и многих других. (Совершенно точно, что существует версия PHP для OS/2. Неизвестно, правда, насколько соответствующая нынешним реалиям - Прим.перев.) Также в PHP включена поддержка большинства современных вебсерверов, таких, как Apache, Microsoft Internet Information Server, Personal Web Server, серверов Netscape и iPlanet, сервера Oreilly Website Pro, Caudium, Xitami, OmniHTTPd и многих других. Для большинства серверов PHP поставляется в качестве модуля, для других, поддерживающих стандарт CGI, PHP может функционировать в качестве процессора CGI.
Таким образом, выбирая PHP, вы получаете свободу выбора операционной системы и вебсервера. Кроме того, у вас появляется выбор между использованием процедурного или объектно-ориентированного программирования или же их сочетания. Несмотря на то, что текущая версия PHP поддерживает не все особенности ООП, многие библиотеки кода и большие приложения (включая библиотеку PEAR) написаны только с использованием ООП.
PHP способен не только выдавать HTML. Возможности PHP включают формирование изображений, файлов PDF и даже роликов Flash (с использованием libswf и Ming), создаваемых "на лету". PHP также способен выдавать любые текстовые данные, такие, как XHTML и другие XML-файлы. PHP способен осуществлять автоматическую генерацию таких файлов и сохранять их в файловой системе вашего сервера вместо того, чтобы отдавать клиенту, организуя, таким образом, кеш динамического содержания, расположенный на стороне сервера.
Одним из значительных преимуществ PHP является поддержка широкого круга баз данных. Создание скрипта, использующего базы данных, - невероятно просто. В настоящее время PHP поддерживает следующие базы данных:
Также в PHP включена поддержка DBX для работы на абстрактном уровне, так что вы можете работать с любой базой данных, использующих DBX. Кроме того, PHP поддерживает ODBC (Open Database Connection standard), таким образом, вы можете работать с любой базой данных, поддерживающей этот всемирно признанный стандарт.
Adabas D Ingres Oracle (OCI7 и OCI8) dBase InterBase Ovrimos Empress FrontBase PostgreSQL FilePro (только чтение) mSQL Solid Hyperwave Direct MS-SQL Sybase IBM DB2 MySQL Velocis Informix ODBC Unix dbm
PHP также поддерживает "общение" с другими сервисами с использованием таких протоколов, как LDAP, IMAP, SNMP, NNTP, POP3, HTTP, COM (на платформах Windows) и многих других. Кроме того, вы получаете возможность работать с сетевыми сокетами "напрямую". PHP поддерживает стандарт обмена сложными структурами данных WDDX. Обращая внимание на взаимодействие между различными языками, следует упомянуть о поддержке объектов Java и возможности их использования в качестве объектов PHP. Для доступа к удаленным объектам вы можете использовать расширение CORBA.
PHP включает средства обработки текстовой информации, начиная с регулярных выражений Perl или POSIX Extended и заканчивая парсером документов XML. Для парсинга XML используются стандарты SAX и DOM. Для преобразования документов XML вы можете использовать расширение XSLT.
Используя PHP в области электронной коммерции, вы обратите внимание на функции осуществления платежей Cybercash, CyberMUT, VeriSign Payflow Pro и CCVS.
Последним по порядку, но не по значению, является поддержка многих других расширений, таких, как функции поисковой машины mnoGoSearch, функции IRC Gateway, функции для работы со сжатыми файлами (gzip, bz2), функции календарных вычислений, функции перевода...
Как вы видите, этой страницы не хватит для того, чтобы перечислить все, что может предложить вам PHP. Читайте следующую главу, Установка PHP и обратитесь к главе Справочник по функциям за более подробными сведениями о перечисленных выше расширениях.
В данном кратком руководстве на примерах объясняются основы PHP. Это руководство включает в себя только создание динамических Web-страниц с помощью PHP, однако реальная область применения PHP гораздо шире. В разделе "Что может PHP" приведена дополнительная информация.
Созданные с использованием PHP Web-страницы обрабатываются, как обычные HTML-страницы. Их можно создавать и изменять точно таким же образом, как и обычные страницы на HTML.
В данном руководстве мы предполагаем, что ваш сервер имеет поддержку PHP и что все файлы, заканчивающиеся на .php, обрабатываются PHP. В большинстве серверов это расширение используется для PHP по умолчанию, но все-таки не лишним будет уточнить это у вашего администратора сервера. Если ваш сервер поддерживает PHP, то у вас есть все, что требуется. Просто создавайте ваши файлы .php и размещайте их в вашем каталоге Web-сервера - они будут обрабатываться автоматически. Не нужно ничего компилировать, не нужно никаких дополнительных программ. Считайте файлы PHP обычными файлами HTML с набором новых "волшебных" тегов, которые позволяют вам делать все, что угодно.
Создайте файл с именем hello.php в корневом каталоге ваших документов Web-сервера и запишите в него следующее:
Заметим, что сходства со скриптами на CGI нет. Файл не обязан быть выполнимым или отмеченным любым другим образом. Это просто обычный файл HTML, в котором есть набор специальных тегов, делающих много интересного.
Эта программа чрезвычайно проста, и для создания настолько простой странички даже необязательно использовать PHP. Все что она делает - это выводит "Привет! с использованием функции PHP echo().
Если у вас этот пример не отображает ничего или выводит окно загрузки, или если вы видите весь этот файл в текстовом виде, то весьма вероятно, что ваш Web-сервер не имеет поддержки PHP. Попросите вашего администратора сервера включить такую поддержку. Предложите ему инструкцию по установке - раздел "Установка" данной документации. Если же вы хотите разрабатывать скрипты на PHP дома, то вам в раздел необходимые файлы. Дома можно разрабатывать скрипты с использованием любой операционной системы, но вам понадобится установить соответствующий Web-сервер.
Цель примера - показать формат специальных тегов PHP. В этом примере мы использовали <?php в качестве открывающего тега, затем шли команды PHP, завершающиеся закрывающим тегом ?>. Таким образом можно сколько угодно раз переходить к коду PHP в файле HTML.
Пара слов о текстовых редакторах: Существует множество текстовых редакторов и интегрированных сред разработки (IDE), в которых вы можете создавать и редактировать файлы PHP. Список некоторых редакторов содержится в разделе "Список редакторов PHP". Если вы хотите порекомендовать какой-либо редактор, посетите данную страницу и попросите добавить данный редактор в список.
Пара слов о текстовых процессорах: Текстовые процессоры (StarOffice Writer, Microsoft Word, Abiword и др.) в большинстве случаев не подходят для редактирования файлов PHP.
Если вы используете текстовый процессор для создания скриптов на PHP, вы должны быть уверены, что сохраняете файл, как ЧИСТО ТЕКСТОВЫЙ. В противном случае PHP не сможет обработать и выполнить вашу программу.
Пара слов о "Блокноте" Windows: При написании скриптов PHP с использованием встроенного "Блокнота" Windows необходимо сохранять файлы с расширением .php. "Блокнот" автоматически добавляет расширение .txt. Для обхода этой проблемы существует несколько методов.
Можно поместить название файла в кавычки (пример: "hello.php").
Кроме того, можно выбрать "Все файлы" вместо "Текстовые документы" из ниспадающего списка с типами файлов в окне сохранения. После этого можно вводить имя файла без кавычек.
Давайте сделаем что-нибудь полезное. К примеру, определим, какой браузер использует тот, кто смотрит в данный момент нашу страницу. Для этого мы проверим строку с именем браузера, посылаемую нам в HTTP-запросе. Эта информация хранится в переменной. Переменные в PHP всегда предваряются знаком доллара. Интересующая нас в данный момент переменная называется $_SERVER["HTTP_USER_AGENT"].
Пару слов об автоматической глобализации переменных в PHP: $_SERVER - специальная зарезервированная переменная PHP, которая содержит всю информацию, полученную от Web-сервера. Она является автоглобализованной (или суперглобальной). Для более подробной информации смотрите раздел "Суперглобальные переменные". Эти специальные переменные появились в PHP, начиная с версии 4.1.0. До этого использовались массивы $HTTP_*_VARS, такие, как $HTTP_SERVER_VARS. Эти массивы, несмотря на то, что они уже устарели, до сих пор существуют (см. замечания по старым программам).
Для вывода данной переменной мы сделаем так:
В PHP есть огромное количество типов переменных. В предыдущем примере мы печатали элемент массива. Массивы в PHP являются очень мощным средством.
$_SERVER - просто переменная, которая предоставлена вам языком PHP. Список таких переменных можно посмотреть в разделе "Зарезервированные переменные". А можно получить их полный список с помощью такой программы:
Если открыть данный файл в браузере, вы увидите страничку с информацией о PHP, а также список всех доступных вам переменных.
Внутрь тегов PHP можно помещать множество команд и создавать кусочки кода, делающие гораздо большее, чем просто вывод на экран. К примеру, если мы хотим сделать проверку на Internet Explorer, мы можем поступить так:
Пример 2-4. Пример использования управляющих структур и функций
Пример вывода данной программы:
|
Здесь мы показали несколько новых элементов. Во-первых, здесь есть команда if. Если вам знаком основной синтаксис языка C, то вы уже заметили что-то схожее. Если же вы не знаете C или подобного по синтаксису языка, то лучший вариант - взять какую-либо книжку по PHP и прочитать ее. Другой вариант - почитать раздел "Описание языка" данного руководства. Список книг по PHP можно найти здесь: http://www.php.net/books.php.
Во-вторых, здесь есть вызов функции strstr(). strstr() - встроенная в PHP функция, которая ищет одну строку в другой. В данном случае мы ищем строку "MSIE" в $_SERVER["HTTP_USER_AGENT"]. Если строка не найдена, эта функция возвращает FALSE, если найдена - TRUE. Если она вернет TRUE, то условие в if окажется истинным, и код в командных скобках ({ }) выполнится. В противном случае данный код не выполняется. Попробуйте создать аналогичные примеры с использованием команд if, else, и других функций, таких, как strtoupper() и strlen(). Также примеры содержатся во многих описаниях функций в данном руководстве.
Продемонстрируем, как можно входить в режим кода PHP и выходить из него прямо внутри кода:
Вместо использования команды PHP echo для вывода, мы вышли из режима кода и послали содержимое HTML. Важный момент здесь - то, что логическая структура кода PHP при этом не теряется. Только одна HTML-часть будет послана клиенту в зависимости от результата функции strstr() (другими словами, в зависимости от того, найдена строка "MSIE" или нет).
Одно из главнейших достоинств PHP - то, как он работает с формами HTML. Здесь основным является то, что каждый элемент формы автоматически станет доступен вашим программам на PHP. Для подробной информации об использовании форм в PHP читайте раздел " Переменные из внешних источников". Вот пример формы HTML:
В этой форме нет ничего особенного. Это обычная форма HTML без каких-либо специальных тегов. Когда пользователь заполнит форму и нажмет кнопку отправки, будет вызвана страница action.php. В этом файле может быть что-то вроде:
Принцип работы данного кода прост и понятен. Переменные The $_POST["name"] и $_POST["age"] автоматически установлены для вас средствами PHP. Ранее мы использовали переменную $_SERVER, здесь же мы точно также используем суперглобальную переменную $_POST, которая содержит все POST-данные. Заметим, что метод отправки нашей формы - POST. Если бы мы использовали метод GET, то информация нашей формы была бы в суперглобальной переменной $_GET. Также можно использовать переменную $_REQUEST, если источник данных не имеет значения. Эта переменная содержит смесь данных GET, POST, COOKIE и FILE. Также советуем взглянуть на описание функции import_request_variables().
Сейчас PHP является популярным языком сценариев (скриптов). Становится все больше и больше распространяемых кусочков кода, которые вы можете использовать в своих скриптах. В большинстве случаев разработчики PHP старались сохранить совместимость с предыдущими версиями так, что код, написанный для более старой версии будет идеально работать и с новыми версиями языка без каких-либо изменений. Однако случается так, что изменения все-таки необходимы.
Есть два важных изменения, которые влияют на старые программы:
Объявление массивов $HTTP_*_VARS устаревшими. Эти массивы требовали глобализации в функциях и процедурах. Новые суперглобальные массивы были введены, начиная с PHP 4.1.0. Это: $_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_REQUEST, и $_SESSION. Более старые массивы $HTTP_*_VARS, такие, как $HTTP_POST_VARS, существуют со времен PHP 3 и, вероятно, будут еще долго существовать для сохранения совместимости.
Внешние переменные больше не глобализуются по умолчанию. Другими словами, директива register_globals в php.ini по умолчанию отключена ("off"), начиная с PHP 4.2.0. Рекомендуемый метод доступа к таким переменным - суперглобальные массивы, описанные выше. Более старые программы, книги и руководства могут считать, что данная директива включена ("on"). К примеру, переменная $id может поступать из строки URL http://www.example.com/foo.php?id=42. Когда указанная директива выключена, $id доступна лишь как $_GET['id'].
То, что вы узнали, поможет вам понять большую часть руководства и разобраться в большинстве приведенных примеров программ. Другие примеры находятся на различных сайтах, ссылки на которые можно найти на php.net: http://www.php.net/links.php.
Before installing first, you need to know what do you want to use PHP for. There are three main fields you can use PHP, as described in the What can PHP do? section:
Server-side scripting
Command line scripting
Client-side GUI applications
For the first and most common form, you need three things: PHP itself, a web server and a web browser. You probably already have a web browser, and depending on your operating system setup, you may also have a web server (eg. Apache on Linux or IIS on Windows). You may also rent webspace at a company. This way, you don't need to set up anything on your own, only write your PHP scripts, upload it to the server you rent, and see the results in your browser.
While setting up the server and PHP on your own, you have two choices for the method of connecting PHP to the server. For many servers PHP has a direct module interface (also called SAPI). These servers include Apache, Microsoft Internet Information Server, Netscape and iPlanet servers. Many other servers have support for ISAPI, the Microsoft module interface (OmniHTTPd for example). If PHP has no module support for your web server, you can always use it as a CGI processor. This means you set up your server to use the command line executable of PHP (php.exe on Windows) to process all PHP file requests on the server.
If you are also interested to use PHP for command line scripting (eg. write scripts autogenerating some images for you offline, or processing text files depending on some arguments you pass to them), you always need the command line executable. For more information, read the section about writing command line PHP applications. In this case, you need no server and no browser.
With PHP you can also write client side GUI applications using the PHP-GTK extension. This is a completely different approach than writing web pages, as you do not output any HTML, but manage windows and objects within them. For more information about PHP-GTK, please visit the site dedicated to this extension. PHP-GTK is not included in the official PHP distribution.
From now on, this section deals with setting up PHP for web servers on Unix and Windows with server module interfaces and CGI executables.
Downloading PHP, the source code, and binary distributions for Windows can be found at http://www.php.net/. We recommend you to choose a mirror nearest to you for downloading the distributions.
This section contains notes and hints specific to installing PHP on HP-UX systems.
Пример 3-1. Installation Instructions for HP-UX 10
|
This section contains notes and hints specific to installing PHP on Linux distributions.
Many Linux distributions have some sort of package installation system, such as RPM. This can assist in setting up a standard configuration, but if you need to have a different set of features (such as a secure server, or a different database driver), you may need to build PHP and/or your webserver. If you are unfamiliar with building and compiling your own software, it is worth checking to see whether somebody has already built a packaged version of PHP with the features you need.
This section contains notes and hints specific to installing PHP on Mac OS X Server.
There are a few pre-packaged and pre-compiled versions of PHP for Mac OS X. This can help in setting up a standard configuration, but if you need to have a different set of features (such as a secure server, or a different database driver), you may need to build PHP and/or your web server yourself. If you are unfamiliar with building and compiling your own software, it's worth checking whether somebody has already built a packaged version of PHP with the features you need.
There are two slightly different versions of Mac OS X, client and server. The following is for OS X Server.
Пример 3-2. Mac OS X server install
|
Those tips are graciously provided by Marc Liyanage.
The PHP module for the Apache web server included in Mac OS X. This version includes support for the MySQL and PostgreSQL databases.
NOTE: Be careful when you do this, you could screw up your Apache web server!
Do this to install:
1. Open a terminal window
2. Type "wget http://www.diax.ch/users/liyanage/software/macosx/libphp4.so.gz", wait for download to finish
3. Type "gunzip libphp4.so.gz"
4. Type "sudo apxs -i -a -n php4 libphp4.so"
#AddType application/x-httpd-php .php #AddType application/x-httpd-php-source .phps |
Finally, type "sudo apachectl graceful" to restart the web server.
PHP should now be up and running. You can test it by dropping a file into your "Sites" folder which is called "test.php". Into that file, write this line: "<?php phpinfo() ?>".
Now open up 127.0.0.1/~your_username/test.php in your web browser. You should see a status table with information about the PHP module.
This section contains notes and hints specific to installing PHP on OpenBSD 3.2.
Using binary packages to install PHP on OpenBSD is the recommended and simplest method. The core package has been separated from the various modules, and each can be installed and removed independently from the others. The files you need can be found on your OpenBSD CD or on the FTP site.
The main package you need to install is php4-core-4.2.3.tgz, which contains the basic engine (plus gettext and iconv). Next, take a look at the module packages, such as php4-mysql-4.2.3.tgz or php4-imap-4.2.3.tgz. You need to use the phpxs command to activate and deactivate these modules in your php.ini.
Пример 3-3. OpenBSD Package Install Example
|
Read the packages(7) manual page for more information about binary packages on OpenBSD.
You can also compile up PHP from source using the ports tree. However, this is only recommended for users familiar with OpenBSD. The PHP4 port is split into three sub-directories: core, extensions and pear. The extensions directory generates sub-packages for all of the supported PHP modules. If you find you do not want to create some of these modules, use the no_* FLAVOR. For example, to skip building the imap module, set the FLAVOR to no_imap.
Older releases of OpenBSD used the FLAVORS system to compile up a statically linked PHP. Since it is hard to generate binary packages using this method, it is now deprecated. You can still use the old stable ports trees if you wish, but they are unsupported by the OpenBSD team. If you have any comments about this, the current maintainer for the port is Anil Madhavapeddy.
This section contains notes and hints specific to installing PHP on Solaris systems.
Solaris installs often lack C compilers and their related tools. The required software is as follows:
gcc (recommended, other C compilers may work)
make
flex
bison
m4
autoconf
automake
perl
gzip
tar
GNU sed
This section will guide you through the general configuration and installation of PHP on Unix systems. Be sure to investigate any sections specific to your platform or web server before you begin the process.
Prerequisite knowledge and software:
Basic UNIX skills (being able to operate "make" and a C compiler, if compiling)
An ANSI C compiler (if compiling)
flex (for compiling)
bison (for compiling)
A web server
Any module specific components (such as gd, pdf libs, etc.)
There are several ways to install PHP for the Unix platform, either with a compile and configure process, or through various pre-packaged methods. This documentation is mainly focused around the process of compiling and configuring PHP.
The initial PHP setup and configuration process is controlled by the use of the commandline options of the configure script. This page outlines the usage of the most common options, but there are many others to play with. Check out the Complete list of configure options for an exhaustive rundown. There are several ways to install PHP:
As an Apache module
As an fhttpd module
For use with AOLServer, NSAPI, phttpd, Pi3Web, Roxen, thttpd, or Zeus.
As a CGI executable
PHP can be compiled in a number of different ways, but one of the most popular is as an Apache module. The following is a quick installation overview.
Пример 3-4. Quick Installation Instructions for PHP 4 (Apache Module Version)
|
When PHP is configured, you are ready to build the CGI executable. The command make should take care of this. If it fails and you can't figure out why, see the Problems section.
This section applies to Windows 98/Me and Windows NT/2000/XP. PHP will not work on 16 bit platforms such as Windows 3.1 and sometimes we refer to the supported Windows platforms as Win32. Windows 95 is no longer supported as of PHP 4.3.0.
There are two main ways to install PHP for Windows: either manually or by using the InstallShield installer.
If you have Microsoft Visual Studio, you can also build PHP from the original source code.
Once you have PHP installed on your Windows system, you may also want to load various extensions for added functionality.
The Windows PHP installer is available from the downloads page at http://www.php.net/downloads.php. This installs the CGI version of PHP and, for IIS, PWS, and Xitami, configures the web server as well.
Замечание: While the InstallShield installer is an easy way to make PHP work, it is restricted in many aspects, as automatic setup of extensions for example is not supported. The whole set of supported extensions is only available by downloading the zip binary distribution.
Install your selected HTTP server on your system and make sure that it works.
Run the executable installer and follow the instructions provided by the installation wizard. Two types of installation are supported - standard, which provides sensible defaults for all the settings it can, and advanced, which asks questions as it goes along.
The installation wizard gathers enough information to set up the php.ini file and configure the web server to use PHP. For IIS and also PWS on NT Workstation, a list of all the nodes on the server with script map settings is displayed, and you can choose those nodes to which you wish to add the PHP script mappings.
Once the installation has completed the installer will inform you if you need to restart your system, restart the server, or just start using PHP.
| Внимание |
Be aware, that this setup of PHP is not secure. If you would like to have a secure PHP setup, you'd better go on the manual way, and set every option carefully. This automatically working setup gives you an instantly working PHP installation, but it is not meant to be used on online servers. |
This install guide will help you manually install and configure PHP on your Windows webserver. The original version of this guide was compiled by Bob Silva, and can be found at http://www.umesd.k12.or.us/php/win32install.html. You need to download the zip binary distribution from the downloads page at http://www.php.net/downloads.php.
PHP 4 for Windows comes in three flavours - a CGI executable (php.exe), a CLI executable (sapi/php.exe) and some other SAPI modules:
| php4apache.dll - Apache 1.3.x module |
| php4apache2.dll - Apache 2.0.x module |
| php4isapi.dll - ISAPI Module for ISAPI compliant webservers like IIS 4.0/PWS 4.0 or newer. |
| php4nsapi.dll - Netscape/iPlanet module |
| Внимание |
The SAPI modules have been significantly improved in the 4.1 release, however, you may find that you encounter possible server errors or other server modules such as ASP failing, in older systems. |
DCOM and MDAC requirements: If you choose one of the SAPI modules and use Windows 95, be sure to download and install the DCOM update from the Microsoft DCOM pages. If you use Microsoft Windows 9x/NT4 download the latest version of the Microsoft Data Access Components (MDAC) for your platform. MDAC is available at http://www.microsoft.com/data/.
The following steps should be performed on all installations before any server specific instructions.
Extract the distribution file to a directory of your choice, c:\ is a good start. The zip package expands to a foldername like php-4.3.1-Win32 which is assumed to be renamed to php. For the sake of convinience and to be version independant the following steps assume your extracted version of PHP lives in c:\php. You might choose any other location but you probably do not want to use a path in which spaces are included (for example: c:\program files\php is not a good idea). Some web servers will crash if you do. The struture of your directory you extracted the zip file will look like:
c:\php | +--cli | | | |-php.exe -- CLI executable - ONLY for commandline scripting | | +--dlls -- support dlls for extensions --> windows system directory | | | |-expat.dll | | | |-fdftk.dll | | | |-... | +--extensions -- extension dlls for PHP | | | |-php_bz2.dll | | | |-php_cpdf.dll | | | |-.. | +--mibs -- support files for SNMP | | +--openssl -- support files for Openssl | | +--pdf-related -- support files for PDF | | +--sapi -- SAPI dlls | | | |-php4apache.dll | | | |-php4apache2.dll | | | |-php4isapi.dll | | | |-.. | |-install.txt | |-.. | |-php.exe -- CGI executable | |-.. | |-php.ini-dist | |-php.ini-recommended | |-php4ts.dll -- main dll --> windows system directory | |-... |
The CGI binary - C:/php/php.exe -, the CLI binary - c:\php\cli\php.exe -, and the SAPI modules - c:\php\sapi\*.dll - rely on the main dll c:\php\php4ts.dll. You have to make sure, that this dll can be found by your PHP installation. The search order for this dll is as follows:
| The same directory from where php.exe is called. In case you use a SAPI module the same directory from where your webserver loads the dll (e.g. php4apache.dll). |
| Any directory in your Windows PATH environment variable. |
The best bet is to make php4ts.dll available, regardless which interface (CGI or SAPI module) you plan to use. To do so, you have to copy this dll to a directory on your Windows path. The best place is your windows system directory:
| c:\windows\system for Windows 9x/ME |
| c:\winnt\system32 for Windows NT/2000 or c:\winnt40\system32 for NT/2000 server |
| c:\windows\system32 for Windows XP |
The next step is to set up a valid configuration file for PHP, php.ini. There are two ini files distributed in the zip file, php.ini-dist and php.ini-recommended. We advise you to use php.ini-recommended, because we optimized the default settings in this file for performance, and security. Read this well documented file carefully and in addition study the ini settings and set every element manually yourself. If you would like to achieve the best security, then this is the way for you, although PHP works fine with these default ini files. Copy your choosen ini-file to a directory where PHP is able to find and rename it to php.ini. By default PHP searchs php.ini in your Windows directory:
| On Windows 9x/ME/XP copy your choosen ini file to your %WINDIR%, which is typically c:\windows. |
| On Windows NT/2000 copy your choosen ini file to your %WINDIR% or %SYSTEMROOT%, which is typically c:\winnt or c:\winnt40 for NT/2000 servers. |
If you're using NTFS on Windows NT, 2000 or XP, make sure that the user running the webserver has read permissions to your php.ini (e.g. make it readable by Everyone).
The following steps are optional.
Edit your new php.ini file. If you plan to use OmniHTTPd, do not follow the next step. Set the doc_root to point to your webservers document_root. For example:
Choose which extensions you would like to load when PHP starts. See the section about Windows extensions, about how to set up one, and what is already built in. Note that on a new installation it is advisable to first get PHP working and tested without any extensions before enabling them in php.ini.
On PWS and IIS, you can set the browscap configuration setting to point to: c:\windows\system\inetsrv\browscap.ini on Windows 9x/Me, c:\winnt\system32\inetsrv\browscap.ini on NT/2000, and c:\windows\system32\inetsrv\browscap.ini on XP.
Following this instructions you are done with the basic steps to setup PHP on Windows. The next step is to choose a webserver and enable it to run PHP. Installation instructions for the following webservers are available:
.. the Windows server family, Personal Web server (PWS) 3 and 4 or newer; Internet Information Server (IIS) 3 and 4 or newer.
.. the Apache servers Apache 1.3.x, and Apache 2.x.
.. the Netscape/iPlanet servers.
.. the OmniHTTPd server.
.. the Oreilly Website Pro server.
.. the Sambar server.
.. the Xitami server.
Before getting started, it is worthwhile answering the question: "Why is building on Windows so hard?" Two reasons come to mind:
Windows does not (yet) enjoy a large community of developers who are willing to freely share their source. As a direct result, the necessary investment in infrastructure required to support such development hasn't been made. By and large, what is available has been made possible by the porting of necessary utilities from Unix. Don't be surprised if some of this heritage shows through from time to time.
Pretty much all of the instructions that follow are of the "set and forget" variety. So sit back and try follow the instructions below as faithfully as you can.
To compile and build PHP you need a Microsoft Development Environment. Microsoft Visuaul C++ 6.0 is recommended. To extract the downloaded files you need a extraction utilitiy (e.g.: Winzip). If you don't already have an unzip utility, you can get a free version from InfoZip.
Before you get started, you have to download...
..the win32 buildtools from the PHP site at http://www.php.net/extra/win32build.zip.
..the source code for the DNS name resolver used by PHP from http://www.php.net/extra/bindlib_w32.zip. This is a replacement for the resolv.lib library included in win32build.zip.
If you plan to compile PHP as a Apache module you will also need the Apache sources.
Finally, you are going to need the source to PHP 4 itself. You can get the latest development version using anonymous CVS, a snapshot or the most recent released source tarball.
After downloading the required packages you have to extract them in a proper place.
Create a working directory where all files end up after extracting, e.g: c:\work.
Create the directory win32build under your working directory (c:\work) and unzip win32build.zip into it.
Create the directory bindlib_w32 under your working directory (c:\work) and unzip bindlib_w32.zip into it.
Extract the downloaded PHP source code into your working directory (c:\work).
+--c:\work | | | +--bindlib_w32 | | | | | +--arpa | | | | | +--conf | | | | | +--... | | | +--php-4.x.x | | | | | +--build | | | | | +--... | | | | | +--win32 | | | | | +--... | | | +--win32build | | | | | +--bin | | | | | +--include | | | | | +--lib |
Замечание: Cygwin users may omit the last step. A properly installed Cygwin environment provides the mandatory files bison.simple and bison.exe.
The next step is to configure MVC ++ to prepare for compiling. Launch Microsoft Visual C++, and from the menu select Tools => Options. In the dialog, select the directories tab. Sequentially change the dropdown to Executables, Includes, and Library files. Your entries should look like this:
Executable files: c:\work\win32build\bin, Cygwin users: cygwin\bin
Include files: c:\work\win32build\include
Library files: c:\work\win32build\lib
You must build the resolv.lib library. Decide whether you want to have debug symbols available (bindlib - Win32 Debug) or not (bindlib - Win32 Release). Build the appropriate configuration:
For GUI users, launch VC++, and then select File => Open Workspace, navigate to c:\work\bindlib_w32 and select bindlib.dsw. Then select Build=>Set Active Configuration and select the desired configuration. Finally select Build=>Rebuild All.
For command line users, make sure that you either have the C++ environment variables registered, or have run vcvars.bat, and then execute one of the following commands:
msdev bindlib.dsp /MAKE "bindlib - Win32 Debug"
msdev bindlib.dsp /MAKE "bindlib - Win32 Release"
The best way to get started is to build the CGI version.
For GUI users, launch VC++, and then select File => Open Workspace and select c:\work\php-4.x.x\win32\php4ts.dsw . Then select Build=>Set Active Configuration and select the desired configuration, either php4ts - Win32 Debug_TS or php4ts - Win32 Release_TS. Finally select Build=>Rebuild All.
For command line users, make sure that you either have the C++ environment variables registered, or have run vcvars.bat, and then execute one of the following commands from the c:\work\php-4.x.x\win32 directory:
msdev php4ts.dsp /MAKE "php4ts - Win32 Debug_TS"
msdev php4ts.dsp /MAKE "php4ts - Win32 Release_TS"
At this point, you should have a usable php.exe in either your c:\work\php-4.x.x.\Debug_TS or Release_TS subdirectories.
It is possible to do minor customization to the build process by editing the main/config.win32.h file. For example you can change the builtin extensions, the location of php.ini and
Next you may want to build the CLI version which is designed to use PHP from the command line. The steps are the same as for building the CGI version, except you have to select the php4ts_cli - Win32 Debug_TS or php4ts_cli - Win32 Release_TS project file. After a succcessfull compiling run you will find the php.exe in either the directory Release_TS\cli\ or Debug_TS\cli\.
Замечание: If you want to use PEAR and the comfortable command line installer, the CLI-SAPI is mandatory. For more information about PEAR and the installer read the documantation at the PEAR website.
In order to build the SAPI module (php4isapi.dll) for integrating PHP with Microsoft IIS, set your active configuration to php4isapi-whatever-config and build the desired dll.
After installing PHP and a webserver on Windows, you will probably want to install some extensions for added functionality. You can choose which extensions you would like to load when PHP starts by modifying your php.ini. You can also load a module dynamically in your script using dl().
The DLLs for PHP extensions are prefixed with 'php_' in PHP 4 (and 'php3_' in PHP 3). This prevents confusion between PHP extensions and their supporting libraries.
Замечание: In PHP 4.3.1 BCMath, Calendar, COM, Ctype, FTP, MySQL, ODBC, Overload, PCRE, Session, Tokenizer, WDDX, XML and Zlib support is built in. You don't need to load any additional extensions in order to use these functions. See your distributions README.txt or install.txt or this table for a list of built in modules.
Edit your php.ini file:
You will need to change the extension_dir setting to point to the directory where your extensions lives, or where you have placed your php_*.dll files. Please do not forget the last backslash. For example:
Enable the extension(s) in php.ini you want to use by uncommenting the 'extension=php_*.dll' lines in php.ini. This is done by deleting the leading ; form the extension you want to load.
Пример 3-5. enable Bzip2 extension
|
Some of the extensions need extra DLLs to work. Couple of them can be found in the distribution package, in the c:\php\dlls\ folder but some, for example Oracle (php_oci8.dll) require DLLs which are not bundled with the distribution package. Copy the bundled DLLs from c:\php\dlls folder to your Windows PATH, safe places are:
| c:\windows\system for Windows 9x/Me |
| c:\winnt\system32 for Windows NT/2000 |
| c:\windows\system32 for Windows XP |
The following table describes some of the extensions available and required additional dlls.
Таблица 3-1. PHP Extensions
| Extension | Description | Notes |
|---|---|---|
| php_bz2.dll | bzip2 compression functions | None |
| php_calendar.dll | Calendar conversion functions | Built in since PHP 4.0.3 |
| php_cpdf.dll | ClibPDF functions | None |
| php_crack.dll | Crack functions | None |
| php3_crypt.dll | Crypt functions | unknown |
| php_ctype.dll | ctype family functions | Built in since PHP 4.3.0 |
| php_curl.dll | CURL, Client URL library functions | Requires: libeay32.dll, ssleay32.dll (bundled) |
| php_cybercash.dll | Cybercash payment functions | PHP <= 4.2.0 |
| php_db.dll | DBM functions | Deprecated. Use DBA instead (php_dba.dll) |
| php_dba.dll | DBA: DataBase (dbm-style) Abstraction layer functions | None |
| php_dbase.dll | dBase functions | None |
| php3_dbm.dll | Berkeley DB2 library | unknown |
| php_dbx.dll | dbx functions | |
| php_domxml.dll | DOM XML functions | PHP <= 4.2.0 requires: libxml2.dll (bundled) |
| php_dotnet.dll | .NET functions | PHP <= 4.1.1 |
| php_exif.dll | Read EXIF headers from JPEG | None |
| php_fbsql.dll | FrontBase functions | PHP <= 4.2.0 |
| php_fdf.dll | FDF: Forms Data Format functions. | Requires: fdftk.dll (bundled) |
| php_filepro.dll | filePro functions | Read-only access |
| php_ftp.dll | FTP functions | Built-in since PHP 4.0.3 |
| php_gd.dll | GD library image functions | None |
| php_gd2.dll | GD2 library image functions | None |
| php_gettext.dll | Gettext functions | PHP <= 4.2.0 requires: gnu_gettext.dll (bundled), PHP >= 4.2.3 requires libintl-1.dll (bundled). |
| php_hyperwave.dll | HyperWave functions | None |
| php_iconv.dll | ICONV characterset conversion | Requires: iconv-1.3.dll (bundled), PHP >=4.2.1 iconv.dll |
| php_ifx.dll | Informix functions | Requires: Informix libraries |
| php_iisfunc.dll | IIS management functions | None |
| php_imap.dll | IMAP POP3 and NNTP functions | PHP 3: php3_imap4r1.dll |
| php_ingres.dll | Ingres II functions | Requires: Ingres II libraries |
| php_interbase.dll | InterBase functions | Requires: gds32.dll (bundled) |
| php_java.dll | Java functions | PHP <= 4.0.6 requires: jvm.dll (bundled) |
| php_ldap.dll | LDAP functions | PHP <= 4.2.0 requires: libsasl.dll (bundled), PHP >= 4.3.0 requires: libeay32.dll, ssleay32.dll (bundled) |
| php_mbstring.dll | Multi-Byte String functions | None |
| php_mcrypt.dll | Mcrypt Encryption functions | Requires: libmcrypt.dll |
| php_mhash.dll | Mhash functions | PHP >= 4.3.0 requires: libmhash.dll (bundled) |
| php_mime_magic.dll | Mimetype functions | Requires: magic.mime (bundled) |
| php_ming.dll | Ming functions for Flash | None |
| php_msql.dll | mSQL functions | Requires: msql.dll (bundled) |
| php3_msql1.dll | mSQL 1 client | unknown |
| php3_msql2.dll | mSQL 2 client | unknown |
| php_mssql.dll | MSSQL functions | Requires: ntwdblib.dll (bundled) |
| php3_mysql.dll | MySQL functions | Built-in in PHP 4 |
| php3_nsmail.dll | Netscape mail functions | unknown |
| php3_oci73.dll | Oracle functions | unknown |
| php_oci8.dll | Oracle 8 functions | Requires: Oracle 8 client libraries |
| php_openssl.dll | OpenSSL functions | Requires: libeay32.dll (bundled) |
| php_oracle.dll | Oracle functions | Requires: Oracle 7 client libraries |
| php_overload.dll | Object overloading functions | Built in since PHP 4.3.0 |
| php_pdf.dll | PDF functions | None |
| php_pgsql.dll | PostgreSQL functions | None |
| php_printer.dll | Printer functions | None |
| php_shmop.dll | Shared Memory functions | None |
| php_snmp.dll | SNMP get and walk functions | NT only! |
| php_sockets.dll | Socket functions | None |
| php_sybase_ct.dll | Sybase functions | Requires: Sybase client libraries |
| php_tokenizer.dll | Tokenizer functions | Built in since PHP 4.3.0 |
| php_w32api.dll | W32api functions | none |
| php_xmlrpc.dll | XML-RPC functions | PHP >= 4.2.1 requires: iconv.dll (bundled) |
| php_xslt.dll | XSLT functions | Requires: sablot.dll, expat.dll (bundled) |
| php_yaz.dll | YAZ functions | Requires: yaz.dll (bundled) |
| php_zib.dll | Zip File functions | Read only access |
| php_zlib.dll | ZLib compression functions | Built in since PHP 4.3.0 |
The default is to build PHP as a CGI program. This creates a commandline interpreter, which can be used for CGI processing, or for non-web-related PHP scripting. If you are running a web server PHP has module support for, you should generally go for that solution for performance reasons. However, the CGI version enables Apache users to run different PHP-enabled pages under different user-ids. Please make sure you read through the Security chapter if you are going to run PHP as a CGI.
As of PHP 4.3.0, some important additions have happened to PHP. A new SAPI named CLI also exists and it has the same name as the CGI binary. What is installed at {PREFIX}/bin/php depends on your configure line and this is described in detail in the manual section named Using PHP from the command line. For further details please read that section of the manual.
If you have built PHP as a CGI program, you may test your build by typing make test. It is always a good idea to test your build. This way you may catch a problem with PHP on your platform early instead of having to struggle with it later.
If you have built PHP 3 as a CGI program, you may benchmark your build by typing make bench. Note that if safe mode is on by default, the benchmark may not be able to finish if it takes longer then the 30 seconds allowed. This is because the set_time_limit() can not be used in safe mode. Use the max_execution_time configuration setting to control this time for your own scripts. make bench ignores the configuration file.
Замечание: make bench is only available for PHP 3.
Some server supplied enviroment variables are not defined in the current CGI/1.1 specification. Only the following variables are defined there; everything else should be treated as 'vendor extensions': AUTH_TYPE, CONTENT_LENGTH, CONTENT_TYPE, GATEWAY_INTERFACE, PATH_INFO, PATH_TRANSLATED, QUERY_STRING, REMOTE_ADDR, REMOTE_HOST, REMOTE_IDENT, REMOTE_USER, REQUEST_METHOD, SCRIPT_NAME, SERVER_NAME, SERVER_PORT, SERVER_PROTOCOL and SERVER_SOFTWARE
This section contains notes and hints specific to Apache installs of PHP, both for Unix and Windows versions. We also have instructions and notes for Apache 2 on a separate page.
You can select arguments to add to the configure on line 10 below from the Complete list of configure options. The version numbers have been omitted here, to ensure the instructions are not incorrect. You will need to replace the 'xxx' here with the correct values from your files.
Пример 3-6. Installation Instructions (Apache Shared Module Version) for PHP 4
|
Depending on your Apache install and Unix variant, there are many possible ways to stop and restart the server. Below are some typical lines used in restarting the server, for different apache/unix installations. You should replace /path/to/ with the path to these applications on your systems.
1. Several Linux and SysV variants: /etc/rc.d/init.d/httpd restart 2. Using apachectl scripts: /path/to/apachectl stop /path/to/apachectl start 3. httpdctl and httpsdctl (Using OpenSSL), similar to apachectl: /path/to/httpsdctl stop /path/to/httpsdctl start 4. Using mod_ssl, or another SSL server, you may want to manually stop and start: /path/to/apachectl stop /path/to/apachectl startssl |
Different examples of compiling PHP for apache are as follows:
This will create a libphp4.so shared library that is loaded into Apache using a LoadModule line in Apache's httpd.conf file. The PostgreSQL support is embedded into this libphp4.so library.
This will create a libphp4.so shared library for Apache, but it will also create a pgsql.so shared library that is loaded into PHP either by using the extension directive in php.ini file or by loading it explicitly in a script using the dl() function.
This will create a libmodphp4.a library, a mod_php4.c and some accompanying files and copy this into the src/modules/php4 directory in the Apache source tree. Then you compile Apache using --activate-module=src/modules/php4/libphp4.a and the Apache build system will create libphp4.a and link it statically into the httpd binary. The PostgreSQL support is included directly into this httpd binary, so the final result here is a single httpd binary that includes all of Apache and all of PHP.
Same as before, except instead of including PostgreSQL support directly into the final httpd you will get a pgsql.so shared library that you can load into PHP from either the php.ini file or directly using dl().
When choosing to build PHP in different ways, you should consider the advantages and drawbacks of each method. Building as a shared object will mean that you can compile apache separately, and don't have to recompile everything as you add to, or change, PHP. Building PHP into apache (static method) means that PHP will load and run faster. For more information, see the Apache webpage on DSO support.
Замечание: Apache's default httpd.conf currently ships with a section that looks like this:
Unless you change that to "Group nogroup" or something like that ("Group daemon" is also very common) PHP will not be able to open files.
Замечание: Make sure you specify the installed version of apxs when using --with-apxs=/path/to/apxs. You must NOT use the apxs version that is in the apache sources but the one that is actually installed on your system.
There are two ways to set up PHP to work with Apache 1.3.x on Windows. One is to use the CGI binary (php.exe), the other is to use the Apache module DLL. In either case you need to stop the Apache server, and edit your httpd.conf to configure Apache to work with PHP.
It is worth noting here that now the SAPI module has been made more stable under windows, we recommend it's use above the CGI binary, since it is more transparent and secure.
Although there can be a few variations of configuring PHP under Apache, these are simple enough to be used by the newcomer. Please consult the Apache Docs for further configuration directives.
If you unziped the PHP package to c:\php\ as described in the Manual Installation Steps section, you need to insert these lines to your Apache configuration file to set up the CGI binary:
ScriptAlias /php/ "c:/php/"
AddType application/x-httpd-php .php .phtml
Action application/x-httpd-php "/php/php.exe"
| Внимание |
By using the CGI setup, your server is open to several possible attacks. Please read our CGI security section to learn how to defend yourself from attacks. |
If you would like to use PHP as a module in Apache, be sure to copy php4ts.dll to the windows/system (for Windows 9x/Me), winnt/system32 (for Windows NT/2000) or windows/system32 (for Windows XP) directory, overwriting any older file. Then you should add the following lines to your Apache httpd.conf file:
Open httpd.conf with your favorite editor and locate the LoadModule directive and add the following line at the end of the list: LoadModule php4_module c:/php/sapi/php4apache.dll
You may find after using the windows installer for Apache that you need to define the AddModule directive for mod_php4.c. This is especially important if the ClearModuleList directive is defined, which you will find by scrolling down a few lines. You will see a list of AddModule entries, add the following line at the end of the list: AddModule mod_php4.c
Search for a phrase similar to # AddType allows you to tweak mime.types. You will see some AddType entries, add the following line at the end of the list: AddType application/x-httpd-php .php. You can choose any extension you want to parse through PHP here. .php is simply the one we suggest. You can even include .html, and .php3 can be added for backwards compatibility.
After changing the configuration file, remember to restart the server, for example, NET STOP APACHE followed by NET START APACHE, if you run Apache as a Windows Service, or use your regular shortcuts.
There are two ways you can use the source code highlighting feature, however their ability to work depends on your installation. If you have configured Apache to use PHP as an SAPI module, then by adding the following line to your httpd.conf (at the same place you inserted AddType application/x-httpd-php .php, see above) you can use this feature: AddType application/x-httpd-php-source .phps.
If you chose to configure Apache to use PHP as a CGI binary, you will need to use the show_source() function. To do this simply create a PHP script file and add this code: <?php show_source ("original_php_script.php"); ?>. Substitute original_php_script.php with the name of the file you wish to show the source of.
Замечание: On Win-Apache all backslashes in a path statement such as "c:\directory\file.ext", must be converted to forward slashes, as "c:/directory/file.ext".
This section contains notes and hints specific to Apache 2.0 installs of PHP, both for Unix and Windows versions.
| Внимание |
Do not use Apache 2.0 and PHP in a production environment neither on Unix nor on Windows. |
You are highly encouraged to take a look at the Apache Documentation to get a basic understanding of the Apache 2.0 Server.
The following versions of PHP are known to work with the most recent version of Apache 2.0:
Замечание: Apache 2.0 SAPI-support started with PHP 4.2.0. PHP 4.2.3 works with Apache 2.0.39, don't use any other version of Apache with PHP 4.2.3. However, the recommended setup is to use PHP 4.3.0 or later with the most recent version of Apache2.
All mentioned versions of PHP will work still with Apache 1.3.x.
Download the most recent version of Apache 2.0 and a fitting PHP version from the above mentioned places. This quick guide covers only the basics to get started with Apache 2.0 and PHP. For more information read the Apache Documentation. The version numbers have been omitted here, to ensure the instructions are not incorrect. You will need to replace the 'NN' here with the correct values from your files.
Пример 3-7. Installation Instructions (Apache 2 Shared Module Version)
|
Following the steps above you will have a running Apache 2.0 with support for PHP as SAPI module. Of course there are many more configuration options available for both, Apache and PHP. For more information use ./configure --help in the corresponding source tree. In case you wish to build a multithreaded version of Apache 2.0 you must overwrite the standard MPM-Module prefork either with worker or perchild. To do so append to your configure line in step 6 above either the option --with-mpm=worker or --with-mpm=perchild. Take care about the consequences and understand what you are doing. For more information read the Apache documentation about the MPM-Modules.
Замечание: To build a multithreaded version of Apache your system must support threads. This also implies to build PHP with experimental Zend Thread Safety (ZTS). Therefore not all extensions might be available. The recommended setup is to build Apache with the standard prefork MPM-Module.
Consider to read the Windows specific notes for Apache 2.0.
| Внимание |
Apache 2.0 is designed to run on Windows NT 4.0, Windows 2000 or Windows XP. At this time, support for Windows 9x is incomplete. Apache 2.0 is not expected to work on those platforms at this time. |
Download the most recent version of Apache 2.0 and a fitting PHP version from the above mentioned places. Follow the Manual Installation Steps and come back to go on with the integration of PHP and Apache.
There are two ways to set up PHP to work with Apache 2.0 on Windows. One is to use the CGI binary the other is to use the Apache module DLL. In either case you need to stop the Apache server, and edit your httpd.conf to configure Apache to work with PHP.
You need to insert these three lines to your Apache httpd.conf configuration file to set up the CGI binary:
If you would like to use PHP as a module in Apache 2.0, be sure to move php4ts.dll to winnt/system32 (for Windows NT/2000) or windows/system32 (for Windows XP), overwriting any older file. You need to insert these two lines to your Apache httpd.conf configuration file to set up the PHP-Module for Apache 2.0:
Замечание: Remember to substitute the c:/php/ for your actual path to PHP in the above examples. Take care to use php4apache2.dll in your LoadModule directive and notphp4apche.dll. The latter one is designd to run with Apache 1.3.x.
| Внимание |
Don't mix up your installation with dll files from different PHP versions . You have the only choice to use the dll's and extensions that ship with your downloaded PHP version. |
PHP 4 can be built as a Pike module for the Caudium webserver. Note that this is not supported with PHP 3. Follow the simple instructions below to install PHP 4 for Caudium.
Пример 3-10. Caudium Installation Instructions
|
You can of course compile your Caudium module with support for the various extensions available in PHP 4. See the complete list of configure options for an exhaustive rundown.
Замечание: When compiling PHP 4 with MySQL support you must make sure that the normal MySQL client code is used. Otherwise there might be conflicts if your Pike already has MySQL support. You do this by specifying a MySQL install directory the --with-mysql option.
To build PHP as an fhttpd module, answer "yes" to "Build as an fhttpd module?" (the --with-fhttpd=DIR option to configure) and specify the fhttpd source base directory. The default directory is /usr/local/src/fhttpd. If you are running fhttpd, building PHP as a module will give better performance, more control and remote execution capability.
This section contains notes and hints specific to IIS (Microsoft Internet Information Server). Installing PHP for PWS/IIS 3, PWS 4 or newer and IIS 4 or newer versions.
Important for CGI users: Read the faq on cgi.force_redirect for important details. This directive needs to be set to 0.
The recommended method for configuring these servers is to use the REG file included with the distribution (pws-php4cgi.reg). You may want to edit this file and make sure the extensions and PHP install directories match your configuration. Or you can follow the steps below to do it manually.
| Внимание |
These steps involve working directly with the Windows registry. One error here can leave your system in an unstable state. We highly recommend that you back up your registry first. The PHP Development team will not be held responsible if you damage your registry. |
Run Regedit.
Navigate to: HKEY_LOCAL_MACHINE /System /CurrentControlSet /Services /W3Svc /Parameters /ScriptMap.
On the edit menu select: New->String Value.
Type in the extension you wish to use for your php scripts. For example .php
Double click on the new string value and enter the path to php.exe in the value data field. ex: c:\php\php.exe.
Repeat these steps for each extension you wish to associate with PHP scripts.
The following steps do not affect the web server installation and only apply if you want your php scripts to be executed when they are run from the command line (ex. run c:\myscripts\test.php) or by double clicking on them in a directory viewer window. You may wish to skip these steps as you might prefer the PHP files to load into a text editor when you double click on them.
Navigate to: HKEY_CLASSES_ROOT
On the edit menu select: New->Key.
Name the key to the extension you setup in the previous section. ex: .php
Highlight the new key and in the right side pane, double click the "default value" and enter phpfile.
Repeat the last step for each extension you set up in the previous section.
Now create another New->Key under HKEY_CLASSES_ROOT and name it phpfile.
Highlight the new key phpfile and in the right side pane, double click the "default value" and enter PHP Script.
Right click on the phpfile key and select New->Key, name it Shell.
Right click on the Shell key and select New->Key, name it open.
Right click on the open key and select New->Key, name it command.
Highlight the new key command and in the right side pane, double click the "default value" and enter the path to php.exe. ex: c:\php\php.exe -q %1. (don't forget the %1).
Exit Regedit.
If using PWS on Windows, reboot to reload the registry.
PWS and IIS 3 users now have a fully operational system. IIS 3 users can use a nifty tool from Steven Genusa to configure their script maps.
When installing PHP on Windows with PWS 4 or newer version, you have two options. One to set up the PHP CGI binary, the other is to use the ISAPI module DLL.
If you choose the CGI binary, do the following:
Edit the enclosed pws-php4cgi.reg file (look into the SAPI dir) to reflect the location of your php.exe. Backslashes should be escaped, for example: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w3svc\parameters\Script Map] ".php"="c:\\php\\php.exe" Now merge this registery file into your system; you may do this by double-clicking it.
In the PWS Manager, right click on a given directory you want to add PHP support to, and select Properties. Check the 'Execute' checkbox, and confirm.
If you choose the ISAPI module, do the following:
Edit the enclosed pws-php4isapi.reg file (look into the SAPI dir) to reflect the location of your php4isapi.dll. Backslashes should be escaped, for example: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w3svc\parameters\Script Map] ".php"="c:\\php\\sapi\\php4isapi.dll" Now merge this registery file into your system; you may do this by double-clicking it.
In the PWS Manager, right click on a given directory you want to add PHP support to, and select Properties. Check the 'Execute' checkbox, and confirm.
To install PHP on an NT/2000/XP Server running IIS 4 or newer, follow these instructions. You have two options to set up PHP, using the CGI binary (php.exe) or with the ISAPI module.
In either case, you need to start the Microsoft Management Console (may appear as 'Internet Services Manager', either in your Windows NT 4.0 Option Pack branch or the Control Panel=>Administrative Tools under Windows 2000/XP). Then right click on your Web server node (this will most probably appear as 'Default Web Server'), and select 'Properties'.
If you want to use the CGI binary, do the following:
Under 'Home Directory', 'Virtual Directory', or 'Directory', click on the 'Configuration' button, and then enter the App Mappings tab.
Click Add, and in the Executable box, type: c:\php\php.exe (assuming that you have unziped PHP in c:\php\).
In the Extension box, type the file name extension you want associated with PHP scripts. Leave 'Method exclusions' blank, and check the Script engine checkbox. You may also like to check the 'check that file exists' box - for a small performance penalty, IIS (or PWS) will check that the script file exists and sort out authentication before firing up php. This means that you will get sensible 404 style error messages instead of cgi errors complaining that php did not output any data.
You must start over from the previous step for each extension you want associated with PHP scripts. .php and .phtml are common, although .php3 may be required for legacy applications.
Set up the appropriate security. (This is done in Internet Service Manager), and if your NT Server uses NTFS file system, add execute rights for I_USR_ to the directory that contains php.exe.
To use the ISAPI module, do the following:
If you don't want to perform HTTP Authentication using PHP, you can (and should) skip this step. Under ISAPI Filters, add a new ISAPI filter. Use PHP as the filter name, and supply a path to the php4isapi.dll.
Under 'Home Directory', click on the 'Configuration' button. Add a new entry to the Application Mappings. Use the path to the php4isapi.dll as the Executable, supply .php as the extension, leave Method exclusions blank, and check the Script engine checkbox.
Stop IIS completely (NET STOP iisadmin)
Start IIS again (NET START w3svc)
This section contains notes and hints specific to Netscape and iPlanet installs of PHP, both for Sun Solaris and Windows versions.
You can find more information about setting up PHP for the Netscape Enterprise Server here: http://benoit.noss.free.fr/php/install-php4.html
To build PHP with NES or iPlanet web servers, enter the proper install directory for the --with-nsapi = DIR option. The default directory is usually /opt/netscape/suitespot/. Please also read /php-xxx-version/sapi/nsapi/nsapi-readme.txt.
Пример 3-11. Installation Example for Netscape Enterprise on Solaris
|
Firstly you may need to add some paths to the LD_LIBRARY_PATH environment for Netscape to find all the shared libs. This can best done in the start script for your Netscape server. Windows users can probably skip this step. The start script is often located in: /path/to/server/https-servername/start
You may also need to edit the configuration files that are located in:/path/to/server/https-servername/config/.
Пример 3-12. Configuration Example for Netscape Enterprise
|
If you are running Netscape Enterprise 4.x, then you should use the following:
Пример 3-13. Configuration Example for Netscape Enterprise 4.x
|
To Install PHP as CGI (for Netscape Enterprise Server, iPlanet, perhaps Fastrack), do the following:
Copy php4ts.dll to your systemroot (the directory where you installed windows)
Make a file association from the command line. Type the following two lines:
assoc .php=PHPScript ftype PHPScript=c:\php\php.exe %1 %* |
In the Netscape Enterprise Administration Server create a dummy shellcgi directory and remove it just after (this step creates 5 important lines in obj.conf and allow the web server to handle shellcgi scripts).
In the Netscape Enterprise Administration Server create a new mime type (Category: type, Content-Type: magnus-internal/shellcgi, File Suffix:php).
Do it for each web server instance you want php to run
More details about setting up PHP as a CGI executable can be found here: http://benoit.noss.free.fr/php/install-php.html
To Install PHP as NSAPI (for Netscape Enterprise Server, iPlanet, perhaps Fastrack, do the following:
Copy php4ts.dll to your systemroot (the directory where you installed windows)
Make a file association from the command line. Type the following two lines:
assoc .php=PHPScript ftype PHPScript=c:\php\php.exe %1 %* |
In the Netscape Enterprise Administration Server create a new mime type (Category: type, Content-Type: magnus-internal/x-httpd-php, File Suffix:php).
Stop your web service and edit obj.conf. At the end of the Init section, place these two lines (necessarily after mime type init!):
Init fn="load-modules" funcs="php4_init,php4_close,php4_execute,php4_auth_trans" shlib="c:/php/sapi/php4nsapi.dll" Init fn="php4_init" errorString="Failed to initialise PHP!" |
In The < Object name="default" > section, place this line necessarily after all 'ObjectType' and before all 'AddLog' lines:
Service fn="php4_execute" type="magnus-internal/x-httpd-php" |
At the end of the file, create a new object called x-httpd-php, by inserting these lines:
<Object name="x-httpd-php"> ObjectType fn="force-type" type="magnus-internal/x-httpd-php" Service fn=php4_execute </Object> |
Restart your web service and apply changes
Do it for each web server instance you want PHP to run
More details about setting up PHP as an NSAPI filter can be found here: http://benoit.noss.free.fr/php/install-php4.html
This section contains notes and hints specific to OmniHTTPd.
You need to complete the following steps to make PHP work with OmniHTTPd. This is a CGI executable setup. SAPI is supported by OmniHTTPd, but some tests have shown that it is not so stable to use PHP as an ISAPI module.
Important for CGI users: Read the faq on cgi.force_redirect for important details. This directive needs to be set to 0.
Step 1: Install OmniHTTPd server.
Step 2: Right click on the blue OmniHTTPd icon in the system tray and select Properties
Step 3: Click on Web Server Global Settings
Step 4: On the 'External' tab, enter: virtual = .php | actual = c:\path-to-php-dir\php.exe, and use the Add button.
Step 5: On the Mime tab, enter: virtual = wwwserver/stdcgi | actual = .php, and use the Add button.
Step 6: Click OK
Repeat steps 2 - 6 for each extension you want to associate with PHP.
Замечание: Some OmniHTTPd packages come with built in PHP support. You can choose at setup time to do a custom setup, and uncheck the PHP component. We recommend you to use the latest PHP binaries. Some OmniHTTPd servers come with PHP 4 beta distributions, so you should choose not to set up the built in support, but install your own. If the server is already on your machine, use the Replace button in Step 4 and 5 to set the new, correct information.
This section contains notes and hints specific to Oreilly Website Pro.
This list describes how to set up the PHP CGI binary or the ISAPI module to work with Oreilly Website Pro on Windows.
Edit the Server Properties and select the tab "Mapping".
From the List select "Associations" and enter the desired extension (.php) and the path to the CGI exe (ex. c:\php\php.exe) or the ISAPI DLL file (ex. c:\php\sapi\php4isapi.dll).
Select "Content Types" add the same extension (.php) and enter the content type. If you choose the CGI executable file, enter 'wwwserver/shellcgi', if you choose the ISAPI module, enter 'wwwserver/isapi' (both without quotes).
This section contains notes and hints specific to the Sambar server for Windows.
This list describes how to set up the ISAPI module to work with the Sambar server on Windows.
Find the file called mappings.ini (in the config directory) in the Sambar isntall directory.
Open mappings.ini and add the following line under [ISAPI]:
(This line assumes that PHP was installed in c:\php.)Now restart the Sambar server for the changes to take effect.
This section contains notes and hints specific to Xitami.
This list describes how to set up the PHP CGI binary to work with Xitami on Windows.
Important for CGI users: Read the faq on cgi.force_redirect for important details. This directive needs to be set to 0.
Make sure the webserver is running, and point your browser to xitamis admin console (usually http://127.0.0.1/admin), and click on Configuration.
Navigate to the Filters, and put the extension which PHP should parse (i.e. .php) into the field File extensions (.xxx).
In Filter command or script put the path and name of your php executable i.e. c:\php\php.exe.
Press the 'Save' icon.
Restart the server to reflect changes.
PHP can be built to support a large number of web servers. Please see Server-related options for a full list of server-related configure options. The PHP CGI binaries are compatible with almost all webservers supporting the CGI standard.
Some problems are more common than others. The most common ones are listed in the PHP FAQ, part of this manual.
If you are still stuck, someone on the PHP installation mailing list may be able to help you. You should check out the archive first, in case someone already answered someone else who had the same problem as you. The archives are available from the support page on http://www.php.net/. To subscribe to the PHP installation mailing list, send an empty mail to php-install-subscribe@lists.php.net. The mailing list address is php-install@lists.php.net.
If you want to get help on the mailing list, please try to be precise and give the necessary details about your environment (which operating system, what PHP version, what web server, if you are running PHP as CGI or a server module, safe mode, etc...), and preferably enough code to make others able to reproduce and test your problem.
If you think you have found a bug in PHP, please report it. The PHP developers probably don't know about it, and unless you report it, chances are it won't be fixed. You can report bugs using the bug-tracking system at http://bugs.php.net/. Please do not send bug reports in mailing list or personal letters. The bug system is also suitable to submit feature requests.
Read the How to report a bug document before submitting any bug reports!
Замечание: These are only used at compile time. If you want to alter PHP's runtime configuration, please see the chapter on Configuration.
The following is a complete list of options supported by PHP 4 configure scripts (as of 4.1.0), used when compiling in Unix-like environments. Some are available in PHP 3, some in PHP 4, and some in both. This is not noted yet.
There are general configuration options for the configure script, consult the appropriate manual pages for GNU autoconf or use the command configure --help for a full, up-to-date list.
Замечание: These options are only used in PHP 4 as of PHP 4.1.0. Some are available in older versions of PHP 4, some even in PHP 3, some only in PHP 4.1.0. If you want to compile an older version, some options will probably not be available.
Include dbplus support.
Include Adabas D support. DIR is the Adabas base install directory, defaults to /usr/local.
Include SAP DB support. DIR is SAP DB base install directory, defaults to /usr/local.
Include Solid support. DIR is the Solid base install directory, defaults to /usr/local/solid.
Include IBM DB2 support. DIR is the DB2 base install directory, defaults to /home/db2inst1/sqllib.
Include Empress support. DIR is the Empress base install directory, defaults to $EMPRESSPATH. From PHP4, this option only supports Empress Version 8.60 and above.
Include Empress Local Access support. DIR is the Empress base install directory, defaults to $EMPRESSPATH. From PHP4, this option only supports Empress Version 8.60 and above.
Include Birdstep support. DIR is the Birdstep base install directory, defaults to /usr/local/birdstep.
Include a user defined ODBC support. The DIR is ODBC install base directory, which defaults to /usr/local. Make sure to define CUSTOM_ODBC_LIBS and have some odbc.h in your include dirs. E.g., you should define following for Sybase SQL Anywhere 5.5.00 on QNX, prior to run configure script: CPPFLAGS="-DODBC_QNX -DSQLANY_BUG" LDFLAGS=-lunix CUSTOM_ODBC_LIBS="-ldblib -lodbc".
Include iODBC support. DIR is the iODBC base install directory, defaults to /usr/local.
Include Easysoft OOB support. DIR is the OOB base install directory, defaults to /usr/local/easysoft/oob/client.
Include unixODBC support. DIR is the unixODBC base install directory, defaults to /usr/local.
Include OpenLink ODBC support. DIR is the OpenLink base install directory, defaults to /usr/local. This is the same as iODBC.
Include DBMaker support. DIR is the DBMaker base install directory, defaults to where the latest version of DBMaker is installed (such as /home/dbmaker/3.6).
Disable unified ODBC support. Only applicable if iODBC, Adabas, Solid, Velocis or a custom ODBC interface is enabled. PHP 3 only!
Disable GD support. PHP 3 only!
The imagick extension has been moved to PECL in PEAR and can be found here. Install instructions for PHP 4 can be found on the PEAR site.
Simply doing --with-imagick is only supported in PHP 3 unless you follow the instructions found on the PEAR site.
Include ming support.
Enable the security check for internal server redirects. You should use this if you are running the CGI version with Apache.
If this is enabled, the PHP CGI binary can safely be placed outside of the web tree and people will not be able to circumvent .htaccess security.
Build PHP as FastCGI application.
Compile with debugging symbols.
Sets how installed files will be laid out. Type is one of PHP (default) or GNU.
Install PEAR in DIR (default PREFIX/lib/php).
Do not install PEAR.
Enable PHP's own SIGCHLD handler.
Disable passing additional runtime library search paths.
Enable explicitly linking against libgcc.
Include experimental php streams. Do not use unless you are testing the code!
Define the location of zlib install directory.
Include ASPELL support.
Include CCVS support.
Include CyberCash support. DIR is the CyberCash MCK install directory.
Include ICAP support.
Path to the ircg-config script.
Include ircg support.
Enable mailparse support.
Include muscat support.
Enable CORBA support via Satellite (EXPERIMENTAL) DIR is the base directory for ORBit.
Enable transparent session id propagation.
Use system regex library (deprecated).
Include vpopmail support.
Use POSIX threads (default).
Build shared libraries [default=yes].
Build static libraries [default=yes].
Optimize for fast installation [default=yes].
Assume the C compiler uses GNU ld [default=no].
Avoid locking (might break parallel builds).
Try to use only PIC/non-PIC objects [default=use both].
Compile with memory limit support.
Disable the URL-aware fopen wrapper that allows accessing files via HTTP or FTP.
Export only required symbols. See INSTALL for more information.
Include IMSp support (DIR is IMSP's include dir and libimsp.a dir). PHP 3 only!
Include Cybercash MCK support. DIR is the cybercash mck build directory, defaults to /usr/src/mck-3.2.0.3-linux for help look in extra/cyberlib. PHP 3 only!
Include DAV support through Apache's mod_dav, DIR is mod_dav's installation directory (Apache module version only!) PHP 3 only!
Compile with remote debugging functions. PHP 3 only!
Take advantage of versioning and scoping provided by Solaris 2.x and Linux. PHP 3 only!
Enable make rules and dependencies not useful (and sometimes confusing) to the casual installer.
Sets the path in which to look for php.ini, defaults to PREFIX/lib.
Enable safe mode by default.
Only allow executables in DIR when in safe mode defaults to /usr/local/php/bin.
Enable magic quotes by default.
Disable the short-form <? start tag by default.
Specify path to the installed AOLserver.
Build shared Apache module. FILE is the optional pathname to the Apache apxs tool; defaults to apxs. Make sure you specify the version of apxs that is actually installed on your system and NOT the one that is in the apache source tarball.
Build Apache module. DIR is the top-level Apache build directory, defaults to /usr/local/apache.
Enable transfer tables for mod_charset (Rus Apache).
Build shared Apache 2.0 module. FILE is the optional pathname to the Apache apxs tool; defaults to apxs.
Build fhttpd module. DIR is the fhttpd sources directory, defaults to /usr/local/src/fhttpd.
Build PHP as an ISAPI module for use with Zeus.
Specify path to the installed Netscape Server.
No information yet.
Build PHP as a module for use with Pi3Web.
Build PHP as a Pike module. DIR is the base Roxen directory, normally /usr/local/roxen/server.
Build the Roxen module using Zend Thread Safety.
Include servlet support. DIR is the base install directory for the JSDK. This SAPI prereqs the java extension must be built as a shared dl.
Build PHP as thttpd module.
Build PHP as a TUX module (Linux only).
Файл конфигурации (называющийся php3.ini в PHP 3.0, и просто php.ini в PHP 4.0) читается каждый раз при запуске PHP. При использовании PHP в виде модуля для Web-сервера, это происходит лишь один раз при запуске сервера. Для версий CGI и CLI, это происходи при каждом пуске.
Расположение php.ini задается при компиляции (смотрите FAQ), но для версий CGI и CLI может быть изменено из командной строки опцией -c (см. раздел про использование PHP из командной строки. Также можно использовать переменную окружения PHPRC для задания дополнительных путей поиска файла php.ini.
Здесь не описывается каждая директива PHP в отдельности. Для полного списка всех директив смотрите хорошо документированный файл php.ini. Можно посмотреть php.ini последней версии в CVS.
Замечание: Значение по умолчанию для директив register_globals изменилось с on на off в PHP 4.2.0.
Пример 4-1. Пример php.ini
|
При использовании модуля Apache можно изменить настройки с помощью директив файлов конфигурации Apache httpd.conf) и .htaccess (для этого понадобятся привилегии "AllowOverride Options" или "AllowOverride All").
В PHP 3.0 были директивы Apache, связанные с соответствующими директивами php3.ini, с единственным различием в том, что у них был префикс "php3_".
В PHP 4.0 есть несколько директив Apache, которые позволяют вам менять конфигурацию PHP из файлов конфигурации Apache.
Устанавливает значение указанной директивы. Может быть использована только для директив типа PHP_INI_ALL и PHP_INI_PERDIR. Для очистки значения задайте none.
Используется для установки значений логических директив. Также может быть использована только с типами PHP_INI_ALL и PHP_INI_PERDIR type directives.
Устанавливает значение указанной директивы. Эта директива НЕ МОЖЕТ быть использована в файлах .htaccess. Любая директива, заданная с помощью php_admin_value, не может быть переопределена в файлах .htaccess.
Устанавливает значение указанной логической директивы. Эта директива НЕ МОЖЕТ быть использована в файлах .htaccess. Любая директива, заданная с помощью php_admin_flag, не может быть переопределена в файлах .htaccess.
Замечание: Константы PHP не определены вне PHP. К примеру, в файле httpd.conf нельзя использовать константы PHP, такие, как E_ALL или E_NOTICE, поскольку они не будут иметь значения и будут восприняты, как 0. Вместо констант придется использовать соответствующие значения.
Независимо от интерфейса PHP, можно изменить некоторые значения прямо во время выполнения программы командой ini_set(). Следующая таблица показывает уровни изменения значений директивы:
Таблица 4-1. Определение констант PHP_INI_*
| Константа | Значение | Уровень |
|---|---|---|
| PHP_INI_USER | 1 | Значение может изменяться в программе пользователя |
| PHP_INI_PERDIR | 2 | Значение может быть задано в php.ini, .htaccess или httpd.conf |
| PHP_INI_SYSTEM | 4 | Значение может быть задано в php.ini или httpd.conf |
| PHP_INI_ALL | 7 | Значение может задаваться где угодно |
Значения конфигурационных директив можно посмотреть в выводе функции phpinfo(). Также можно получит доступ к данным значениям с использованием ini_get() или get_cfg_var().
Таблица 4-3. Language and Misc Configuration Options
| Name | Default | Changeable |
|---|---|---|
| short_open_tag | On | PHP_INI_SYSTEM|PHP_INI_PERDIR |
| asp_tags | Off | PHP_INI_SYSTEM|PHP_INI_PERDIR |
| precision | "14" | PHP_INI_ALL |
| y2k_compliance | Off | PHP_INI_ALL |
| allow_call_time_pass_reference | On | PHP_INI_SYSTEM|PHP_INI_PERDIR |
| expose_php | On | PHP_INI_SYSTEM |
Here is a short explanation of the configuration directives.
Tells whether the short form (<? ?>) of PHP's open tag should be allowed. If you want to use PHP in combination with XML, you can disable this option in order to use <?xml ?> inline. Otherwise, you can print it with PHP, for example: <?php echo '<?xml version="1.0"'; ?>. Also if disabled, you must use the long form of the PHP open tag (<?php ?>).
Замечание: This directive also affects the shorthand <?=, which is identical to <? echo. Use of this shortcut requires short_open_tag to be on.
Enables the use of ASP-like <% %> tags in addition to the usual <?php ?> tags. This includes the variable-value printing shorthand of <%= $value %>. For more information, see Escaping from HTML.
Замечание: Support for ASP-style tags was added in 3.0.4.
The number of significant digits displayed in floating point numbers.
Enforce year 2000 compliance (will cause problems with non-compliant browsers)
Whether to enable the ability to force arguments to be passed by reference at function call time. This method is deprecated and is likely to be unsupported in future versions of PHP/Zend. The encouraged method of specifying which arguments should be passed by reference is in the function declaration. You're encouraged to try and turn this option Off and make sure your scripts work properly with it in order to ensure they will work with future versions of the language (you will receive a warning each time you use this feature, and the argument will be passed by value instead of by reference).
See also References Explained.
Decides whether PHP may expose the fact that it is installed on the server (e.g. by adding its signature to the Web server header). It is no security threat in any way, but it makes it possible to determine whether you use PHP on your server or not.
Here is a short explanation of the configuration directives.
This sets the maximum amount of memory in bytes that a script is allowed to allocate. This helps prevent poorly written scripts for eating up all available memory on a server. In order to use this directive you must have enabled it at compile time. So, your configure line would have included: --enable-memory-limit. Note that you have to set it to -1 if you don't want any limit for your memory.
See also: max_execution_time.
Таблица 4-5. Data Handling Configuration Options
| Name | Default | Changeable |
|---|---|---|
| track-vars | "On" | PHP_INI_?? |
| arg_separator.output | "&" | PHP_INI_ALL |
| arg_separator.input | "&" | PHP_INI_SYSTEM|PHP_INI_PERDIR |
| variables_order | "EGPCS" | PHP_INI_ALL |
| register_globals | "Off" | PHP_INI_PERDIR|PHP_INI_SYSTEM |
| register_argc_argv | "On" | PHP_INI_PERDIR|PHP_INI_SYSTEM |
| post_max_size | "8M" | PHP_INI_SYSTEM|PHP_INI_PERDIR |
| gpc_order | "GPC" | PHP_INI_ALL |
| auto_prepend_file | "" | PHP_INI_SYSTEM|PHP_INI_PERDIR |
| auto_append_file | "" | PHP_INI_SYSTEM|PHP_INI_PERDIR |
| default_mimetype | "text/html" | PHP_INI_ALL |
| default_charset | "iso-8859-1" | PHP_INI_ALL |
| always_populate_raw_post_data | "0" | PHP_INI_SYSTEM|PHP_INI_PERDIR |
| allow_webdav_methods | "0" | PHP_INI_SYSTEM|PHP_INI_PERDIR |
Here is a short explanation of the configuration directives.
If enabled, then Environment, GET, POST, Cookie, and Server variables can be found in the global associative arrays $_ENV, $_GET, $_POST, $_COOKIE, and $_SERVER.
Note that as of PHP 4.0.3, track_vars is always turned on.
The separator used in PHP generated URLs to separate arguments.
List of separator(s) used by PHP to parse input URLs into variables.
Замечание: Every character in this directive is considered as separator!
Set the order of the EGPCS (Environment, GET, POST, Cookie, Server) variable parsing. The default setting of this directive is "EGPCS". Setting this to "GP", for example, will cause PHP to completely ignore environment variables, cookies and server variables, and to overwrite any GET method variables with POST-method variables of the same name.
See also register_globals.
Tells whether or not to register the EGPCS (Environment, GET, POST, Cookie, Server) variables as global variables. For example; if register_globals = on, the url http://www.example.com/test.php?id=3 will produce $id. Or, $DOCUMENT_ROOT from $_SERVER['DOCUMENT_ROOT']. You may want to turn this off if you don't want to clutter your scripts' global scope with user data. As of PHP 4.2.0, this directive defaults to off. It's preferred to go through PHP Predefined Variables instead, such as the superglobals: $_ENV, $_GET, $_POST, $_COOKIE, and $_SERVER. Please read the security chapter on Using register_globals for related information.
Please note that register_globals cannot be set at runtime (ini_set()). Although, you can use .htaccess if your host allows it as described above. An example .htaccess entry: php_flag register_globals on.
Замечание: register_globals is affected by the variables_order directive.
Tells PHP whether to declare the argv & argc variables (that would contain the GET information).
See also command line. Also, this directive became available in PHP 4.0.0 and was always "on" before that.
Sets max size of post data allowed. This setting also affects file upload. To upload large files, this value must be larger than upload_max_filesize.
If memory limit is enabled by your configure script, memory_limit also affects file uploading. Generally speaking, memory_limit should be larger than post_max_size.
Set the order of GET/POST/COOKIE variable parsing. The default setting of this directive is "GPC". Setting this to "GP", for example, will cause PHP to completely ignore cookies and to overwrite any GET method variables with POST-method variables of the same name.
Замечание: This option is not available in PHP 4. Use variables_order instead.
Specifies the name of a file that is automatically parsed before the main file. The file is included as if it was called with the include() function, so include_path is used.
The special value none disables auto-prepending.
Specifies the name of a file that is automatically parsed after the main file. The file is included as if it was called with the include() function, so include_path is used.
The special value none disables auto-appending.
Замечание: If the script is terminated with exit(), auto-append will not occur.
As of 4.0b4, PHP always outputs a character encoding by default in the Content-type: header. To disable sending of the charset, simply set it to be empty.
Always populate the $HTTP_RAW_POST_DATA variable.
Allow handling of WebDAV http requests within PHP scripts (eg. PROPFIND, PROPPATCH, MOVE, COPY, etc..) If you want to get the post data of those requests, you have to set always_populate_raw_post_data as well.
See also: magic_quotes_gpc, magic-quotes-runtime, and magic_quotes_sybase.
Таблица 4-6. Paths and Directories Configuration Options
| Name | Default | Changeable |
|---|---|---|
| include_path | PHP_INCLUDE_PATH | PHP_INI_ALL |
| doc_root | PHP_INCLUDE_PATH | PHP_INI_SYSTEM |
| user_dir | NULL | PHP_INI_SYSTEM |
| extension_dir | PHP_EXTENSION_DIR | PHP_INI_SYSTEM |
| cgi.force_redirect | "1" | PHP_INI_SYSTEM |
| cgi.redirect_status_env | "" | PHP_INI_SYSTEM |
| fastcgi.impersonate | "0" | PHP_INI_SYSTEM |
Here is a short explanation of the configuration directives.
Specifies a list of directories where the require(), include() and fopen_with_path() functions look for files. The format is like the system's PATH environment variable: a list of directories separated with a colon in UNIX or semicolon in Windows.
Using a . in the include path allows for relative includes as it means the current directory.
PHP's "root directory" on the server. Only used if non-empty. If PHP is configured with safe mode, no files outside this directory are served. If PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root if you are running php as a CGI under any web server (other than IIS) The alternative is to use the cgi.force_redirect configuration below.
The base name of the directory used on a user's home directory for PHP files, for example public_html.
In what directory PHP should look for dynamically loadable extensions. See also: enable_dl, and dl().
Which dynamically loadable extensions to load when PHP starts up.
cgi.force_redirect is necessary to provide security running PHP as a CGI under most web servers. Left undefined, PHP turns this on by default. You can turn it off AT YOUR OWN RISK.
Замечание: Windows Users: You CAN safely turn this off for IIS, in fact, you MUST. To get OmniHTTPD or Xitami to work you MUST turn it off.
If cgi.force_redirect is turned on, and you are not running under Apache or Netscape (iPlanet) web servers, you MAY need to set an environment variable name that PHP will look for to know it is OK to continue execution.
Замечание: Setting this variable MAY cause security issues, KNOW WHAT YOU ARE DOING FIRST.
FastCGI under IIS (on WINNT based OS) supports the ability to impersonate security tokens of the calling client. This allows IIS to define the security context that the request runs under. mod_fastcgi under Apache does not currently support this feature (03/17/2002) Set to 1 if running under IIS. Default is zero.
Таблица 4-7. File Uploads Configuration Options
| Name | Default | Changeable |
|---|---|---|
| file_uploads | "1" | PHP_INI_SYSTEM |
| upload_tmp_dir | NULL | PHP_INI_SYSTEM |
| upload_max_filesize | "2M" | PHP_INI_SYSTEM|PHP_INI_PERDIR |
Here is a short explanation of the configuration directives.
Whether or not to allow HTTP file uploads. See also the upload_max_filesize, upload_tmp_dir, and post_max_size directives.
The temporary directory used for storing files when doing file upload. Must be writable by whatever user PHP is running as. If not specified PHP will use the system's default.
The maximum size of an uploaded file.
PHP - это мощный язык программирования и интерпретатор. Будучи интегрированным в виде модуля в Web-сервер, или выполняясь как отдельное CGI-приложение, он может обращаться к файлам, исполнять команды и открывать сетевые соединения на сервере. Эти особенности делают все, что выполняется на Web-сервере, небезопасным. PHP специально разрабатывался для того, чтобы быть более безопасным языком для написания CGI-совместимых программ, нежели Perl или С, и, если правильно выставлены настройки компиляции и выполнения, а также при наличии достаточного опыта программирования, PHP даст вам необходимое соотношение гибкости и безопасности.
Поскольку существует множество различных вариантов использования PHP, существует очень много настроек, контролирующих его поведение. Большой выбор опций означает, что вы сможете использовать PHP для многих целей, однако также значит, что есть такие комбинации этих опций и настроек сервера, которые приведут к проблемам безопасности.
Гибкость настройки PHP конкурирует с гибкостью программирования. PHP может быть использован для создания серверных приложений со всеми возможностями пользователя shell, или для простого включения файлов на стороне сервера, которое не представляет опасности в хорошо контролируемой системе. То, как построена система, и насколько она безопасна, практически полностью зависит от разработчика, использующего PHP.
В начале главы даются основные советы по реализации безопасности, объясняются различные комбинации опций настройки и ситуации, в которых они могут быть безопасно использованы. Также приводятся различные соображения по части программирования для разных уровней безопасности.
Полностью безопасная система практически не может существовать, поэтому основной используемый здесь подход - подход разумного риска. К примеру, если каждая переменная, переданная пользователем, будет требовать двух биометрических подтверждений (вроде сканирования сетчатки и отпечатка пальца), у вас будет очень высокий уровень контроля. С другой стороны, заполнение длинных и сложных форм может занимать достаточно длительное время, что обычно заставляет пользователей искать пути обхода системы безопасности.
Наилучший вариант обычно соответствует требованиям безопасности, но не мешает работе пользователей, а также не перегружает программный код излишней сложностью. Что касается сложности, то некоторые атаки как раз и являются следствием чрезмерного "наворачивания" защиты. Как известно, чем сложнее защита, тем больше в ней не совсем очевидных "дыр".
Всегда необходимо помнить: система безопасности настолько хороша, насколько безопасно ее самое слабое место. Если, к примеру, ведутся отчеты по всем операциям, времени, месту и т.д., но проверка пользователей осуществляется с использованием одного cookie, то соответствие имен пользователей в отчетах с реальными пользователями весьма и весьма сомнительно.
При отладке помните, что невозможно предугадать все варианты развития событий даже для одной единственной странички. Ожидаемые входные данные могут отличаться от введенных недобросовестным работником, хакером с многолетним стажем или просто кошкой, прошедшейся по клавиатуре. Поэтому всегда удобнее подходить к программе с точки зрения логики, чтобы проследить места возможного появления неожиданных данных, а также их использования.
Интернет полон людей, которые хотят сделать себе имя путем взлома вашего кода, останова вашего сайта, размещения неподходящих данных, в общем, всего, что не дает вам жить спокойно. Неважно, какого масштаба ваш сайт, вы находитесь под прицелом просто потому, что вы в сети, потому, что у вас есть сервер, к которому можно подключиться. Множество программ для взлома не различают размеров, они просто прокачивают огромное количество IP-траффика в поисках жертвы. Постарайтесь не стать таковой.
Использование PHP в виде приложения CGI - вариант для тех, кто по тем или иным причинам не хочет встраивать PHP в приложение сервера (к примеру, Apache), в виде модуля, или для тех, то хочет использовать PHP совместно с CGI-оболочками, помогающими создать безопасную среду для выполнения программ. Такая настройка обычно включает в себя инсталляцию приложения PHP в директорию cgi-bin на сервере. Рекомендация CERTCA-96.11 выступает против помещения интерпретаторов в cgi-bin. Даже при том, что PHP может быть использован, как независимый интерпретатор, он разрабатавылся для предотвращения атак, связанных с данным вариантом настройки:
Получение доступа к системным файлам: http://my.host/cgi-bin/php?/etc/passwd
Информация запроса в URL после знака вопроса (?) передается с помощью CGI интерпретатору в виде командной строки. Обычно интерпретаторы открывают и выполняют файл, заданный первым аргументом в данной строке.
При вызове в роли приложения CGI, PHP не интерпретирует аргументы командной строки.
Получение доступа к любому документу на сервере: http://my.host/cgi-bin/php/secret/doc.html
Информационнася часть URL после названия приложения PHP /secret/doc.html обычно используется для задания файла, который будет открыт и интерпретирован приложением CGI. В общем случае для перенаправления запросов вида http://my.host/secret/script.php интерпретатору PHP используются директивы конфигурации Web-сервера (к примеру, Action в Apache). При такой настройке, сервер сначала проверяет разрешения на доступ к данной директории /secret, и только после создает перенаправленный запрос http://my.host/cgi-bin/php/secret/script.php. К сожалению, если запрос уже дан в вышеприведенной форме, сервер не выполняет никаких проверок на право доступа к файлу /secret/script.php, выполняя данную проверку только для файла /cgi-bin/php. Таким образом, любой пользователь c доступом к /cgi-bin/php может получить доступ к любому защищенному документу на сервере.
В PHP, опция конфигурации компилятора--enable-force-cgi-redirect и опции конфигурации времени выполненияdoc_root и user_dir могут быть использованы для предотвращения подобных атак, если дерево документов сервера имеет каталоги с ограничением доступа. Далее приводятся подробные пояснения к различным комбинациям опций.
Если ваш сервер не содержит ничего защищенного паролем или списком IP-адресов, то в вышеперечисленных опциях нет необходимости. Если ваш Web-сервер не допускает перенаправлений, или если сервер не имеет возможности безопасно перенаправить запрос приложению PHP, вы можете установить опцию --enable-force-cgi-redirect конфигурирующей программе. Однако, вам все равно придется следить за тем, чтобы ваши программы не зависели от метода их вызова, как прямого http://my.host/cgi-bin/php/dir/script.php так и с использованием перенаправления http://my.host/dir/script.php.
Перенаправление может быть настроено в сервере Apache с использованием директив AddHandler и Action directives (см. ниже).
Эта опция компиляции не дает никому использовать PHP напрямую, с применением URL вроде http://my.host/cgi-bin/php/secretdir/script.php. PHP будет транслировать данные только в том случае, если они уже прошли через перенаправление Web-сервера.
Обычно перенаправление в сервере Apache конфигурируется с использованием следующих команд:
Action php-script /cgi-bin/php AddHandler php-script .php |
Эта опция была проверена только для Web-сервера Apache и основывается на установке им не-CGI-стандартной переменной окружения REDIRECT_STATUS для перенаправленных запросов. Если ваш Web-сервер не поддерживает никаких путей указания того, осуществлялось ли перенаправление запроса, вы не можете использовать эту опцию и должны использовать другие варианты использования приложения CGI, описанные ниже.
Помещение активного содержимого (вроде программ и исполняемых файлов) в директории документов Web-сервера считается небезопасным. Если в случае какой-либо ошибки в конфигурировании программы не выполнятся, а отобразятся как обычные HTML-документы, это приведет к утечке интеллектуальной собственности или скрытой информации вроде паролей. Поэтому многие системные администраторы предпочитают создавать отдельную структуру директорий для программ, доступных только через PHP CGI, а поэтому всегда интепретируемых и отображаемых верно.
К тому же, если недоступен метод безопасного перенаправления запросов, описанный в предыдущей части, необходимо установить doc_root для программ, отличный от корневого каталога документов Web-сервера.
Корневой каталог документов для программ PHP можно установить с помощью директивы doc_root в файле конфигурации или с помощью переменной окружения PHP_DOCUMENT_ROOT. Если такая установка сделана, то CGI-версия PHP всегда будет добавлять к информации пути в запросе значение параметра doc_root, так что в этом случае вы можете быть уверены, что ни одна программа не выполнится за пределами этой директории (исключение составляет лишь случай с использованием параметра user_dir, описанный ниже).
Еще одной полезной опцией является user_dir. Если user_dir не задана, то единственным фактором, влияющим на имя открываемого файла является doc_root. Открытие URL вроде http://my.host/~user/doc.php не приведет в этом случае к открытию файла внутри домашнего каталога пользователя. В этом случае будет открыт файл ~user/doc.php в каталоге, заданном в doc_root.
Если user_dir установлена, к примеру, в public_php, то запрос http://my.host/~user/doc.php откроет файл doc.php в каталоге public_php, находящемся в домашнем каталоге пользователя. Если домашний каталог пользователя - /home/user, то в этом случае будет открыт файл /home/user/public_php/doc.php.
user_dir используется независимо от doc_root, что дает возможность задавать корневую директорию документов и пользовательские директории независимо друг от друга.
Весьма безопасным является помещение программы-транслятора PHP за пределами дерева документов Web-сервера. К примеру, в /usr/local/bin. У этого варианта есть лишь один недостаток - то, что в начало каждого файла с тэгами PHP придется помещать следующую строку:
. Также потребуется сделать данные файлы исполняемыми, т.е. придется обращаться с ними так же, как и с любыми другими CGI-программами на Perl, sh или на других известных языках, использующих конструкцию #! для запуска.Для того, чтобы PHP начал в данном случае корректно обрабатывать PATH_INFO и PATH_TRANSLATED, транслятор PHP должен быть скомпилирован с опцией конфигурации --enable-discard-path.
При использовании PHP, как модуля Apache, данный модуль получает все права и разрешения Apache (обычно, права пользователя "nobody", т.е. "отсутствующего" пользователя). Это вносит некоторые сложности в систему безопасности и авторизации. К примеру, если PHP используется для обращения к базе данных, то в случае отсутствия встроенного контроля доступа в базе данных ее придется сделать доступной для пользователя "nobody". В этом случае скрипт злоумышленника может получить доступ на чтение и изменение базы данных даже без указания имени пользователя и пароля. Также возможно, что сетевой червь проникнет на страницу администратора и уничтожит все ваши базы данных. Можно защититься от этого путем введения авторизации в Apache, или разработав собственную модель доступа с использованием LDAP, файлов .htaccess (и др.) и использовать этот код, как часть ваших программ на PHP.
Часто случается так, что когда безопасность достигает уровня, где PHP (а в данном случае, Apache) практически не представляет проблемы безопасности, оказывается, что PHP не может записать ни одного файла в пользовательские каталоги. Или, допустим, не имеет доступа к базам данных. PHP оказывается одинакого защищенным от записи дозволенных и недозволенных файлов, или от произведения дозволенных или недозволенных операций с базами данных.
Очень частая ошибка на этом этапе - дать PHP права "root", или администратора или каким-либо образом увеличить разрешения для Apache.
Установка для Apache разрешений администратора (root) очень опасна для системы в целом. Те, кто не является специалистами по безопасности, в данном случае должны избегать любых операций вроде "sudo" или "chroot".
Есть более простые решения. Используя open_basedir, можно контролировать и ограничивать использование PHP директорий. Также можно создать области "только для Apache", ограничив весь доступ не-пользовательскими или не-системными файлами.
PHP подчиняется установкам безопасности на уровне файлов и каталогов, которые встроены в большинство серверных систем. Это позволяет контролировать, какие файлы могут быть прочитаны. С особой аккуратностью нужно относиться к файлам с правом чтения "для всех" - нужно помнить о том, они могут быть считаны любым пользователем, имеющим доступ к данной файловой системе.
Поскольку PHP разрабатывался для предоставления пользовательских прав доступа к системе, возможно создать программу на PHP, которая позволит вам читать системные файлы, такие, как /etc/passwd, изменять параметры ваших сетевых соединений, создавать большие задания для печати и т.п. Это создает ряд проблем - нужно быть уверенным в том, что именно необходимые файлы разрешены для чтения и записи.
Приведем следующую программу, где пользователь хочет стереть файл в своем домашнем каталоге. Это типичная ситуация, когда Web-интерфейс PHP используется для управления файлами, т.е. пользователи Apache имеют возможность удалять файлы в своих домашних каталогах.
Назначение интерпретатору PHP ограниченных прав.
Проверка всех переданных переменных.
Пример 5-3. Более безопасная проверка имени файла
|
Пример 5-4. Еще более безопасная проверка имени файла
|
В зависимости от вашей операционной системы, существуют файлы, о безопасности которых надо позаботиться - драйверы устройств (/dev/ или COM1), файлы конфигурации (файлы /etc/ или файлы .ini), известные области хранения данных (/home/, Mои документы), и т.д. В связи с этим, обычно проще создать политику в которой запрещено все, кроме того, что разрешено, как говорится, "вручную".
Сегодня базы данных - основная составляющая практически любых приложений, основанных на Web, которая дает возможность предоставления разнообразного динамического содержимого. Поскольку в таких базах данных может храниться весьма важная и секретная информация, нужно позаботиться и об их защите.
Для получения или сохранения информации в базе данных, к ней нужно подключиться, послать запрос, обработать ответ и закрыть подключение. Сегодня для всего этого обычно используется структурированный язык запросов (Structured Query Language, SQL). Давайте посмотрим, как злоумышленник может поступить с SQL-запросом.
Как известно, PHP не может сам защитить базу данных. Следующие разделы являются введением в основы доступа и использования баз данных в скриптах на PHP.
Помните простое правило: защита строится "вглубь". Чем больше мест вы защитите и чем больше действий предпримете для защиты базы данных, тем меньше вероятность успеха у злоумышленника на извлечение и использование хранимой в ней секретной информации. Все опасные места устраняются правильной разработкой структуры базы данных и использующего ее приложения.
Первый шаг всегда - собственно создание базы данных, за исключением случаев использования чужих баз. Когда создается база данных, ей назначается владелец, который и вызвал команду создания. Обычно только один владелец ("суперпользователь") может делать что угодно с объектами внутри этой базы данных и для того, чтобы позволить другим пользователям использовать ее, им должны быть назначены права доступа.
Приложения никогда не должны подключаться к базе данных в роли ее владельца или "суперпользователя", поскольку в этом случае пользователи могут произвести любые действия вроде модификации схемы (к примеру, удаления таблиц) или удаления всего ее содержимого.
Можно создать различных пользователей баз данных для каждого необходимого действия приложений, очень сильно ограничивая доступ последних к объектам базы данных. Требуемые права должны назначаться однократно, их использования в других местах приложения нужно избегать. Это значит, что если злоумышленник получит доступ с использованием той или иной учетной записи, он сможет получить лишь тот доступ, которым обладала использованная часть программы.
В приложения лучше не вводить всю логику работы с базами данных. Это можно сделать и в самой базе данных с использованием флагов, представлений, правил и встроенных процедур. В случае развития и расширения системы встроенные процедуры могут быть изменены для автоматической обработки новых полей, а флаги предоставят дополнительные возможности для отладки транзакций.
Можно устанавливать подключения с помощью SSL для шифрования соединений клиент-сервер, что дает повышенную безопасность. А можно использовать ssh для шифрования сетевых соединений между клиентами и сервером баз данных. Любой из этих способов сильно усложняет отслеживание и получение информации из сетевого траффика.
SSL/SSH защищает данные только по пути от клиента к серверу, но не данные, хранимые в базе данных. SSL - лишь сетевой протокол.
Когда злоумышленник получает доступ к вашей базе данных в обход Web-сервера, хранимые важные данные могут быть получены и использованы, за исключением случая, когда информация защищена в самой базе данных. Шифрование - весьма хороший прием в этом случае, но такой способ поддерживают ныне лишь очень немногие системы управления базами данных.
Самый легкий путь в этом случае - создать свою собственную систему шифрования, а затем использовать ее в скриптах на PHP. PHP способствует такому подходу благодаря наличию специфичных раширений, таких, как Mcrypt и Mhash, охватывающих большой ряд алгоритмов шифрования. Программа шифрует сохраняемые данные и расшифровывает получаемые. Для детального описания схем шифрования смотрите ссылки.
В случае скрытых данных, где не требуется их исходный вид (к примеру, для отображения), можно использовать хеширование. Известным примером хеширования является сохранение в базе данных хеша MD5 от пароля вместо самого пароля. Для подробного описания смотрите crypt() и md5().
Пример 5-5. Использование хешированных паролей
|
Многие разработчики Web-приложений считают запросы SQL не стоящими внимания, не зная о том, что их может использовать злоумышленник. Это означает, что запросы SQL могут быть использованы для обхода систем защиты, аутентификации и авторизации, а также иногда могут быть использованы для получения доступа к командам уровня операционной системы.
Внедрение в команды SQL - техника, при которой злоумышленник создает или изменяет команды SQL для получения доступа к скрытым данным, для изменения существующих и даже для выполнения команд уровня операционной системы. Это достигается в том случае, если программа использует введенные данные в комбинации со статическими параметрами для создания запроса SQL. Следующие примеры, к сожалению, основаны на реально произошедших случаях:
При недостаточной проверке вводимых данных и соединении с базой данных на правах суперпользователя злоумышленник может создать нового суперпользователя в базе данных.
Пример 5-6. Разделение результата запроса по страницам и... создание суперпользователей (PostgreSQL и MySQL)
|
// в случае PostgreSQL
0;
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
select 'crack', usesysid, 't','t','crack'
from pg_shadow where usename='postgres';
--
// в случае MySQL
0;
UPDATE user SET Password=PASSWORD('crack') WHERE user='root';
FLUSH PRIVILEGES; |
Замечание: Обычная практика - заставить транслятор SQL проигнорировать остаток запроса разработчика с помощью обозначения начала коментария SQL --.
Существует путь получения паролей через ваши страницы поиска. Все, что нужно злоумышленнику - это одна не обработанная должным образом переменная, используемая в SQL-запросе. Использоваться могут команды WHERE, ORDER BY, LIMIT и OFFSET запроса SELECT. Если ваша база данных поддерживает конструкцию UNION, злоумышленник может добавить к исходному запросу еще один - для получения паролей. В этом случае поможет хранение зашифрованных паролей.
Запросы SQL "UPDATE" также могут быть использованы для атаки на базу данных. Эти запросы также подвержены опасности "обрезки" и добавления новых запросов. Но здесь злоумышленник работает с командой SET. В этом случае необходимо знание некоторой информации о структуре базы данных для удачной модификации запроса. Такая информация может быть получена путем изучения названий переменных форм или просто подбором. В конце концов, не так уж и много имен придумано для полей пользователей и паролей.
// $uid == ' or uid like'%admin%'; -- $query = "UPDATE usertable SET pwd='...' WHERE uid='' or uid like '%admin%'; --"; // $pwd == "hehehe', admin='yes', trusted=100 " $query = "UPDATE usertable SET pwd='hehehe', admin='yes', trusted=100 WHERE ...;" |
А вот пугающий пример того, как на некоторых серверах баз данных могут быть выполнены команды уровня операционной системы:
$query = "SELECT * FROM products
WHERE id LIKE '%a%'
exec master..xp_cmdshell 'net user test testpass /ADD'--";
$result = mssql_query($query); |
Замечание: Некоторые из вышеперечисленных примеров привязаны к конкретному серверу баз данных. Но это вовсе не означает, что подобная атака невозможна на другое программное обеспечение. Ваш сервер баз данных тоже так или иначе будет уязвим для непредвиденных атак.
В большинстве примеров видно, что для атаки злоумышленник должен обладать некоторой информацией. Все верно, но никогда заранее не известно, какими путями уйдет данная информация. Если это все-таки случится, база данных становится незащищенной. Если вы используете свободно распространяемый пакет управления базами данных, который принадлежит какой-нибудь системе управления содержимым или форуму, злоумышленник легко получит копию данной части вашей программы. Это также может представлять "дыру" в безопасности.
Большинство атак построены на использовании кода, который писался без учета соображений безопасности. Никогда не доверяйте введенным данным, особенно если они идут с клиентской стороны, пусть даже и из поля отметки, скрытого поля или записи cookie. Первый пример показывает, к чему может привести подмена этих данных.
Никогда не соединяйтесь с базой данных в роли суперпользователя или владельца. Всегда используйте специальных пользователей с минимумом прав.
Проверяйте ввод на совпадение типа данных с требуемым. PHP включает в себя большое количество проверочных функций, от самых простейших из разделов "Функции для работы с переменными" и "Функции обработки символьного типа", (к примеру is_numeric() и ctype_digit() соответственно) до регулярных выражений Perl ("Регулярные выражения, совместимые с Perl").
Если программа ожидает число, проверяйте данные с помощью is_numeric(), или просто изменяйте тип с помощью settype(), или даже используйте численное представление, выданное sprintf().
Пример 5-10. Более безопасная разбивка на страницы
|
Предваряйте любой нечисловой ввод, передаваемый в базу данных, функциями addslashes() или addcslashes(). В первом примере показано, что кавычек в статической части запроса недостаточно.
Не выводите никакой информации о структуре базы данных ни коим образом. Для описания подробностей смотрите раздел "Отчеты об ошибках" и "Функции обработки и учета ошибок".
Можно использовать хранимые процедуры и заданные расположения для того, чтобы отвязать обращение к данным от программы так, чтобы пользователи не имели прямого доступа к таблицам и представлениям, но этот вариант имеет собственные проблемы.
Кроме того, ведите журнал операций в программе или собственно в базе данных, если это поддерживается. Ведение журнала не предотвратит внедрения, но оно поможет определить, какая часть программы была поставлена под удар. Сам журнал бесполезен - полезна хранимая в нем информация. Чем ее больше - тем лучше.
В случае настройки безопасности PHP у отчета об ошибках есть две стороны. Одна - плюс в сторону безопасности, другая - наоборот.
Стандартная техника атаки включает в себя тестирование системы путем указания заведомо неверных данных и получения деталей всех возвращенных ошибок. Это позволяет взломщику получить информацию о сервере, о возможных слабостях системы защиты. К примеру, если злоумышленнику доступна информация о странице, использующей предварительный ввод данных в форму, то он может попытаться изменить передаваемые переменные:
Ошибки, которые обычно возвращаются PHP, очень помогают в отладке программ, указывая на файл или функцию, а также номер строки где произошла ошибка. Однако, вся эта информация может быть использована. Очень часто разработчики используют функции show_source(), highlight_string() или highlight_file(), как отладочные, но в реальном случае они могут показать скрытые переменные, неотлаженные участки кода и другую опасную информацию. Особенно опасен запуск кода с встроенными отладочными частями или с использованием технологий отладки. Если злоумышленник определит вашу схему отладки, он может просто послать вашему коду отладочные команды для произведения своих действий.
Независимо от способа обработки ошибок, возможность тестирования системы приводит к получению взломщиком дополнительной информации.
К примеру, сам стиль отображения ошибок PHP обозначает, что в системе запущен PHP. Если злоумышленник, видящий .html страницу захочет проверить сервер на слабые места в безопасности путем ввода неверных данных, он, таким образом, узнает, что система построена с использованием PHP.
Ошибки функций могут указать на запущенный в системе сервер баз данных или дать информацию о том, как написана эта Web-страница. Это позволяет вести дальнейшее исследование открытых мест в базе данных или искать ошибки и слабые места в Web-странице. Путем посылки различных некорректных данных злоумышленник может, например, узнать последовательность аутентификации (из номеров строк), а также может попытаться обнаружить "дыры" в различных местах программы.
Ошибки файловой системы или общие ошибки PHP могут открыть заданные Web-серверу разрешения, а также структуру файлов сервера. Коды ошибок разработчика ухудшают ситуацию, приводя к весьма примитивному использованию "официально скрытой" информации.
Есть три основных пути решения проблемы. Первый - отладить все функции и попытаться компенсировать наличие ошибок. Второй - полностью отключить отчет об ошибках. Третий - использовать собственный обработчик ошибок PHP. Выбор зависит от вашего желания и структуры вашей системы безопасности.
Еще один способ решения проблемы "досрочно" - использование встроенной опции PHP error_reporting(), для того, чтобы обезопасить программу и найти уязвимые переменные. Тестируя программу до развертывания с E_ALL можно быстро найти места, где переменные могут быть открыты для модификации. Как только программа готова к развертыванию, E_NONE предотвращает исследование.
Пример 5-13. Нахождение небезопасных переменных с помощью E_ALL
|
Еще одно средство PHP для повышения безопасности - конфигурация с использованием register_globals = off. Это отключает внедрение пользовательских переменных в среду переменных программы на PHP, сводя попытки внедрения злоумышленником нужных ему значений на нет. Опция полностью изолирует внутренние переменные от предоставляемых пользователем данных.
Конечно, это немного увеличивает количество усилий, необходимых для обработки пользовательского ввода. Но все-таки игра стоит свеч, и плюсы такого подхода гораздо более существенны, нежели минусы.
Пример 5-16. Простейшая проверка на подмену данных
|
Самые слабые места в большинстве программ на PHP не являются следствием проблем самого языка, напротив, они являются следствием написания этих программ без учета соображений безопасности. Поэтому вы всегда должны тратить некоторое время на продумывание ограничений тех или иных участков кода для снижения риска от некорректно заданных переменных.
Пример 5-17. Небезопасное использование переменной
|
Будет ли эта программа использовать именно необходимые файлы?
Могут ли быть обработаны необычные или нежелательные данные?
Может ли эта программа использоваться нежелательным образом?
Может ли она использоваться в совокупности с другими программами для реализации злого умысла?
Будут ли должным образом записаны в журнал операции?
Также следует подумать об отключении register_globals, magic_quotes, и других опций, которые ставят под сомнение корректность, источник и значения отдельно взятых переменных. Работа в режиме отображения всех ошибок (error_reporting=E_ALL) также предупредит об использовании переменных без предварительной проверки и инициализации.
В общем случае, скрытие - самая слабая форма системы безопасности. Но в некоторых случаях необходима любая малость.
Есть несколько приемов, позволяющих скрыть PHP, что замедлит действия злоумышленника, пытающегося обнаружить слабости в вашей системе. Установка в файле php.ini опции expose_php = off уменьшит количество доступной информации.
Другая тактика - настройка сервера Web (вроде Apache) для обработки различных типов файлов с помощью PHP. Это делается через директивы .htaccess или через файл конфигурации Apache. Затем можно использовать "отвлекающие" расширения файлов:
PHP, как и любая другая большая система, постоянно изменяется и дорабатывается. Каждая новая версия обычно включает как серьезные, так и небольшие изменения для устранения проблем безопасности, конфигурации, а также всего, что влияет на общую безопасность и стабильность системы.
Как и в случае с другими программами, лучший вариант - это выполнять обновление как можно чаще, а также следить за последними версиями и сделанными в них изменениями.
Когда PHP обрабатывает файл, он просто передаёт его текст, пока не встретит один из специальных тегов, который сообщает ему о необходимости начать интерпретацию текста как кода PHP. Затем он выполняет весь найденный код до закрывающего тега, говорящего интерпретатору, что далее снова идет просто текст. Этот механизм позволяет вам внедрять PHP-код в HTML - все за пределами тегов PHP остается неизменным, тогда как внутри - интерпретируется как код.
Существует четыре набора тегов, которые могут быть использованы для обозначения PHP-кода. Из них только два (<?php. . .?> и <script language="php">. . .</script>) всегда доступны; другие могут быть включены или выключены в конфигурационном файле php.ini. Хотя короткие теги и теги в стиле ASP могут быть удобны, они не так переносимы, как длинные версии. Кроме того, если вы намереваетесь вставлять PHP-код в XML или XHTML, чтобы соответствовать XML, вам следует использовать форму <?php. . .?>.
Теги, поддерживаемые PHP:
Пример 6-1. Способы вставки в HTML
|
Первый способ, <?php. . .?>, наиболее предпочтительный, так как он позволяет использовать PHP в коде, соответствующем правилам XML, таком как XHTML.
Второй способ не всегда доступен. Короткие теги доступны только когда они включены. Это можно сделать, используя функцию short_tags() (только в PHP 3), включив установку short_open_tag в конфигурационном файле PHP, либо скомпилировав PHP с параметром --enable-short-tags для configure. Даже если оно включено по умолчанию в php.ini-dist, использование коротких тегов не рекомендуется.
Четвертый способ доступен только если теги в стиле ASP были включены, используя конфигурационную установку asp_tags.
Замечание: Поддержка тегов в стиле ASP была добавлена в версии 3.0.4.
Замечание: Следует избегать использования коротких тегов при разработке приложений или библиотек, предназначенных для распространения или размещения на PHP-серверах, не находящихся под вашим контролем, так как короткие теги могут не поддерживаться на целевом сервере. Для создания переносимого, совместимого кода, не используйте короткие теги.
Закрывающий тег блока PHP-кода включает сразу следующий за ним перевод строки, если он имеется. Кроме того, закрывающий тег автоматически подразумевает точку с запятой; вам не нужно заканчивать последнюю строку кода в блоке точкой с запятой.
PHP позволяет использовать такие структуры:
Инструкции разделяются также как и в C или Perl - каждое выражение заканчивается точкой с запятой.
Закрывающий тег (?>) также подразумевает конец инструкции, поэтому два следующих фрагмента кода эквиваленты:
PHP поддерживает комметарии в стиле 'C', 'C++' и оболочки Unix. Например:
<?php
echo "Это тест"; // Это однострочный комментарий в стиле c++
/* Это многострочный комментарий
еще одна строка комментария */
echo "Это еще один тест";
echo "Последний тест"; # Это комментарий в стиле оболочки Unix
?> |
Однострочные комментарии идут только до конца строки или текущего блока PHP-кода, в зависимости от того, что идет перед ними.
Будьте внимательны, следите за отсутствием вложенных 'C'-комментариев, они могут появиться во время комментирования больших блоков.
Однострочные комментарии идут только до конца строки или текущего блока PHP-кода, в зависимости от того, что идет перед ними. Это означает, что HTML-код после // ?> БУДЕТ напечатан: ?> выводит из режима PHP и возвращает в режим HTML, но // не позволяет этого сделать.
PHP поддерживает восемь простых типов.
Четыре скалярных типа:
Два смешанных типа: И, наконец, два специальных типа: В этой документации также представлено несколько псевдо-типов для удобства понимания: Вы также можете найти несколько упоминаний типа двойной точности. Рассматривайте его как число с плавающей точкой, два имени существуют только по историческим причинам.Как правило, программист не устанавливает тип переменной; предпочтительнее, чтобы это делал PHP во время выполнения программы в зависимости от контекста, в котором используется переменная.
Замечание: Если вы желаете проверить тип и значение определенного выражения, используйте var_dump().
Замечание: Если же вам для отладки необходимо просто удобочитаемое представление типа, используйте gettype(). Чтобы проверить на определенный тип, не используйте gettype(), применяйте для этого is_type функции. Вот несколько примеров:
$bool = TRUE; // логический $str = "foo"; // строковый $int = 12; // целочисленный echo gettype($bool); // выводит "boolean" echo gettype($str); // выводит "string" // Если это целое, увеличить на четыре if (is_int($int)) { $int += 4; } // Если $bool - это строка, вывести ее // (ничего не выводит) if (is_string($bool)) { echo "Строка: $bool"; }
Если вы хотите принудительно изменить тип переменной, вы можете либо привести переменную, либо использовать функцию settype().
Обратите внимание, что переменная, в зависимости от ее типа в данный момент, в определенных ситуациях может иметь разные значения. Более подробную информацию смотрите в разделе Манипуляции с типами.
Это простейший тип. Он выражает истинность значения - это может быть либо TRUE, либо FALSE.
Замечание: Булев тип был введен в PHP 4.
Чтобы определить булев тип, используйте ключевое слово TRUE или FALSE. Оба регистро-независимы.
Обычно вы используете некий оператор, который возвращает логическое выражение, а затем предает его управляющей конструкции.
// == это оператор, который проверяет
// эквивалентность и возвращает булево значение
if ($action == "показать_версию") {
echo "Версия 1.23";
}
// это не обязательно...
if ($show_separators == TRUE) {
echo "<hr>\n";
}
// ...потому что вы можете просто написать
if ($show_separators) {
echo "<hr>\n";
} |
Для несомненной конвертации значения в булев тип используйте привидение типа (bool) или (boolean). Однако в большинстве случаев вам нет необходимости использовать привидение типа, поскольку значение будет автоматически конвертировано, если оператор, функция или управляющая конструкция требует булев аргумент.
Смотрите также Манипуляции с типами.
При конвертации в логический тип, следующие значения рассматриваются как FALSE:
Сам булев FALSE
целое 0 (ноль)
число с плавающей точкой 0.0 (ноль)
массив с нулевыми элементами
объект с нулевыми переменными-членами
специальный тип NULL (включая неустановленные переменные)
| Внимание |
-1 считается TRUE, как и любое ненулевое (отрицательное или положительное) число! |
Целое это число из множества Z = {..., -2, -1, 0, 1, 2, ...}.
Смотрите также: Целые произвольной длины и Числа с плавающей точкой
Целые могут быть указаны в десятичной, шестнадцатеричной или восьмеричной системе счисления, по желанию с предшествующим знаком (- или +).
Если вы используете восьмеричную систему счисления, вы должны предварить число 0 (нулем), для использования шестнадцатеричной системы нужно поставить перед числом 0x.
Если вы определите число, превышающее пределы целого типа, оно будет интерпретировано как число с плавающей точкой. Также, если вы используете оператор, результатом работы которого будет число, превышающее пределы целого, вместо него будет возвращено число с плавающей точкой.
$large_number = 2147483647; var_dump($large_number); // вывод: int(2147483647) $large_number = 2147483648; var_dump($large_number); // вывод: float(2147483648) // это справедливо и для шестнадцатеричных целых: var_dump( 0x80000000 ); // вывод: float(2147483648) $million = 1000000; $large_number = 50000 * $million; var_dump($large_number); // вывод: float(50000000000) |
| Внимание |
К сожалению, в PHP была ошибка, так что это не всегда верно работает, когда используются отрицательные числа. Например: когда вы умножаете -50000 * $million, результатом будет -429496728. Однако, если оба операнда положительны, проблем не возникает. Эта ошибка устранена в PHP 4.1.0. |
в PHP не существует оператора деления целых. Результатом 1/2 будет число с плавающей точкой 0.5. Вы можете привести значение к целому, что всегда округляет его в меньшую сторону, либо использовать функцию round().
Для несомненной конвертации значения в целое используйте привидение типа (int) или (integer). Однако в большинстве случаев вам нет необходимости использовать привидение типа, поскольку значение будет автоматически конвертировано, если оператор, функция или управляющая конструкция требует целый аргумент. Вы также можете конвертировать значение в целое при помощи функции intval().
Смотрите также Манипуляции с типами.
При конвертации из числа с плавющей точкой в целое, число будет округлено в сторону нуля.
Если число с плавающей точкой превышает пределы целого (как правило, это +/- 2.15e+9 = 2^31), результат будет неопределённым, так как целое не имеет достаточной точности, чтобы вернуть верный результат. В этом случае не будет выведено ни предупреждения, ни даже замечания!
| Внимание |
Никогда не приводите неизвестную дробь к целому, так как это может иногда дать неожиданные результаты. Смотрите более подробно: предупреждение о точности числел с плавающей точкой. |
| Предостережение |
Для других типов поведение конвертации в целое не определено. В настоящее время поведение такое же, как если бы значение сперва было конвертировано в булев тип. Однако не полагайтесь на это поведение, так как он может измениться без предупреждения. |
Числа с плавющей точкой (они же числа двойной точности или действительные числа) могут быть определены при помощи любого из следующих синтаксисов:
Формально:LNUM [0-9]+
DNUM ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
EXPONENT_DNUM ( ({LNUM} | {DNUM}) [eE][+-]? {LNUM}) |
| Точность числа с плавающей точкой |
Довольно часто простые десятичные дроби вроде 0.1 или 0.7 не могут быть конвертированы в свои внутренние двоичные аналоги без небольшой потери точности. Это может привести к неожиданным результатам: например, floor((0.1+0.7)*10) скорее всего возвратит 7 вместо ожидаемой 8 как результат внутреннего представления числа, являющегося в действительности чем-то вроде 7.9999999999.... Это связано с невозможностью точно выразить некоторые дроби в десятичной системе счисления конечным числом цифр. Например, 1/3 в десятичной форме принимает вид 0.3333333. . .. Так что никогда не доверяйте точности последних цифр в результатах с числами с плавающей точкой и никогда не проверяйте их на равенство. Если вам дейсвительно необходима высокая точность, вам следует использовать математические функции произвольной точности или gmp-функции. |
О том когда и как строки конвертируются в числа с плавающей точкой читайте в разделе Конвертация строк в числа. Для значений других типов конвертация будет такой же, как если бы значение сначала было конвертировано в целое, а затем в число с плавающей точкой. Дополнительную информацию смотрите в разделе Конвертация в целое.
Строка - это набор символов. В PHP символ это то же самое, что и байт, это значит, что возможно ровно 256 различных символов. Это также означает, что PHP не имеет встроенной поддержки Unicode'а. Некоторую поддержку Unicode'а обеспечивают эти функции utf8_enncode() и utf8_decode().
Замечание: Нет никаких проблем, если строка очень велика. Практически не существует ограничений на размер строк, налагаемых PHP, так что нет абсолютно никаких причин беспокоиться об их длине.
Строка может быть определена тремя различными способами.
Простейший способ определить строку - это заключить ее в одинарные кавычки (символ ').
Чтобы использовать одинарную кавычку внутри строки, как и во многих других языках, ее необходимо предварить символом обратной косой черты (\), т. е. мнемонизировать ее. Если обратная наклонная черта должна идти перед одинарной кавычкой либо быть в конце строки, вам необходимо продублировать ее. Обратите внимание, что если вы попытаетесь мнемонизировать любой другой символ, обратная косая черта также будет напечатана! Так что, как правило, нет необходимости мнемонизировать саму обратную косую черту.
Замечание: В PHP 3 в данном случае будет выдано сообщение уровня E_NOTICE.
Замечание: В отличие от двух других синтаксисов, переменные, встречающиеся в строках, заключенных в одинарные кавычки, не обрабатываются.
echo ''это простая строка'; echo 'Вы можете вставлять в строки символ новой строки таким образом'; echo 'Однажды Арнольд сказал: "I\'ll be back"'; // вывод: ... "I'll be back" echo 'Вы уверены, что хотите удалить C:\\*.*?'; // вывод: ... удалить C:\*.*? echo 'Вы уверены, что хотите удалить C:\*.*?'; // вывод: ... удалить C:\*.*? echo 'Я пытаюсь вставить в этой точке: \n символ новой строки'; // вывод: ... в этой точке: \n символ новой строки |
Если строка заключена в двойные кавычки ("), PHP распознает большее количество мнемоник специальных символов:
Таблица 7-1. Мнемоники символов
| последовательность | значение |
|---|---|
| \n | новая строка (LF или 0x0A (10) в ASCII) |
| \r | возврат каретки (CR или 0x0D (13) в ASCII) |
| \t | горизонтальная табуляция (HT или 0x09 (9) в ASCII) |
| \\ | обратная наклонная черта |
| \$ | знак доллара |
| \" | двойная кавычка |
| \[0-7]{1,3} | последовательность символов, соответсвующая регулярному выражению, символ в восьмеричной системе счисления |
| \x[0-9A-Fa-f]{1,2} | последовательность символов, соответсвующая регулярному выражению, символ в шестнадцатеричной системе счисления |
Повторяем, если вы захотите мнемнонизировать любой другой символ, обратная косая черта также будет напечатана!
Но самым важным свойством строк в двойных кавычках является обработка переменных. Смотрите более подробно: обработка строк.
Другой способ определения строк - это использование heredoc-синтаксиса ("<<<"). После <<< необходимо указать идентификатор, затем идет строка, а потом этот же идентификатор, закрывающий вставку.
Закрывающий идентификтор должен начинаться в первом столбце строки. Кроме того, идентификатор должен соответствовать тем же правилам именования, что и все остальные метки в PHP: содержать только буквенно-цифровые символы и знак подчеркивания, и должен начинаться с нецифры или знака подчеркивания.
| Внимание |
Важно отметить, что строка с закрывающим идентификатором не содержит других символов, за исключением, возможно, точки с запятой (;). Это означает, что идентификатор не должен вводиться с отступом и что не может быть никаких пробелов или знаков табуляции до или после точки с запятой. |
Heredoc-текст ведёт себя так же, как и строка в двойных кавычках, но без них. Это означает, что вам нет необходимости мнемонизировать кавычки в heredoc, но вы по-прежнему можете использовать вышеперечисленные коды-мнемоники. Переменные обрабатываются, но с применением сложных переменных внутри heredoc нужно быть также внимательным, как и при работе со строками.
Пример 7-2. Пример определения heredoc-строки
|
Замечание: Поддержка heredoc была добавлена в PHP 4.
Если строка определяется в двойных кавычках, либо при помощи heredoc, переменные внутри нее обрабатываются.
Существует два типа синтаксиса - простой и сложный. Простой синтаксис более легок и удобен, он дает возможность обработки переменной, значения массива или свойства объекта.
Сложный синтаксис был введен в PHP 4 и может быть распознан по фигурным скобкам, окружающих выражение.
Если интерпретатор встречает знак доллара ($), он захватывает столько символов, сколько возможно, чтобы сформировать правильное имя переменной. Если вы хотите точно определить конец имени, заключайте имя переменной в фигурные скобки.
$beer = 'Heineken';
echo "$beer's taste is great"; // работает, "'" это неверный символ для имени переменной
echo "He drank some $beers"; // не работает, 's' это верный символ для имени переменной
echo "He drank some ${beer}s"; // работает |
Точно также могут быть обработаны элемент массива или свойство объекта. В элементах массива закрывающая квадратная скобка (]) обозначает конец определения элемента. Для свойств объекта применяются те же правила, что и для простых переменных, хотя с ними невозможен трюк, как с переменными.
$fruits = array('strawberry' => 'red', 'banana' => 'yellow');
// Заметьте, что вне кавычек эта конструкция работает по-другому
echo "A banana is $fruits[banana].";
echo "This square is $square->width meters broad.";
// Не работает. Для решения см. сложный синтаксис.
echo "This square is $square->width00 centimeters broad."; |
Для чего-либо более сложного вы должны использовать сложный синтаксис.
Он называется сложным не потому, что труден в понимании, а потому что позволяет использовать сложные выражения.
Фактически, вы можете включить любое значение, находящееся в пространстве имени в строке с этим синтаксисом. Вы просто записываете выражение таким же образом, как и вне строки, а затем заключаете его в { и }. Поскольку вы не можете заменить мнемоникой '{', этот синтаксис будет распознаваться только когда $ следует непосредственно за {. (Используйте "{\$" или "\{$" чтобы отобразить "{$"). Несколько поясняющих примеров:
$great = 'fantastic';
echo "This is { $great}"; // не будет работать, выведет: This is { fantastic}
echo "This is {$great}"; // работает, выведет: This is fantastic
echo "Этот квадрат шириной {$square->width}00 сантиметров.";
echo "Это работает: {$arr[4][3]}";
// Это неверно по той же причине,
// что и $foo[bar] неверно вне строки.
echo "Это неправильно: {$arr[foo][3]}";
echo "Следует делать это так: {$arr['foo'][3]}";
echo "Вы можете даже записать {$obj->values[3]->name}";
echo "Это значение переменной по имени $name: {${$name}}"; |
Символы в строках можно использовать, определив их смещение относительно начала строки, начиная с нуля, в фигурных скобках после строки.
Замечание: Для обеспечения обратной совместимости, вы по-прежнему имеете возможность использовать в тех же целях скобки массива. Однако, начиная с PHP 4, этот синтаксис нежелателен к использованию.
Строки могут быть объединены при помощи оператора '.' (точка). Обратите внимание, оператор сложения '+' здесь не работает. Дополнительную информацию смотрите в разделе Строковые операторы.
Для модификации строк существует множество полезных функций.
Основные функции описаны в разделе строковых функций, функции регулярных выражений для расширенного поиска и замены (в двух частях: Perl и POSIX расширенный).
Также существуют функции для URL-строк, и функции для шифрования/дешифрования строк (mcrypt и mhash).
Наконец, если вы все еще не нашли, что искали, смотрите также функции для символьного типа.
Вы можете конвертировать значение в строку, используя приведение (string), либо функцию strval(). В выражениях, где необходима строка, конвертация происходит автоматически. Это происходит, когда вы используете функции echo() или print(), либо когда вы сравниваете значение переменной со строкой.
Логическое значение TRUE конвертируется в строку "1", а значение FALSE представляется как "" (пустая строка). Этим способом вы можете конвертировать значения в обе стороны из булева типа в строковый и наоборот.
Целое или число с плавающей точкой конвертируется в строку, представленную числом, состоящим из его цифр (включая показалтель степени для чисел с плавающей точкой).
Массивы всегда конвертируются в строку "Array", так что вы не можете отобразить содержимое массива, используя echo() или print(), чтобы узнать, что он содержит. Дополнительные советы вы можете найти ниже.
Объекты всегда конвертируются в строку "Object". Если вы хотите вывести значение переменной-члена объекта по причине отладки, прочтите следующие абзацы. Если вы хотите получить имя класса требуемого объекта, используйте функцию get_class().
Ресурсы всегда конвертируются в строки со структурой "Resource id #1", где 1 - это уникальный номер ресурса, присвоенный ему PHP во время выполнения. Если вы хотите получить тип ресурса, используйте функцию get_resource_type().
NULL всегда конвертируется в пустую строку.
Как вы могли видеть выше, вывод массивов, объектов или ресурсов не предоставляет вам никакой полезной информации о самих значениях. Более подходящий способ вывода значений для отладки - использовать функции print_r() и var_dump().
Вы также можете конвертировать значения PHP в строки для постоянного хранения. Этот метод называется сериализацией и может быть выполнен при помощи функции serialize(). Кроме того, если в вашей установке PHP есть поддержка WDDX, вы можете сериализовать значения PHP в структуры XML.
Если строка распознается как числовое значение, результирующее значение и тип определяется так как показано далее.
Строка будет распознана как float, если она содержит любой из символов '.', 'e', или 'E'. Иначе она будет определена как целое.
Значение определяется по начальной части строки. Если строка начинается с верного числового значения, будет использовано это значение. Иначе значением будет 0 (ноль). Верное числовое значение - это одна или более цифр (могущих содержать десятичную точку), по желанию предваренных знаком, с последующим необязательным показателем степени. Показатель степени - это 'e' или 'E' с последующими одной или более цифрами.
$foo = 1 + "10.5"; // $foo это float (11.5) $foo = 1 + "-1.3e3"; // $foo это float (-1299) $foo = 1 + "bob-1.3e3"; // $foo это integer (1) $foo = 1 + "bob3"; // $foo это integer (1) $foo = 1 + "10 Small Pigs"; // $foo это integer (11) $foo = 4 + "10.2 Little Piggies"; // $foo это float (14.2) $foo = "10.0 pigs " + 1; // $foo это float (11) $foo = "10.0 pigs " + 1.0; // $foo это float (11) |
Более подробную информацию об этой конвертации смотрите в документации по Unix в разделе о strtod(3).
Если вы хотите протестировать любой из примеров этого раздела, вы можете скопировать и вставить его и следующую строку, чтобы увидеть, что происходит:
Не ожидайте получить код символа, конвертировав его в целое (как вы могли бы сделать, например, в C). Для конвертации символов в их коды и обратно используйте функции ord() и chr().
An array in PHP is actually an ordered map. A map is a type that maps values to keys. This type is optimized in several ways, so you can use it as a real array, or a list (vector), hashtable (which is an implementation of a map), dictionary, collection, stack, queue and probably more. Because you can have another PHP-array as a value, you can also quite easily simulate trees.
Explanation of those structures is beyond the scope of this manual, but you'll find at least one example for each of those structures. For more information we refer you to external literature about this broad topic.
An array can be created by the array() language-construct. It takes a certain number of comma-separated key => value pairs.
array( [key =>] value
, ...
)
// key is either string or nonnegative integer
// value can be anything |
A key is either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. "8" will be interpreted as 8, while "08" will be interpreted as "08"). There are no different indexed and associative array types in PHP, there is only one array type, which can both contain integer and string indices.
A value can be of any PHP type.
If you omit a key, the maximum of the integer-indices is taken, and the new key will be that maximum + 1. As integers can be negative, this is also true for negative indices. Having e.g. the highest index being -6 will result in being -5 the new key. If no integer-indices exist yet, the key will be 0 (zero). If you specify a key that already has a value assigned to it, that value will be overwritten.
// This array is the same as ... array(5 => 43, 32, 56, "b" => 12); // ...this array array(5 => 43, 6 => 32, 7 => 56, "b" => 12); |
Using TRUE as a key will evalute to integer 1 as key. Using FALSE as a key will evalute to integer 0 as key. Using NULL as a key will evaluate to an empty string. Using an emptry string as key will create (or overwrite) a key with an empty string and its value, it is not the same as using empty brackets.
You cannot use arrays or objects as keys. Doing so will result in a warning: Illegal offset type.
You can also modify an existing array, by explicitly setting values in it.
This is done by assigning values to the array while specifying the key in brackets. You can also omit the key, add an empty pair of brackets ("[]") to the variable-name in that case.
$arr[key] = value; $arr[] = value; // key is either string or nonnegative integer // value can be anything |
There are quite some useful function for working with arrays, see the array functions section.
Замечание: The unset() function allows unsetting keys of an array. Be aware that the array will NOT be reindexed. If you only use "usual integer indices" (starting from zero, increasing by one), you can achive the reindex effect by using array_values().
The foreach control structure exists specifically for arrays. It provides an easy way to traverse an array.
You should always use quotes around an associative array index. For example, use $foo['bar'] and not $foo[bar]. But why is $foo[bar] wrong? You might have seen the following syntax in old scripts:
This is wrong, but it works. Then, why is it wrong? The reason is that this code has an undefined constant (bar) rather than a string ('bar' - notice the quotes), and PHP may in future define constants which, unfortunately for your code, have the same name. It works, because the undefined constant gets converted to a string of the same name automatically for backward compatibility reasons.As stated in the syntax section, there must be an expression between the square brackets ('[' and ']'). That means that you can write things like this:
This is an example of using a function return value as the array index. PHP also knows about constants, as you may have seen the E_* ones before.$error_descriptions[E_ERROR] = "A fatal error has occured"; $error_descriptions[E_WARNING] = "PHP issued a warning"; $error_descriptions[E_NOTICE] = "This is just an informal notice"; |
$error_descriptions[1] = "A fatal error has occured"; $error_descriptions[2] = "PHP issued a warning"; $error_descriptions[8] = "This is just an informal notice"; |
Then, how is it possible that $foo[bar] works? It works, because bar is due to its syntax expected to be a constant expression. However, in this case no constant with the name bar exists. PHP now assumes that you meant bar literally, as the string "bar", but that you forgot to write the quotes.
At some point in the future, the PHP team might want to add another constant or keyword, or you may introduce another constant into your application, and then you get in trouble. For example, you already cannot use the words empty and default this way, since they are special reserved keywords.
Замечание: When you turn error_reporting to E_ALL, you will see that PHP generates notices whenever an index is used which is not defined. Consider this script:
The output is:
Замечание: Inside a double-quoted string, another syntax is valid. See variable parsing in strings for more details.
For any of the types: integer, float, string, boolean and resource, if you convert a value to an array, you get an array with one element (with index 0), which is the scalar value you started with.
If you convert an object to an array, you get the properties (member variables) of that object as the array's elements. The keys are the member variable names.
If you convert a NULL value to an array, you get an empty array.
The array type in PHP is very versatile, so here will be some examples to show you the full power of arrays.
// this
$a = array( 'color' => 'red',
'taste' => 'sweet',
'shape' => 'round',
'name' => 'apple',
4 // key will be 0
);
// is completely equivalent with
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name'] = 'apple';
$a[] = 4; // key will be 0
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// will result in the array array(0 => 'a' , 1 => 'b' , 2 => 'c'),
// or simply array('a', 'b', 'c') |
Пример 7-4. Using array()
|
Note that it is currently not possible to change the values of the array directly in such a loop. A workaround is the following:
This example creates a one-based array.
Arrays are ordered. You can also change the order using various sorting-functions. See the array functions section for more information. You can count the number of items in an array using the count() function.
Because the value of an array can be everything, it can also be another array. This way you can make recursive and multi-dimensional arrays.
Пример 7-10. Recursive and multi-dimensional arrays
|
You should be aware, that array assignment always involves value copying. You need to use the reference operator to copy an array by reference.
To initialize an object, you use the new statement to instantiate the object to a variable.
For a full discussion, please read the section Classes and Objects.
If an object is converted to an object, it is not modified. If a value of any other type is converted to an object, a new instace of the stdClass built in class is created. If the value was null, the new instance will be empty. For any other value, a member variable named scalar will contain the value.
A resource is a special variable, holding a reference to an external resource. Resources are created and used by special functions. See the appendix for a listing of all these functions and the corresponding resource types.
Замечание: The resource type was introduced in PHP 4
As resource types hold special handlers to opened files, database connections, image canvas areas and the like, you cannot convert any value to a resource.
Due to the reference-counting system introduced with PHP4's Zend-engine, it is automatically detected when a resource is no longer referred to (just like Java). When this is the case, all resources that were in use for this resource are made free by the garbage collector. For this reason, it is rarely ever necessary to free the memory manually by using some free_result function.
Замечание: Persistent database links are special, they are not destroyed by the garbage collector. See also the section about persistent connections.
The special NULL value represents that a variable has no value. NULL is the only possible value of type NULL.
Замечание: The null type was introduced in PHP 4
A variable is considered to be NULL if
it has been assigned the constant NULL.
it has not been set to any value yet.
it has been unset().
mixed indicates that a parameter may accept multiple (but not necesseraly all) types.
gettype() for example will accept all PHP types, while str_replace() will accept strings and arrays.
Some functions like call_user_function() or usort() accept user defined callback functions as a parameter. Callback functions can not only be simple functions but also object methods including static class methods.
A PHP function is simply passed by its name as a string. You can pass any builtin or user defined function with the exception of array(), echo(), empty(), eval(), exit(), isset(), list(), print() and unset().
A method of an instantiated object is passed as an array containing an object as the element with index 0 and a method name as the element with index 1.
Static class methods can also be passed without instantiating an object of that class by passing the class name instead of an object as the element with index 0.
Пример 7-11. Callback function examples
|
PHP does not require (or support) explicit type definition in variable declaration; a variable's type is determined by the context in which that variable is used. That is to say, if you assign a string value to variable $var, $var becomes a string. If you then assign an integer value to $var, it becomes an integer.
An example of PHP's automatic type conversion is the addition operator '+'. If any of the operands is a float, then all operands are evaluated as floats, and the result will be a float. Otherwise, the operands will be interpreted as integers, and the result will also be an integer. Note that this does NOT change the types of the operands themselves; the only change is in how the operands are evaluated.
$foo = "0"; // $foo is string (ASCII 48) $foo += 2; // $foo is now an integer (2) $foo = $foo + 1.3; // $foo is now a float (3.3) $foo = 5 + "10 Little Piggies"; // $foo is integer (15) $foo = 5 + "10 Small Pigs"; // $foo is integer (15) |
If the last two examples above seem odd, see String conversion to numbers.
If you wish to force a variable to be evaluated as a certain type, see the section on Type casting. If you wish to change the type of a variable, see settype().
If you would like to test any of the examples in this section, you can use the var_dump() function.
Замечание: The behaviour of an automatic conversion to array is currently undefined.
Since PHP (for historical reasons) supports indexing into strings via offsets using the same syntax as array indexing, the example above leads to a problem: should $a become an array with its first element being "f", or should "f" become the first character of the string $a?
The current versions of PHP interpret the second assignment as a string offset identification, so $a becomes "f", the result of this automatic conversion however should be considered undefined. PHP 4 introduced the new curly bracket syntax to access characters in string, use this syntax instead of the one presented above:
See the section titled String access by character for more informaton.
Type casting in PHP works much as it does in C: the name of the desired type is written in parentheses before the variable which is to be cast.
The casts allowed are:
(int), (integer) - cast to integer
(bool), (boolean) - cast to boolean
(float), (double), (real) - cast to float
(string) - cast to string
(array) - cast to array
(object) - cast to object
Note that tabs and spaces are allowed inside the parentheses, so the following are functionally equivalent:
Замечание: Instead of casting a variable to string, you can also enclose the variable in double quotes.
It may not be obvious exactly what will happen when casting between certain types. For more info, see these sections:
Variables in PHP are represented by a dollar sign followed by the name of the variable. The variable name is case-sensitive.
Variable names follow the same rules as other labels in PHP. A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'
Замечание: For our purposes here, a letter is a-z, A-Z, and the ASCII characters from 127 through 255 (0x7f-0xff).
<?php $var = "Bob"; $Var = "Joe"; echo "$var, $Var"; // outputs "Bob, Joe" $4site = 'not yet'; // invalid; starts with a number $_4site = 'not yet'; // valid; starts with an underscore $tдyte = 'mansikka'; // valid; 'д' is ASCII 228. ?> |
In PHP 3, variables are always assigned by value. That is to say, when you assign an expression to a variable, the entire value of the original expression is copied into the destination variable. This means, for instance, that after assigning one variable's value to another, changing one of those variables will have no effect on the other. For more information on this kind of assignment, see the chapter on Expressions.
PHP 4 offers another way to assign values to variables: assign by reference. This means that the new variable simply references (in other words, "becomes an alias for" or "points to") the original variable. Changes to the new variable affect the original, and vice versa. This also means that no copying is performed; thus, the assignment happens more quickly. However, any speedup will likely be noticed only in tight loops or when assigning large arrays or objects.
To assign by reference, simply prepend an ampersand (&) to the beginning of the variable which is being assigned (the source variable). For instance, the following code snippet outputs 'My name is Bob' twice:
<?php $foo = 'Bob'; // Assign the value 'Bob' to $foo $bar = &$foo; // Reference $foo via $bar. $bar = "My name is $bar"; // Alter $bar... echo $bar; echo $foo; // $foo is altered too. ?> |
One important thing to note is that only named variables may be assigned by reference.
PHP provides a large number of predefined variables to any script which it runs. Many of these variables, however, cannot be fully documented as they are dependent upon which server is running, the version and setup of the server, and other factors. Some of these variables will not be available when PHP is run on the command line. For a listing of these variables, please see the section on Reserved Predefined Variables.
| Внимание |
In PHP 4.2.0 and later, the default value for the PHP directive register_globals is off. This is a major change in PHP. Having register_globals off affects the set of predefined variables available in the global scope. For example, to get DOCUMENT_ROOT you'll use $_SERVER['DOCUMENT_ROOT'] instead of $DOCUMENT_ROOT, or $_GET['id'] from the URL http://www.example.com/test.php?id=3 instead of $id, or $_ENV['HOME'] instead of $HOME. For related information on this change, read the configuration entry for register_globals, the security chapter on Using Register Globals , as well as the PHP 4.1.0 and 4.2.0 Release Announcements. Using the available PHP Reserved Predefined Variables, like the superglobal arrays, is preferred. |
From version 4.1.0 onward, PHP provides an additional set of predefined arrays containing variables from the web server (if applicable), the environment, and user input. These new arrays are rather special in that they are automatically global--i.e., automatically available in every scope. For this reason, they are often known as 'autoglobals' or 'superglobals'. (There is no mechanism in PHP for user-defined superglobals.) The superglobals are listed below; however, for a listing of their contents and further discussion on PHP predefined variables and their natures, please see the section Reserved Predefined Variables. Also, you'll notice how the older predefined variables ($HTTP_*_VARS) still exist.
Variable variables: Superglobals cannot be used as variable variables.
If certain variables in variables_order are not set, their appropriate PHP predefined arrays are also left empty.
PHP Superglobals
Contains a reference to every variable which is currently available within the global scope of the script. The keys of this array are the names of the global variables. $GLOBALS has existed since PHP 3.
Variables set by the web server or otherwise directly related to the execution environment of the current script. Analogous to the old $HTTP_SERVER_VARS array (which is still available, but deprecated).
Variables provided to the script via HTTP GET. Analogous to the old $HTTP_GET_VARS array (which is still available, but deprecated).
Variables provided to the script via HTTP POST. Analogous to the old $HTTP_POST_VARS array (which is still available, but deprecated).
Variables provided to the script via HTTP cookies. Analogous to the old $HTTP_COOKIE_VARS array (which is still available, but deprecated).
Variables provided to the script via HTTP post file uploads. Analogous to the old $HTTP_POST_FILES array (which is still available, but deprecated). See POST method uploads for more information.
Variables provided to the script via the environment. Analogous to the old $HTTP_ENV_VARS array (which is still available, but deprecated).
Variables provided to the script via any user input mechanism, and which therefore cannot be trusted. The presence and order of variable inclusion in this array is defined according to the variables_order configuration directive. This array has no direct analogue in versions of PHP prior to 4.1.0. See also import_request_variables().
Замечание: When running on the command line , this will not include the argv and argc entries; these are present in the $_SERVER array.
Variables which are currently registered to a script's session. Analogous to the old $HTTP_SESSION_VARS array (which is still available, but deprecated). See the Session handling functions section for more information.
The scope of a variable is the context within which it is defined. For the most part all PHP variables only have a single scope. This single scope spans included and required files as well. For example:
Here the $a variable will be available within the included b.inc script. However, within user-defined functions a local function scope is introduced. Any variable used inside a function is by default limited to the local function scope. For example:
<?php
$a = 1; /* global scope */
function Test()
{
echo $a; /* reference to local scope variable */
}
Test();
?> |
This script will not produce any output because the echo statement refers to a local version of the $a variable, and it has not been assigned a value within this scope. You may notice that this is a little bit different from the C language in that global variables in C are automatically available to functions unless specifically overridden by a local definition. This can cause some problems in that people may inadvertently change a global variable. In PHP global variables must be declared global inside a function if they are going to be used in that function. An example:
The above script will output "3". By declaring $a and $b global within the function, all references to either variable will refer to the global version. There is no limit to the number of global variables that can be manipulated by a function.
A second way to access variables from the global scope is to use the special PHP-defined $GLOBALS array. The previous example can be rewritten as:
<?php
$a = 1;
$b = 2;
function Sum()
{
$GLOBALS["b"] = $GLOBALS["a"] + $GLOBALS["b"];
}
Sum();
echo $b;
?> |
The $GLOBALS array is an associative array with the name of the global variable being the key and the contents of that variable being the value of the array element. Notice how $GLOBALS exists in any scope, this is because $GLOBALS is a superglobal. Here's an example demonstrating the power of superglobals:
<?php
function test_global()
{
// Most predefined variables aren't "super" and require
// 'global' to be available to the functions local scope.
global $HTTP_POST_VARS;
print $HTTP_POST_VARS['name'];
// Superglobals are available in any scope and do
// not require 'global'. Superglobals are available
// as of PHP 4.1.0
print $_POST['name'];
}
?> |
Another important feature of variable scoping is the static variable. A static variable exists only in a local function scope, but it does not lose its value when program execution leaves this scope. Consider the following example:
This function is quite useless since every time it is called it sets $a to 0 and prints "0". The $a++ which increments the variable serves no purpose since as soon as the function exits the $a variable disappears. To make a useful counting function which will not lose track of the current count, the $a variable is declared static:
Now, every time the Test() function is called it will print the value of $a and increment it.
Static variables also provide one way to deal with recursive functions. A recursive function is one which calls itself. Care must be taken when writing a recursive function because it is possible to make it recurse indefinitely. You must make sure you have an adequate way of terminating the recursion. The following simple function recursively counts to 10, using the static variable $count to know when to stop:
<?php
function Test()
{
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
Test ();
}
$count--;
}
?> |
The Zend Engine 1, driving PHP4, implements the static and global modifier for variables in terms of references. For example, a true global variable imported inside a function scope with the global statement actually creates a reference to the global variable. This can lead to unexpected behaviour which the following example addresses:
<?php
function test_global_ref() {
global $obj;
$obj = &new stdclass;
}
function test_global_noref() {
global $obj;
$obj = new stdclass;
}
test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?> |
Executing this example will result in the following output:
NULL
object(stdClass)(0) {
} |
A similar behaviour applies to the static statement. References are not stored statically:
<?php
function &get_instance_ref() {
static $obj;
echo "Static object: ";
var_dump($obj);
if (!isset($obj)) {
// Assign a reference to the static variable
$obj = &new stdclass;
}
$obj->property++;
return $obj;
}
function &get_instance_noref() {
static $obj;
echo "Static object: ";
var_dump($obj);
if (!isset($obj)) {
// Assign the object to the static variable
$obj = new stdclass;
}
$obj->property++;
return $obj;
}
$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();
?> |
Executing this example will result in the following output:
Static object: NULL
Static object: NULL
Static object: NULL
Static object: object(stdClass)(1) {
["property"]=>
int(1)
} |
This example demonstrates that when assigning a reference to a static variable, it's not remembered when you call the &get_instance_ref() function a second time.
Sometimes it is convenient to be able to have variable variable names. That is, a variable name which can be set and used dynamically. A normal variable is set with a statement such as:
A variable variable takes the value of a variable and treats that as the name of a variable. In the above example, hello, can be used as the name of a variable by using two dollar signs. i.e.
At this point two variables have been defined and stored in the PHP symbol tree: $a with contents "hello" and $hello with contents "world". Therefore, this statement:
produces the exact same output as:
i.e. they both produce: hello world.
In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second.
| Внимание |
Please note that variable variables cannot be used with PHP's Superglobal arrays. This means you cannot do things like ${$_GET}. If you are looking for a way to handle availability of superglobals and the old HTTP_*_VARS, you might want to try referencing them. |
When a form is submitted to a PHP script, the information from that form is automatically made available to the script. There are many ways to access this information, for example:
Depending on your particular setup and personal preferences, there are many ways to access data from your HTML forms. Some examples are:
Пример 8-2. Accessing data from a simple POST HTML form
|
Using a GET form is similar except you'll use the appropriate GET predefined variable instead. GET also applies to the QUERY_STRING (the information after the '?' in an URL). So, for example, http://www.example.com/test.php?id=3 contains GET data which is accessible with $_GET['id']. See also $_REQUEST and import_request_variables().
Замечание: Superglobal arrays, like $_POST and $_GET, became available in PHP 4.1.0
As shown, before PHP 4.2.0 the default value for register_globals was on. And, in PHP 3 it was always on. The PHP community is encouraging all to not rely on this directive as it's preferred to assume it's off and code accordingly.
Замечание: The magic_quotes_gpc configuration directive affects Get, Post and Cookie values. If turned on, value (It's "PHP!") will automagically become (It\'s \"PHP!\"). Escaping is needed for DB insertion. See also addslashes(), stripslashes() and magic_quotes_sybase.
PHP also understands arrays in the context of form variables (see the related faq). You may, for example, group related variables together, or use this feature to retrieve values from a multiple select input. For example, let's post a form to itself and upon submission display the data:
Пример 8-3. More complex form variables
|
In PHP 3, the array form variable usage is limited to single-dimensional arrays. In PHP 4, no such restriction applies.
When submitting a form, it is possible to use an image instead of the standard submit button with a tag like:
When the user clicks somewhere on the image, the accompanying form will be transmitted to the server with two additional variables, sub_x and sub_y. These contain the coordinates of the user click within the image. The experienced may note that the actual variable names sent by the browser contains a period rather than an underscore, but PHP converts the period to an underscore automatically.
PHP transparently supports HTTP cookies as defined by Netscape's Spec. Cookies are a mechanism for storing data in the remote browser and thus tracking or identifying return users. You can set cookies using the setcookie() function. Cookies are part of the HTTP header, so the SetCookie function must be called before any output is sent to the browser. This is the same restriction as for the header() function. Cookie data is then available in the appropriate cookie data arrays, such as $_COOKIE, $HTTP_COOKIE_VARS as well as in $_REQUEST. See the setcookie() manual page for more details and examples.
If you wish to assign multiple values to a single cookie variable, you may assign it as an array. For example:
<?php
setcookie("MyCookie[foo]", "Testing 1", time()+3600);
setcookie("MyCookie[bar]", "Testing 2", time()+3600);
?> |
That will create two seperate cookies although MyCookie will now be a single array in your script. If you want to set just one cookie with multiple values, consider using serialize() or explode() on the value first.
Note that a cookie will replace a previous cookie by the same name in your browser unless the path or domain is different. So, for a shopping cart application you may want to keep a counter and pass this along. i.e.
Пример 8-4. A setcookie() example
|
Typically, PHP does not alter the names of variables when they are passed into a script. However, it should be noted that the dot (period, full stop) is not a valid character in a PHP variable name. For the reason, look at it:
<?php $varname.ext; /* invalid variable name */ ?> |
For this reason, it is important to note that PHP will automatically replace any dots in incoming variable names with underscores.
Because PHP determines the types of variables and converts them (generally) as needed, it is not always obvious what type a given variable is at any one time. PHP includes several functions which find out what type a variable is, such as: gettype(), is_array(), is_float(), is_int(), is_object(), and is_string(). See also the chapter on Types.
A constant is an identifier (name) for a simple value. As the name suggests, that value cannot change during the execution of the script (except for magic constants, which aren't actually constants). A constant is case-sensitive by default. By convention, constant identifiers are always uppercase.
The name of a constant follows the same rules as any label in PHP. A valid constant name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thusly: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
Замечание: For our purposes here, a letter is a-z, A-Z, and the ASCII characters from 127 through 255 (0x7f-0xff).
Like superglobals, the scope of a constant is global. You can access constants anywhere in your script without regard to scope. For more information on scope, read the manual section on variable scope.
You can define a constant by using the define()-function. Once a constant is defined, it can never be changed or undefined.
Only scalar data (boolean, integer, float and string) can be contained in constants.
You can get the value of a constant by simply specifying its name. Unlike with variables, you should not prepend a constant with a $. You can also use the function constant() to read a constant's value if you wish to obtain the constant's name dynamically. Use get_defined_constants() to get a list of all defined constants.
Замечание: Constants and (global) variables are in a different namespace. This implies that for example TRUE and $TRUE are generally different.
If you use an undefined constant, PHP assumes that you mean the name of the constant itself. A notice will be issued when this happens. Use the defined()-function if you want to know if a constant is set.
These are the differences between constants and variables:
Constants do not have a dollar sign ($) before them;
Constants may only be defined using the define() function, not by simple assignment;
Constants may be defined and accessed anywhere without regard to variable scoping rules;
Constants may not be redefined or undefined once they have been set; and
Constants may only evaluate to scalar values.
PHP provides a large number of predefined constants to any script which it runs. Many of these constants, however, are created by various extensions, and will only be present when those extensions are available, either via dynamic loading or because they have been compiled in.
There are four magical constants that change depending on where they are used. For example, the value of __LINE__ depends on the line that it's used on in your script. These special constants are case-insensitive and are as follows:
Таблица 9-1. A few "magical" PHP constants
| Name | Description |
|---|---|
| __LINE__ | The current line number of the file. |
| __FILE__ | The full path and filename of the file. |
| __FUNCTION__ | The function name. (This was added in PHP 4.3.0.) |
| __CLASS__ | The class name. (This was added in PHP 4.3.0.) |
A list of predefined constants is available in the reserved predefined constants section.
Expressions are the most important building stones of PHP. In PHP, almost anything you write is an expression. The simplest yet most accurate way to define an expression is "anything that has a value".
The most basic forms of expressions are constants and variables. When you type "$a = 5", you're assigning '5' into $a. '5', obviously, has the value 5, or in other words '5' is an expression with the value of 5 (in this case, '5' is an integer constant).
After this assignment, you'd expect $a's value to be 5 as well, so if you wrote $b = $a, you'd expect it to behave just as if you wrote $b = 5. In other words, $a is an expression with the value of 5 as well. If everything works right, this is exactly what will happen.
Slightly more complex examples for expressions are functions. For instance, consider the following function:
Assuming you're familiar with the concept of functions (if you're not, take a look at the chapter about functions), you'd assume that typing $c = foo() is essentially just like writing $c = 5, and you're right. Functions are expressions with the value of their return value. Since foo() returns 5, the value of the expression 'foo()' is 5. Usually functions don't just return a static value but compute something.
Of course, values in PHP don't have to be integers, and very often they aren't. PHP supports three scalar value types: integer values, floating point values and string values (scalar values are values that you can't 'break' into smaller pieces, unlike arrays, for instance). PHP also supports two composite (non-scalar) types: arrays and objects. Each of these value types can be assigned into variables or returned from functions.
So far, users of PHP/FI 2 shouldn't feel any change. However, PHP takes expressions much further, in the same way many other languages do. PHP is an expression-oriented language, in the sense that almost everything is an expression. Consider the example we've already dealt with, '$a = 5'. It's easy to see that there are two values involved here, the value of the integer constant '5', and the value of $a which is being updated to 5 as well. But the truth is that there's one additional value involved here, and that's the value of the assignment itself. The assignment itself evaluates to the assigned value, in this case 5. In practice, it means that '$a = 5', regardless of what it does, is an expression with the value 5. Thus, writing something like '$b = ($a = 5)' is like writing '$a = 5; $b = 5;' (a semicolon marks the end of a statement). Since assignments are parsed in a right to left order, you can also write '$b = $a = 5'.
Another good example of expression orientation is pre- and post-increment and decrement. Users of PHP/FI 2 and many other languages may be familiar with the notation of variable++ and variable--. These are increment and decrement operators. In PHP/FI 2, the statement '$a++' has no value (is not an expression), and thus you can't assign it or use it in any way. PHP enhances the increment/decrement capabilities by making these expressions as well, like in C. In PHP, like in C, there are two types of increment - pre-increment and post-increment. Both pre-increment and post-increment essentially increment the variable, and the effect on the variable is idential. The difference is with the value of the increment expression. Pre-increment, which is written '++$variable', evaluates to the incremented value (PHP increments the variable before reading its value, thus the name 'pre-increment'). Post-increment, which is written '$variable++' evaluates to the original value of $variable, before it was incremented (PHP increments the variable after reading its value, thus the name 'post-increment').
A very common type of expressions are comparison expressions. These expressions evaluate to either 0 or 1, meaning FALSE or TRUE (respectively). PHP supports > (bigger than), >= (bigger than or equal to), == (equal), != (not equal), < (smaller than) and <= (smaller than or equal to). These expressions are most commonly used inside conditional execution, such as if statements.
The last example of expressions we'll deal with here is combined operator-assignment expressions. You already know that if you want to increment $a by 1, you can simply write '$a++' or '++$a'. But what if you want to add more than one to it, for instance 3? You could write '$a++' multiple times, but this is obviously not a very efficient or comfortable way. A much more common practice is to write '$a = $a + 3'. '$a + 3' evaluates to the value of $a plus 3, and is assigned back into $a, which results in incrementing $a by 3. In PHP, as in several other languages like C, you can write this in a shorter way, which with time would become clearer and quicker to understand as well. Adding 3 to the current value of $a can be written '$a += 3'. This means exactly "take the value of $a, add 3 to it, and assign it back into $a". In addition to being shorter and clearer, this also results in faster execution. The value of '$a += 3', like the value of a regular assignment, is the assigned value. Notice that it is NOT 3, but the combined value of $a plus 3 (this is the value that's assigned into $a). Any two-place operator can be used in this operator-assignment mode, for example '$a -= 5' (subtract 5 from the value of $a), '$b *= 7' (multiply the value of $b by 7), etc.
There is one more expression that may seem odd if you haven't seen it in other languages, the ternary conditional operator:
If the value of the first subexpression is TRUE (non-zero), then the second subexpression is evaluated, and that is the result of the conditional expression. Otherwise, the third subexpression is evaluated, and that is the value.The following example should help you understand pre- and post-increment and expressions in general a bit better:
function double($i)
{
return $i*2;
}
$b = $a = 5; /* assign the value five into the variable $a and $b */
$c = $a++; /* post-increment, assign original value of $a
(5) to $c */
$e = $d = ++$b; /* pre-increment, assign the incremented value of
$b (6) to $d and $e */
/* at this point, both $d and $e are equal to 6 */
$f = double($d++); /* assign twice the value of $d <emphasis>before</emphasis>
the increment, 2*6 = 12 to $f */
$g = double(++$e); /* assign twice the value of $e <emphasis>after</emphasis>
the increment, 2*7 = 14 to $g */
$h = $g += 10; /* first, $g is incremented by 10 and ends with the
value of 24. the value of the assignment (24) is
then assigned into $h, and $h ends with the value
of 24 as well. */ |
In the beginning of the chapter we said that we'll be describing the various statement types, and as promised, expressions can be statements. However, not every expression is a statement. In this case, a statement has the form of 'expr' ';' that is, an expression followed by a semicolon. In '$b=$a=5;', $a=5 is a valid expression, but it's not a statement by itself. '$b=$a=5;' however is a valid statement.
One last thing worth mentioning is the truth value of expressions. In many events, mainly in conditional execution and loops, you're not interested in the specific value of the expression, but only care about whether it means TRUE or FALSE. The constants TRUE and FALSE (case-insensitive) are the two possible boolean values. When necessary, an expression is automatically converted to boolean. See the section about type-casting for details about how.
PHP provides a full and powerful implementation of expressions, and documenting it entirely goes beyond the scope of this manual. The above examples should give you a good idea about what expressions are and how you can construct useful expressions. Throughout the rest of this manual we'll write expr to indicate any valid PHP expression.
The precedence of an operator specifies how "tightly" it binds two expressions together. For example, in the expression 1 + 5 * 3, the answer is 16 and not 18 because the multiplication ("*") operator has a higher precedence than the addition ("+") operator. Parentheses may be used to force precedence, if necessary. For instance: (1 + 5) * 3 evaluates to 18.
The following table lists the precedence of operators with the lowest-precedence operators listed first.
Таблица 11-1. Operator Precedence
| Associativity | Operators |
|---|---|
| left | , |
| left | or |
| left | xor |
| left | and |
| right | |
| left | = += -= *= /= .= %= &= |= ^= <<= >>= |
| left | ? : |
| left | || |
| left | && |
| left | | |
| left | ^ |
| left | & |
| non-associative | == != === !== |
| non-associative | < <= > >= |
| left | << >> |
| left | + - . |
| left | * / % |
| right | ! ~ ++ -- (int) (float) (string) (array) (object) @ |
| right | [ |
| non-associative | new |
Замечание: Although ! has a higher precedence than =, PHP will still allow expressions similar to the following: if (!$a = foo()), in which case the output from foo() is put into $a.
Remember basic arithmetic from school? These work just like those.
Таблица 11-2. Arithmetic Operators
| Example | Name | Result |
|---|---|---|
| $a + $b | Addition | Sum of $a and $b. |
| $a - $b | Subtraction | Difference of $a and $b. |
| $a * $b | Multiplication | Product of $a and $b. |
| $a / $b | Division | Quotient of $a and $b. |
| $a % $b | Modulus | Remainder of $a divided by $b. |
The division operator ("/") returns a float value anytime, even if the two operands are integers (or strings that get converted to integers).
See also the manual page on Math functions.
The basic assignment operator is "=". Your first inclination might be to think of this as "equal to". Don't. It really means that the the left operand gets set to the value of the expression on the rights (that is, "gets set to").
The value of an assignment expression is the value assigned. That is, the value of "$a = 3" is 3. This allows you to do some tricky things:
In addition to the basic assignment operator, there are "combined operators" for all of the binary arithmetic and string operators that allow you to use a value in an expression and then set its value to the result of that expression. For example:
$a = 3; $a += 5; // sets $a to 8, as if we had said: $a = $a + 5; $b = "Hello "; $b .= "There!"; // sets $b to "Hello There!", just like $b = $b . "There!"; |
Note that the assignment copies the original variable to the new one (assignment by value), so changes to one will not affect the other. This may also have relevance if you need to copy something like a large array inside a tight loop. PHP 4 supports assignment by reference, using the $var = &$othervar; syntax, but this is not possible in PHP 3. 'Assignment by reference' means that both variables end up pointing at the same data, and nothing is copied anywhere. To learn more about references, please read References explained.
Bitwise operators allow you to turn specific bits within an integer on or off. If both the left- and right-hand parameters are strings, the bitwise operator will operate on the characters in this string.
<?php
echo 12 ^ 9; // Outputs '5'
echo "12" ^ "9"; // Outputs the Backspace character (ascii 8)
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
echo "hallo" ^ "hello"; // Outputs the ascii values #0 #4 #0 #0 #0
// 'a' ^ 'e' = #4
?> |
Таблица 11-3. Bitwise Operators
| Example | Name | Result |
|---|---|---|
| $a & $b | And | Bits that are set in both $a and $b are set. |
| $a | $b | Or | Bits that are set in either $a or $b are set. |
| $a ^ $b | Xor | Bits that are set in $a or $b but not both are set. |
| ~ $a | Not | Bits that are set in $a are not set, and vice versa. |
| $a << $b | Shift left | Shift the bits of $a $b steps to the left (each step means "multiply by two") |
| $a >> $b | Shift right | Shift the bits of $a $b steps to the right (each step means "divide by two") |
Comparison operators, as their name implies, allow you to compare two values.
Таблица 11-4. Comparison Operators
| Example | Name | Result |
|---|---|---|
| $a == $b | Equal | TRUE if $a is equal to $b. |
| $a === $b | Identical | TRUE if $a is equal to $b, and they are of the same type. (PHP 4 only) |
| $a != $b | Not equal | TRUE if $a is not equal to $b. |
| $a <> $b | Not equal | TRUE if $a is not equal to $b. |
| $a !== $b | Not identical | TRUE if $a is not equal to $b, or they are not of the same type. (PHP 4 only) |
| $a < $b | Less than | TRUE if $a is strictly less than $b. |
| $a > $b | Greater than | TRUE if $a is strictly greater than $b. |
| $a <= $b | Less than or equal to | TRUE if $a is less than or equal to $b. |
| $a >= $b | Greater than or equal to | TRUE if $a is greater than or equal to $b. |
Another conditional operator is the "?:" (or ternary) operator, which operates as in C and many other languages.
<?php
// Example usage for: Ternary Operator
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
// The above is identical to this if/else statement
if (empty($_POST['action'])) {
$action = 'default';
} else {
$action = $_POST['action'];
}
?> |
See also strcasecmp(), strcmp(), and the manual section on Types.
PHP supports one error control operator: the at sign (@). When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored.
If the track_errors feature is enabled, any error message generated by the expression will be saved in the variable $php_errormsg. This variable will be overwritten on each error, so check early if you want to use it.
<?php
/* Intentional file error */
$my_file = @file ('non_existent_file') or
die ("Failed opening file: error was '$php_errormsg'");
// this works for any expression, not just functions:
$value = @$cache[$key];
// will not issue a notice if the index $key doesn't exist.
?> |
Замечание: The @-operator works only on expressions. A simple rule of thumb is: if you can take the value of something, you can prepend the @ operator to it. For instance, you can prepend it to variables, function and include() calls, constants, and so forth. You cannot prepend it to function or class definitions, or conditional structures such as if and foreach, and so forth.
See also error_reporting() and the manual section for Error Handling and Logging functions.
Замечание: The "@" error-control operator prefix will not disable messages that are the result of parse errors.
| Внимание |
Currently the "@" error-control operator prefix will even disable error reporting for critical errors that will terminate script execution. Among other things, this means that if you use "@" to suppress errors from a certain function and either it isn't available or has been mistyped, the script will die right there with no indication as to why. |
PHP supports one execution operator: backticks (``). Note that these are not single-quotes! PHP will attempt to execute the contents of the backticks as a shell command; the output will be returned (i.e., it won't simply be dumped to output; it can be assigned to a variable). Use of the backtick operator is identical to shell_exec().
Замечание: The backtick operator is disabled when safe mode is enabled or shell_exec() is disabled.
See also the manual section on Program Execution functions, popen() proc_open(), and Using PHP from the commandline.
PHP supports C-style pre- and post-increment and decrement operators.
Таблица 11-5. Increment/decrement Operators
| Example | Name | Effect |
|---|---|---|
| ++$a | Pre-increment | Increments $a by one, then returns $a. |
| $a++ | Post-increment | Returns $a, then increments $a by one. |
| --$a | Pre-decrement | Decrements $a by one, then returns $a. |
| $a-- | Post-decrement | Returns $a, then decrements $a by one. |
Here's a simple example script:
<?php echo "<h3>Postincrement</h3>"; $a = 5; echo "Should be 5: " . $a++ . "<br />\n"; echo "Should be 6: " . $a . "<br />\n"; echo "<h3>Preincrement</h3>"; $a = 5; echo "Should be 6: " . ++$a . "<br />\n"; echo "Should be 6: " . $a . "<br />\n"; echo "<h3>Postdecrement</h3>"; $a = 5; echo "Should be 5: " . $a-- . "<br />\n"; echo "Should be 4: " . $a . "<br />\n"; echo "<h3>Predecrement</h3>"; $a = 5; echo "Should be 4: " . --$a . "<br />\n"; echo "Should be 4: " . $a . "<br />\n"; ?> |
PHP follows Perl's convention when dealing with arithmetic operations on character variables and not C's. For example, in Perl 'Z'+1 turns into 'AA', while in C 'Z'+1 turns into '[' ( ord('Z') == 90, ord('[') == 91 ). Note that character variables can be incremented but not decremented.
Таблица 11-6. Logical Operators
| Example | Name | Result |
|---|---|---|
| $a and $b | And | TRUE if both $a and $b are TRUE. |
| $a or $b | Or | TRUE if either $a or $b is TRUE. |
| $a xor $b | Xor | TRUE if either $a or $b is TRUE, but not both. |
| ! $a | Not | TRUE if $a is not TRUE. |
| $a && $b | And | TRUE if both $a and $b are TRUE. |
| $a || $b | Or | TRUE if either $a or $b is TRUE. |
The reason for the two different variations of "and" and "or" operators is that they operate at different precedences. (See Operator Precedence.)
There are two string operators. The first is the concatenation operator ('.'), which returns the concatenation of its right and left arguments. The second is the concatenating assignment operator ('.='), which appends the argument on the right side to the argument on the left side. Please read Assignment Operators for more information.
$a = "Hello "; $b = $a . "World!"; // now $b contains "Hello World!" $a = "Hello "; $a .= "World!"; // now $a contains "Hello World!" |
See also the manual sections on the String type and String functions.
The only array operator in PHP is the + operator. It appends the right handed array to the left handed, whereas duplicated keys are NOT overwritten.
$a = array("a" => "apple", "b" => "banana");
$b = array("a" =>"pear", "b" => "strawberry", "c" => "cherry");
$c = $a + $b;
var_dump($c); |
array(3) {
["a"]=>
string(5) "apple"
["b"]=>
string(6) "banana"
["c"]=>
string(6) "cherry"
} |
See also the manual sections on the Array type and Array functions.
Any PHP script is built out of a series of statements. A statement can be an assignment, a function call, a loop, a conditional statement of even a statement that does nothing (an empty statement). Statements usually end with a semicolon. In addition, statements can be grouped into a statement-group by encapsulating a group of statements with curly braces. A statement-group is a statement by itself as well. The various statement types are described in this chapter.
The if construct is one of the most important features of many languages, PHP included. It allows for conditional execution of code fragments. PHP features an if structure that is similar to that of C:
As described in the section about expressions, expr is evaluated to its Boolean value. If expr evaluates to TRUE, PHP will execute statement, and if it evaluates to FALSE - it'll ignore it. More information about what values evaluate to FALSE can be found in the 'Converting to boolean' section.
The following example would display a is bigger than b if $a is bigger than $b:
Often you'd want to have more than one statement to be executed conditionally. Of course, there's no need to wrap each statement with an if clause. Instead, you can group several statements into a statement group. For example, this code would display a is bigger than b if $a is bigger than $b, and would then assign the value of $a into $b:
If statements can be nested indefinitely within other if statements, which provides you with complete flexibility for conditional execution of the various parts of your program.
Often you'd want to execute a statement if a certain condition is met, and a different statement if the condition is not met. This is what else is for. else extends an if statement to execute a statement in case the expression in the if statement evaluates to FALSE. For example, the following code would display a is bigger than b if $a is bigger than $b, and a is NOT bigger than b otherwise:
The else statement is only executed if the if expression evaluated to FALSE, and if there were any elseif expressions - only if they evaluated to FALSE as well (see elseif).elseif, as its name suggests, is a combination of if and else. Like else, it extends an if statement to execute a different statement in case the original if expression evaluates to FALSE. However, unlike else, it will execute that alternative expression only if the elseif conditional expression evaluates to TRUE. For example, the following code would display a is bigger than b, a equal to b or a is smaller than b:
if ($a > $b) {
print "a is bigger than b";
} elseif ($a == $b) {
print "a is equal to b";
} else {
print "a is smaller than b";
} |
There may be several elseifs within the same if statement. The first elseif expression (if any) that evaluates to TRUE would be executed. In PHP, you can also write 'else if' (in two words) and the behavior would be identical to the one of 'elseif' (in a single word). The syntactic meaning is slightly different (if you're familiar with C, this is the same behavior) but the bottom line is that both would result in exactly the same behavior.
The elseif statement is only executed if the preceding if expression and any preceding elseif expressions evaluated to FALSE, and the current elseif expression evaluated to TRUE.
PHP offers an alternative syntax for some of its control structures; namely, if, while, for, foreach, and switch. In each case, the basic form of the alternate syntax is to change the opening brace to a colon (:) and the closing brace to endif;, endwhile;, endfor;, endforeach;, or endswitch;, respectively.
In the above example, the HTML block "A is equal to 5" is nested within an if statement written in the alternative syntax. The HTML block would be displayed only if $a is equal to 5.
The alternative syntax applies to else and elseif as well. The following is an if structure with elseif and else in the alternative format:
while loops are the simplest type of loop in PHP. They behave just like their C counterparts. The basic form of a while statement is:
The meaning of a while statement is simple. It tells PHP to execute the nested statement(s) repeatedly, as long as the while expression evaluates to TRUE. The value of the expression is checked each time at the beginning of the loop, so even if this value changes during the execution of the nested statement(s), execution will not stop until the end of the iteration (each time PHP runs the statements in the loop is one iteration). Sometimes, if the while expression evaluates to FALSE from the very beginning, the nested statement(s) won't even be run once.
Like with the if statement, you can group multiple statements within the same while loop by surrounding a group of statements with curly braces, or by using the alternate syntax:
The following examples are identical, and both print numbers from 1 to 10:
do..while loops are very similar to while loops, except the truth expression is checked at the end of each iteration instead of in the beginning. The main difference from regular while loops is that the first iteration of a do..while loop is guaranteed to run (the truth expression is only checked at the end of the iteration), whereas it's may not necessarily run with a regular while loop (the truth expression is checked at the beginning of each iteration, if it evaluates to FALSE right from the beginning, the loop execution would end immediately).
There is just one syntax for do..while loops:
The above loop would run one time exactly, since after the first iteration, when truth expression is checked, it evaluates to FALSE ($i is not bigger than 0) and the loop execution ends.
Advanced C users may be familiar with a different usage of the do..while loop, to allow stopping execution in the middle of code blocks, by encapsulating them with do..while(0), and using the break statement. The following code fragment demonstrates this:
do {
if ($i < 5) {
print "i is not big enough";
break;
}
$i *= $factor;
if ($i < $minimum_limit) {
break;
}
print "i is ok";
...process i...
} while(0); |
Don't worry if you don't understand this right away or at all. You can code scripts and even powerful scripts without using this 'feature'.
for loops are the most complex loops in PHP. They behave like their C counterparts. The syntax of a for loop is:
The first expression (expr1) is evaluated (executed) once unconditionally at the beginning of the loop.
In the beginning of each iteration, expr2 is evaluated. If it evaluates to TRUE, the loop continues and the nested statement(s) are executed. If it evaluates to FALSE, the execution of the loop ends.
At the end of each iteration, expr3 is evaluated (executed).
Each of the expressions can be empty. expr2 being empty means the loop should be run indefinitely (PHP implicitly considers it as TRUE, like C). This may not be as useless as you might think, since often you'd want to end the loop using a conditional break statement instead of using the for truth expression.
Consider the following examples. All of them display numbers from 1 to 10:
/* example 1 */
for ($i = 1; $i <= 10; $i++) {
print $i;
}
/* example 2 */
for ($i = 1;;$i++) {
if ($i > 10) {
break;
}
print $i;
}
/* example 3 */
$i = 1;
for (;;) {
if ($i > 10) {
break;
}
print $i;
$i++;
}
/* example 4 */
for ($i = 1; $i <= 10; print $i, $i++); |
Of course, the first example appears to be the nicest one (or perhaps the fourth), but you may find that being able to use empty expressions in for loops comes in handy in many occasions.
PHP also supports the alternate "colon syntax" for for loops.
Other languages have a foreach statement to traverse an array or hash. PHP 3 has no such construct; PHP 4 does (see foreach). In PHP 3, you can combine while with the list() and each() functions to achieve the same effect. See the documentation for these functions for an example.
PHP 4 (not PHP 3) includes a foreach construct, much like Perl and some other languages. This simply gives an easy way to iterate over arrays. foreach works only on arrays, and will issue an error when you try to use it on a variable with a different data type or an uninitialized variables. There are two syntaxes; the second is a minor but useful extension of the first:
The first form loops over the array given by array_expression. On each loop, the value of the current element is assigned to $value and the internal array pointer is advanced by one (so on the next loop, you'll be looking at the next element).
The second form does the same thing, except that the current element's key will be assigned to the variable $key on each loop.
Замечание: When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset() before a foreach loop.
Замечание: Also note that foreach operates on a copy of the specified array, not the array itself, therefore the array pointer is not modified as with the each() construct and changes to the array element returned are not reflected in the original array. However, the internal pointer of the original array is advanced with the processing of the array. Assuming the foreach loop runs to completion, the array's internal pointer will be at the end of the array.
Замечание: foreach does not support the ability to suppress error messages using '@'.
You may have noticed that the following are functionally identical:
$arr = array("one", "two", "three");
reset ($arr);
while (list(, $value) = each ($arr)) {
echo "Value: $value<br>\n";
}
foreach ($arr as $value) {
echo "Value: $value<br>\n";
} |
reset ($arr);
while (list($key, $value) = each ($arr)) {
echo "Key: $key; Value: $value<br>\n";
}
foreach ($arr as $key => $value) {
echo "Key: $key; Value: $value<br>\n";
} |
Some more examples to demonstrate usages:
/* foreach example 1: value only */
$a = array (1, 2, 3, 17);
foreach ($a as $v) {
print "Current value of \$a: $v.\n";
}
/* foreach example 2: value (with key printed for illustration) */
$a = array (1, 2, 3, 17);
$i = 0; /* for illustrative purposes only */
foreach($a as $v) {
print "\$a[$i] => $v.\n";
$i++;
}
/* foreach example 3: key and value */
$a = array (
"one" => 1,
"two" => 2,
"three" => 3,
"seventeen" => 17
);
foreach($a as $k => $v) {
print "\$a[$k] => $v.\n";
}
/* foreach example 4: multi-dimensional arrays */
$a[0][0] = "a";
$a[0][1] = "b";
$a[1][0] = "y";
$a[1][1] = "z";
foreach($a as $v1) {
foreach ($v1 as $v2) {
print "$v2\n";
}
}
/* foreach example 5: dynamic arrays */
foreach(array(1, 2, 3, 4, 5) as $v) {
print "$v\n";
} |
break ends execution of the current for, foreach while, do..while or switch structure.
break accepts an optional numeric argument which tells it how many nested enclosing structures are to be broken out of.
$arr = array ('one', 'two', 'three', 'four', 'stop', 'five');
while (list (, $val) = each ($arr)) {
if ($val == 'stop') {
break; /* You could also write 'break 1;' here. */
}
echo "$val<br>\n";
}
/* Using the optional argument. */
$i = 0;
while (++$i) {
switch ($i) {
case 5:
echo "At 5<br>\n";
break 1; /* Exit only the switch. */
case 10:
echo "At 10; quitting<br>\n";
break 2; /* Exit the switch and the while. */
default:
break;
}
} |
continue is used within looping structures to skip the rest of the current loop iteration and continue execution at the beginning of the next iteration.
continue accepts an optional numeric argument which tells it how many levels of enclosing loops it should skip to the end of.
while (list ($key, $value) = each ($arr)) {
if (!($key % 2)) { // skip odd members
continue;
}
do_something_odd ($value);
}
$i = 0;
while ($i++ < 5) {
echo "Outer<br>\n";
while (1) {
echo " Middle<br>\n";
while (1) {
echo " Inner<br>\n";
continue 3;
}
echo "This never gets output.<br>\n";
}
echo "Neither does this.<br>\n";
} |
The switch statement is similar to a series of IF statements on the same expression. In many occasions, you may want to compare the same variable (or expression) with many different values, and execute a different piece of code depending on which value it equals to. This is exactly what the switch statement is for.
The following two examples are two different ways to write the same thing, one using a series of if statements, and the other using the switch statement:
if ($i == 0) {
print "i equals 0";
} elseif ($i == 1) {
print "i equals 1";
} elseif ($i == 2) {
print "i equals 2";
}
switch ($i) {
case 0:
print "i equals 0";
break;
case 1:
print "i equals 1";
break;
case 2:
print "i equals 2";
break;
} |
It is important to understand how the switch statement is executed in order to avoid mistakes. The switch statement executes line by line (actually, statement by statement). In the beginning, no code is executed. Only when a case statement is found with a value that matches the value of the switch expression does PHP begin to execute the statements. PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement. If you don't write a break statement at the end of a case's statement list, PHP will go on executing the statements of the following case. For example:
Here, if $i is equal to 0, PHP would execute all of the print statements! If $i is equal to 1, PHP would execute the last two print statements. You would get the expected behavior ('i equals 2' would be displayed) only if $i is equal to 2. Thus, it is important not to forget break statements (even though you may want to avoid supplying them on purpose under certain circumstances).
In a switch statement, the condition is evaluated only once and the result is compared to each case statement. In an elseif statement, the condition is evaluated again. If your condition is more complicated than a simple compare and/or is in a tight loop, a switch may be faster.
The statement list for a case can also be empty, which simply passes control into the statement list for the next case.
switch ($i) {
case 0:
case 1:
case 2:
print "i is less than 3 but not negative";
break;
case 3:
print "i is 3";
} |
A special case is the default case. This case matches anything that wasn't matched by the other cases, and should be the last case statement. For example:
switch ($i) {
case 0:
print "i equals 0";
break;
case 1:
print "i equals 1";
break;
case 2:
print "i equals 2";
break;
default:
print "i is not equal to 0, 1 or 2";
} |
The case expression may be any expression that evaluates to a simple type, that is, integer or floating-point numbers and strings. Arrays or objects cannot be used here unless they are dereferenced to a simple type.
The alternative syntax for control structures is supported with switches. For more information, see Alternative syntax for control structures .
The declare construct is used to set execution directives for a block of code. The syntax of declare is similar to the syntax of other flow control constructs:
The directive section allows the behavior of the declare block to be set. Currently only one directive is recognized: the ticks directive. (See below for more information on the ticks directive)
The statement part of the declare block will be executed -- how it is executed and what side effects occur during execution may depend on the directive set in the directive block.
A tick is an event that occurs for every N low-level statements executed by the parser within the declare block. The value for N is specified using ticks=N within the declare blocks's directive section.
The event(s) that occur on each tick are specified using the register_tick_function(). See the example below for more details. Note that more than one event can occur for each tick.
Пример 12-1. Profile a section of PHP code
|
Ticks are well suited for debugging, implementing simple multitasking, backgrounded I/O and many other tasks.
See also register_tick_function() and unregister_tick_function().
If called from within a function, the return() statement immediately ends execution of the current function, and returns its argument as the value of the function call. return() will also end the execution of an eval() statement or script file.
If called from the global scope, then execution of the current script file is ended. If the current script file was include()ed or require()ed, then control is passed back to the calling file. Furthermore, if the current script file was include()ed, then the value given to return() will be returned as the value of the include() call. If return() is called from within the main script file, then script execution ends. If the current script file was named by the auto_prepend_file or auto_append_file configuration options in php.ini, then that script file's execution is ended.
For more information, see Returning values.
Замечание: Note that since return() is a language construct and not a function, the parentheses surrounding its arguments are not required--in fact, it is more common to leave them out than to use them, although it doesn't matter one way or the other.
The require() statement includes and evaluates the specific file.
require() includes and evaluates a specific file. Detailed information on how this inclusion works is described in the documentation for include().
require() and include() are identical in every way except how they handle failure. include() produces a Warning while require() results in a Fatal Error. In other words, don't hesitate to use require() if you want a missing file to halt processing of the page. include() does not behave this way, the script will continue regardless. Be sure to have an appropriate include_path setting as well.
Пример 12-2. Basic require() examples
|
See the include() documentation for more examples.
Замечание: Prior to PHP 4.0.2, the following applies: require() will always attempt to read the target file, even if the line it's on never executes. The conditional statement won't affect require(). However, if the line on which the require() occurs is not executed, neither will any of the code in the target file be executed. Similarly, looping structures do not affect the behaviour of require(). Although the code contained in the target file is still subject to the loop, the require() itself happens only once.
| Внимание |
В настоящее время версия PHP для Windows не поддерживает возможность использования удаленных файлов этой функцией даже в том случае, если включена опция allow_url_fopen. |
See also include(), require_once(), include_once(), eval(), file(), readfile(), virtual() and include_path.
The include() statement includes and evaluates the specified file.
The documentation below also applies to require(). The two constructs are identical in every way except how they handle failure. include() produces a Warning while require() results in a Fatal Error. In other words, use require() if you want a missing file to halt processing of the page. include() does not behave this way, the script will continue regardless. Be sure to have an appropriate include_path setting as well.
When a file is included, the code it contains inherits the variable scope of the line on which the include occurs. Any variables available at that line in the calling file will be available within the called file, from that point forward.
Пример 12-3. Basic include() example
|
If the include occurs inside a function within the calling file, then all of the code contained in the called file will behave as though it had been defined inside that function. So, it will follow the variable scope of that function.
Пример 12-4. Including within functions
|
When a file is included, parsing drops out of PHP mode and into HTML mode at the beginning of the target file, and resumes again at the end. For this reason, any code inside the target file which should be executed as PHP code must be enclosed within valid PHP start and end tags.
If "URL fopen wrappers" are enabled in PHP (which they are in the default configuration), you can specify the file to be included using an URL (via HTTP or other supported wrapper - see Прил. I for a list of protocols) instead of a local pathname. If the target server interprets the target file as PHP code, variables may be passed to the included file using an URL request string as used with HTTP GET. This is not strictly speaking the same thing as including the file and having it inherit the parent file's variable scope; the script is actually being run on the remote server and the result is then being included into the local script.
| Внимание |
В настоящее время версия PHP для Windows не поддерживает возможность использования удаленных файлов этой функцией даже в том случае, если включена опция allow_url_fopen. |
Пример 12-5. include() through HTTP
|
Because include() and require() are special language constructs, you must enclose them within a statement block if it's inside a conditional block.
Handling Returns: It is possible to execute a return() statement inside an included file in order to terminate processing in that file and return to the script which called it. Also, it's possible to return values from included files. You can take the value of the include call as you would a normal function.
Замечание: In PHP 3, the return may not appear inside a block unless it's a function block, in which case the return() applies to that function and not the whole file.
$bar is the value 1 because the include was successful. Notice the difference between the above examples. The first uses return() within the included file while the other does not. A few other ways to "include" files into variables are with fopen(), file() or by using include() along with Output Control Functions.
See also require(), require_once(), include_once(), readfile(), virtual(), and include_path.
The require_once() statement includes and evaluates the specified file during the execution of the script. This is a behavior similar to the require() statement, with the only difference being that if the code from a file has already been included, it will not be included again. See the documentation for require() for more information on how this statement works.
require_once() should be used in cases where the same file might be included and evaluated more than once during a particular execution of a script, and you want to be sure that it is included exactly once to avoid problems with function redefinitions, variable value reassignments, etc.
For examples on using require_once() and include_once(), look at the PEAR code included in the latest PHP source code distributions.
Замечание: require_once() was added in PHP 4.0.1pl2
Замечание: Be aware, that the behaviour of require_once() and include_once() may not be what you expect on a non case sensitive operating system (such as Windows).
Пример 12-8. require_once() is case sensitive
require_once("a.php"); // this will include a.php require_once("A.php"); // this will include a.php again on Windows!
| Внимание |
В настоящее время версия PHP для Windows не поддерживает возможность использования удаленных файлов этой функцией даже в том случае, если включена опция allow_url_fopen. |
See also: require(), include(), include_once(), get_required_files(), get_included_files(), readfile(), and virtual().
The include_once() statement includes and evaluates the specified file during the execution of the script. This is a behavior similar to the include() statement, with the only difference being that if the code from a file has already been included, it will not be included again. As the name suggests, it will be included just once.
include_once() should be used in cases where the same file might be included and evaluated more than once during a particular execution of a script, and you want to be sure that it is included exactly once to avoid problems with function redefinitions, variable value reassignments, etc.
For more examples on using require_once() and include_once(), look at the PEAR code included in the latest PHP source code distributions.
Замечание: include_once() was added in PHP 4.0.1pl2
Замечание: Be aware, that the behaviour of include_once() and require_once() may not be what you expect on a non case sensitive operating system (such as Windows).
Пример 12-9. include_once() is case sensitive
include_once("a.php"); // this will include a.php include_once("A.php"); // this will include a.php again on Windows!