РНР 5 в подлиннике

Страница 243 из 554


Глава 25. Работа с HTTP и WWW

491

Однако если сохраняемый массив имеет небольшой размер, каждый его элемент можно разместить в отдельном cookie:

setcookie("arr[0] ", "What was said was for you and for you alone."); setcookie("arr[1][0]", "Whoa, deja vu."); // многомерный массив, помните?

По сути, cookie с именем агг[0] ничем не отличается с точки зрения браузера и сервера от обычного cookie. Зато РНР, получив cookie с именем, содержащим квадратные скобки, поймет, что это на самом деле элемент массива, и создаст его (массив) как элементы $_cookie и $_request (в последний массив также попадут get- и post-данные):

echo "Значение первого элемента cookie: {$_cookie['arr1][0])<br>"; echo "{$_reqdest['arr'][1][0]) - What did you just say?";

Тут нет ничего удивительного — ведь РНР поступает точно так же и с переменными, поступившими из формы пользователя... Правда, в отличие от форм, не советуем вам особо увлекаться подобными cookies: дело в том, что в большинстве браузеров число cookies, которые могут быть установлены одним сервером, ограничено, причем ограничено именно их количество, а не суммарный объем. Поэтому, наверное, лучше будет все-таки воспользоваться функцией serialize!) и установить один cookie, а еще лучше — написать собственную функцию сериализации, которая упаковывает данные чуть эффективнее.

Получение cookie

Давайте подведем итог. Предположим, сценарий отработал и установил какой-то cookie, например, с именем Hotel и значением Lafayette. В следующий раз при запуске этого сценария (на самом деле, и всех других сценариев, расположенных на том же сервере в том же каталоге или ниже по дереву) ему передастся пара типа Hotei=Lafayette (через специальную переменную окружения http_cookie). РНР это событие перехватит и автоматически создаст элемент в массивах $_cookie и $_reqdest. Его имя, как вы уже догадались, Hotel, а значение — Lafayette.

Если включен режим register_globals, cookie также проявит себя в виде глобальной переменной $Hotel со значением Lafayette.

Вы видите, что интерпретатор действует точно так же, как если бы значение нашего cookie пришло откуда-то из формы. Та переменная, которую мы установили в прошлый раз, будет доступна и сейчас!

Как известно, для одного и того же документа в Apache нельзя применять два "обработчика". Иными словами, действует принцип (по крайней мере, в Apache первого поколения): либо РНР, либо SSI (Server-Side Includes, включения на стороне сервера). Однако в РНР имеются определенные средства для "эмуляции" SSI-конструкции include virtual.

SSI и функция virtualQ

492

Часть IV. Стандартные функции РНР

Примечание )

При использовании SSI-страниц конструкция <!—#include virtuai="URL" —> загружает файл, URL которого указан у нее в параметрах, обрабатывает его нужным обработчиком и выводит в браузер. То есть все происходит так, будто указанный URL был затребован "виртуальным браузером". Большинство SSI-файлов ограничиваются использованием этой возможности.

int virtual(string $url)

Функция virtual 0 представляет собой процедуру, которая может поддерживаться только в случае, если РНР установлен как модуль Apache. Она делает то же самое, что и SSI-инструкция <!—#inciude virtuai="..." — >. Иными словами, она генерирует новый запрос серверу, обрабатываемый им обычным образом, а затем выводит данные в стандартный поток вывода.

Чаще всего функция virtual() используется для запуска внешних CGI-сценариев, написанных на другом языке программирования, или же для обработки SSI-файлов более сложной структуры. В случае, если запускается сценарий, он должен генерировать правильные HTTP-заголовки, иначе будет выведено сообщение об ошибке.

щшшшшшшт

Заметьте, что для включения обычных PHP-файлов (не являющихся законченными скриптами, а, например, содержащих набор функций) функция virtual!) неприменима — используйте вместо нее оператор require_once.

Эмуляция функции virtualQ

Функция virtual!) работает только в том случае, если РНР установлен как модуль Apache. Проблемы начинаются, если это не так, и какой-то уже готовый сценарий интенсивно использует вызовы virtual!). Тогда мы должны будем либо переделать сценарий, либо написать эмуляцию для функции virtual!) (благо в "сценарном" варианте РНР эта функция отсутствует, так что можно без оглядки на ключевые слова создать процедуру с именем virtual!)). Вот как мы здесь поступим (листинг 25.4).

I Листинг 25.4. Файл lib/virtual.php

<?php ## Эмуляция функции virtual!)• if (! function__exists ("virtual") ) { // Условно определяемая функция function virtual($url) {

$script_name = $_SERVER [ ' SCRIPT_NAME ' ] ; $server = $__SERVER[ ' HTTP_HOST ' ] ; // хост:порт // Преобразуем относительный URI в абсолютный, if !$url[0] != '/') {

// Адрес относительно КАТАЛОГА скрипта.

$dir = str_replace ("\\", "/", dirname ($script__name) ) ;

$url = substr($dir, -1)=="/"? $dir.$url : "$dir/$url";

}




  Hostland.Ru

 «Бесплатный хостинг Hostland.Su» © 2006