Анимация
JavaScript
|
Главная Библионтека Но как же сопоставить идентификатор обработчика тому сценарию, который содержит его код? У сервера Apache для этого есть специальная директива под названием Action. Где задается эта директива? В любом файле конфигурации Apache. Конечно, удобнее всего это делать в файле .htaccess, расположенном в корневом каталоге виртуального хоста, чтобы изменения распространились сразу на весь сервер. Мы уже рассматривали такую стратегию выше, только теперь все будет чуточку сложнее. Вот требуемые директивы. Поместим их, как водится, в главный .htaccess-файл хоста. # Сначала связ1ваем имя обработчика с конкретн1м файлом. # Знак "?" говорит серверу, что исходн1Й URL запроса следует # передать сценарию методом GET, т. е. через QUERY STRING. Action libhandler "/lib/libhandler.php?" # Теперь уведомляем сервер, документы какого типа желаем # " пропускать" через наш обработчик. AddHandler libhandler .html .htm В этом фрагменте есть два тонких места. □ Путь к сценарию обработчика всегда указывается как абсолютный URL без указания имени хоста и порта. Мы не можем задать здесь ни путь к файлу, ни даже относительный URL. По той причине, чтобы позволить одному обработчику "передавать эстафету" другому. В самом деле, ведь это и происходит в нашем примере: Apache сначала определяет, что документ нужно "пропустить" через обработчик libhandler, а т. к. он представляет собой ни что иное, как сценарий на PHP, то и через интерпретатор PHP. В деталях затронутый процесс чуть сложнее, но мы не будем в него углубляться. □ После URL сценария в директиве Action следует знак ?. Зачем он? Это связано с механизмом, который использует Apache для того, чтобы определить конечный обработчик для того или иного документа. Когда пользователь посылает серверу URL, который, как Apache "знает", подходит под одну из команд Action, к этому URL слева просто присоединяется второй параметр директивы, и все начинается сначала - до тех пор, пока не будет найден последний обработчик. Например, если пользователь ввел /dir/file.html, то благодаря директиве Action указанный адрес преобразуется в /lib/libhandler.php?/dir/file.html. Это - ни что иное, как адрес PHP-сценария с параметром, который будет передан программе, как обгчно, через переменную окружения query string. Теперь сервер знает, что все документы с расширением html и htm нужно обрабатывать при помощи сценария, расположенного по адресу /lib/libhandler.php. Точнее, при каждой попытке открыть страницы с указанными расширениями Apache будет запускать наш сценарий и в числе обычных переменных окружения отправлять ему несколько специальных, содержащих первичную информацию о запросе, переданном пользователем. Мы сейчас рассмотрим эти переменные на практике. Если вас интересует их полный список, попробуйте распечатать массив $globals или вос- Вы, возможно, спросите, почему же мы не добавили в список расширений, на которые будет "реагировать" сценарий, еще одно - php? Давайте посмотрим, что бы произошло, поступи мы так. Предположим, пользователь хочет загрузить страницу /a.php. Apache "видит", что расширение у нее - php, и запускает обработчик с именем /lib/libhandler.php. Точнее, он "сваливает" всю работу на сценарий libhandler.php. Еще точнее - перенаправляет сервер по адресу /lib/libhandler.php?a.php! И тут же зацикливается, потому что у этого сценария расширение - также php. Итак, сервер начинает вызывать сценарий снова и снова, все удлиняя его URL - до тех пор, пока не "поймет": что-то неверно, и пора аварийно завершаться, о чем и сообщает в файлах журнала. О том, как решить эту проблему, рассказано в самом конце главы. Ну вот, у нас уже почти все готово. Осталось только написать сам код обработчика. Это не так уж и сложно. Но прежде давайте вспомним, зачем мы вообще связались с обработчиками. Для автоматической загрузки библиотекаря перед выполнением того или иного сценария, помните? Что же, вот пример (листинг 29.5). ( Замечание Мы подразумеваем, что обработчик libhandler.php находится в том же самом каталоге, что и библиотекарь с большинством модулей. Это довольно удобно, поскольку позволяет нам задавать путь к каталогу с модулями лишь в единственном месте - в директиве Action файла .htaccess, да и то в виде относительного URL. Оцените, насколько это проще для будущих модификаций сайта. Листинг 29.5. Обработчик /lib/libhandler.php с подключением библиотекаря <? Прежде всего, устанавливаем свои каталоги поиска модулей. Это, по нашей договоренности, - текущий в данн1й момент каталог. $INC[]=getcwd(); Проверяем, не пытается ли пользователь запустить обработчик напрямую, минуя Apache - например, путем набора в браузере адреса /lib/libhandler.php. Так как адрес, введенн1й пользователем, всегда передается в переменной окружения REQUEST URI, то нужно "бить тревогу", если переданная строка адреса встречается пользоваться функцией phpinfo(), вставив ее первой и единственной командой обработчика libhandler.php. в имени файла обработчика ( причем в любом регистре символов). не заб1ли отрезать в этой строке часть после ?, потому что она будет мешать при сравнении с именем файла. К сожалению, похоже, это единственный переносимый между операционными системами способ проверки легальности запуска обработчика. $FileName=strtr( FILE ,"\\","/"); $ReqName=ereg Replace("\\?.*","",strtr(getenv("REQUEST URI"),"\\","/")); if(eregi(quotemeta($ReqName),$FileName)) { Выводим сообщение об ошибке include "libhandler.err"; Записываем в журнал данные о пользователе $f=fopen("libhandler.log","a+"); fputs($f,date("d.m.Y H:i.s")." $REMOTE ADDR - Access denied\n"); fclose($f); Завершаем работу exit; Все в порядке - корректируем переменные окружения в соответствии с запрошенным пользователем адресом. @putenv("REQUEST URI=". $GLOBALS["HTTP ENV VARS"]["REQUEST URI"]= $GLOBALS["REQUEST URI"]= getenv("QUERY STRING") @putenv("QUERY STRING=". $GLOBALS["HTTP ENV VARS"]["QUERY STRING"]= $GLOBALS["QUERY STRING"]= ereg Replace("[?]*\\?","",getenv("QUERY STRING")) Подключаем библиотекарь include "librarian.phl"; Здесь можно выполнить еще какие-нибудь действия... . . . Запускаем тот сценарий, который был запрошен пользователем chdir(dirname($SCRIPT FILENAME)); include $SCRIPT FILENAME; ?> 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 [ 135 ] 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |