Настройка / FAQ по PHP
Оглавление
- Каким образом создать ссылку, типа как у http://lenta.ru/2002/01/09/?
- Я делаю так, как написано в примерах, но переменные, передаваемые в скрипт, не видны. Почему?
- Зачем теперь register_globals=off?
- У моего хостера стоит register_globals=off, как можно включить register_globals программно?
- Настраиваем PDFLib для работы с кириллицей. (Windows)
Каким образом создать ссылку, типа как у http://lenta.ru/2002/01/09/?
У ленты этот движок основан на mod_rewrite, имнсхо, поскольку там апач стоит
www.lenta.ru HTTP/1.1 200 OK Date: Fri, 11 Jan 2002 14:45:37 GMT Server: Apache/1.3.14 (Unix) rus/PL30.0
соответственный rewrite rule регекспом - и все ок. а в директории хтмл'ки складывать - черезчур корявый изврат. 8)
вот пример, как организовать подобное:
мы хотим выводить новости из базы данных по запрошенному ури
w3.lenta.ru/2002/01/11/tv6/ имея таблицу с полями новостей anchor VARCHAR(255), date date, announce VARCHAR(255), body TEXT; где anchor - текстовый указатель, date - дата, announce - анонс новости, body - тело новости.
делаем виртуальный хост
--- [ httpd.conf ] --- LoadModule rewrite_module modules/mod_rewrite.so <VirtualHost 192.168.10.1> ServerName w3.lenta.ru DocumentRoot "/wwwroot/htdocs/w3lenta" RewriteEngine On RewriteLogLevel 2 RewriteCond %{REQUEST_URI} !/index\.php RewriteRule ^/([0-9][0-9][0-9][0-9]+)/([0-9][0-9]+)/([0-9][0-9]+)/(.*)/$ /news.php?anchor=$4&date=$1-$2-$3 [T=application/x-httpd-php,L] ErrorLog logs/w3lenta-error.log CustomLog logs/w3lenta-access.log common <Directory /wwwroot/htdocs/w3lenta> Options +Includes -Indexes </Directory> </VirtualHost> --- [ httpd.conf ] ---
сразу привожу извинения за длинный регексп - пхп/перловый ^/(\d{4}+)/(\d{2}+)/(\d{2}+)/(.*)/$ не прокатил. видимо модифер \d rewrite engine не понимает - у него там какие-то свои правила паттернов.
прописываем w3.lenta.ru в hosts на ip 192.168.10.1 (ip по вкусу - у кого как отстроен локальный айпишник)
создаем два файла в корне /wwwroot/htdocs/w3lenta/:
1. этот будет отвечать на запрос w3.lenta.ru и в нем, допустим, строится листинг по таблице из 10-ти последних новостей, но мы сюда забьем тестируемый урл.
--- [ index.php ] --- <a href="/2002/01/11/tv6/">ТВ-6 распадается</a> --- [ index.php ] ---
2. этот будет выводить новость по date и anchor. кода не прописано, но сделать select announce, body, date from table where date=$date AND anchor=$anchor из таблицы новостей, я думаю, трудности никому не составит. 8)
--- [ news.php ] --- <? echo 'данные запрошенной новости: anchor = '.$anchor.', date = '.$date.' '; echo 'REQUEST_URI: http://'.getenv("HTTP_HOST").getenv("REQUEST_URI"); ?> --- [ news.php ] ---
набираем в ослике w3.lenta.ru, щелкаем линк, и наслаждаемся результатом 8)
данные запрошенной новости: anchor = tv6, date = 2002-01-11
REQUEST_URI: http://w3.lenta.ru/2002/01/11/tv6/
remarks: в реале можно сделать, если админ конфиг пропишет или ты сам админ. 8)
некоторые феньки rewrit'а (не могу сказать точно какие) работают только в версии апача выше 1.2 - я тестировал на 1.3.20. категорию прикрутить тоже несложно - просто соответствующих категориям регекспов налепить, убрав modifier L (last rule) из всех окромя последнего.
Я делаю так, как написано в примерах, но переменные, передаваемые в скрипт, не видны. Почему?
Hачиная с PHP версии 4.1 установка register_globals по умолчанию установлена в Off. Это означает, что к переменным переданным извне, например так http://some.server.dom/script.php?varname=value, при такой настройке в скрипте нельзя обращаться напрямую по имени $varname. Вместо этого надо использовать обращение к элементам специально предопределенных следующих массивов:
$_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER (в PHP версии от 4.1) или, соответственно, $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_SERVER_VARS (в любых версиях PHP).
При этом обращение к переменной приведенной в примере выше будет выглядеть так:
$_GET['varname'] или $HTTP_GET_VARS['varname']
Зачем теперь register_globals=off?
Это сделано для облегчения написания безопасных скриптов. При разработке достаточно сложных проектов, когда число используемых переменных велико, очень легко можно допустить использование неинициализированной переменной, которая при register_globals=On может быть передана скрипту извне злобным хацкером. Поэтому, для написания хороших скриптов, рекомендуется обращаться к входным переменным через предопределенные массивы (при этом программист, заранее зная, что эти переменные переданы снаружи производит соответствующие проверки на корректность) и включить error_reporting = E_ALL (по крайней мере, на этапе написания и тестирования скрипта) для того, чтобы PHP предупреждал о использовании неинициализированных переменных.
Безусловно, возможно написание хороших и безопасных скриптов и при register_globals=On, но:
- это требует значительно более внимательного подхода к написанию;
- эти скрипты не будут корректно работать на хостинге, где register_globals=Off (в отличие от скриптов, написанных для
register_globals=Off, которые будут корректно работать везде);
ВНИМАНИЕ!
- возможно, что из будущих версий PHP register_globals будет исключен вообще.
У моего хостера стоит register_globals=off, как можно включить register_globals программно?
Так как, вероятно, в следующих версиях register_globals уберут совсем и поведение PHP будет таким, как при register_globals=off, то рассмотрим этот вопрос под другим углом.
Поскольку существует множество уже используемых скриптов (надежных и не очень), которые написаны в расчете на register_globals=On, то добавлением нескольких строк кода заставим скрипт работать.
В общем случае, надо из предопределенных массивов $_GET, $_POST, $_COOKIE, $_SESSION, $_SERVER (или какие вам нужны) импортировать значения в переменные с именами элементов. Hапример так (для переменных получаемых по GET):
<? while (list($name, $value)=each($HTTP_GET_VARS)) { if(isset($$name)) continue; $$name=$value; } ?>
или, лучше так:
<? extract($HTTP_GET_VARS); extract($HTTP_POST_VARS); extract($HTTP_COOKIE_VARS); extract($HTTP_SESSION_VARS); extract($HTTP_SERVER_VARS); ?>
Естественно, это негативно сказывается на безопасности, поскольку после выполнения такого кода у вас станут глобальными все переменные переданные снаружи (нужные и ненужные), т.е. это все равно, что сделать register_globals=On.
Настраиваем PDFLib для работы с кириллицей. (Windows)
Внимание!!! Опыты проводились с PDFLib 4.0.2 / PHP 4.3.2 / Apache 2.0.46 / Windows 2000
1) В директории, где установлен PHP - есть папка "pdf-related".
Открыть эту папочку, найти файл "pdflib.upr".
Открыть файл "pdflib.upr" каким нибудь редактором.
Заменить строку:
%//home/tm/src/pdflib/fonts
на
/d:/path/pdf-related
Где: d - буква диска, а path/pdf-related - путь к папке "pdf-related"
2) Теперь обозначит путь к файлу настроек "pdflib.upr":
а) Можно создать системную WIN-переменную:
PDFLIBRESOURCE d:/path/pdf-related
б) Можно в PHP-скрипте указать явным образом путь к "pdflib.upr":
<?php $p =PDF_new(); PDF_open_file($p, ""); PDF_begin_page($p, 595, 842); /* ВОТ ЗДЕСЬ УКАЗЫВАЕТЬСЯ ПУТЬ К ФАЙЛУ HАСТРОЕК */ PDF_set_parameter($p, "resourcefile", "D:/php/pdf-related/pdflib.upr"); $font = PDF_findfont($p, "Arial", "cp1251", 1); PDF_setfont($p, $font, 18.0); PDF_set_text_pos($p, 50, 700); PDF_show($p, "ПРОВЕРКА! УРА, РАБОТАЕТ!"); PDF_end_page($p); PDF_close($p); $buf = PDF_get_buffer($p); $len = strlen($buf); header("Content-type: application/pdf"); header("Content-Length: $len"); header("Content-Disposition: inline; filename=hello_php.pdf"); print $buf; PDF_delete($p); ?>
3) ENJOY!!! :-)