Если вы только что столкнулись с PHP, то вам нужно знать некоторые определения.
Прежде всего, PHP – это язык программирования и служит он для написания команд (сценариев), адресованных серверу. Если говорить ещё проще, то при помощи PHP мы можем общаться с сервером.
Команды PHP легко внедряются в HTML страницы. Именно это свойство является важным преимуществом языка PHP перед такими языками, как Perl и C.
PHP код сценария начинается после открывающего тэга и заканчивается закрывающим ?> . Текст между этими двумя тэгами считывается программой , находящейся на сервере, а в HTML-документ выводится полученный результат. Рассмотрим на примере:
include
("sidebar.htm")
;
?>
Если нам нужно что-то вставить в html код страницы необходимо использовать команду include (вставить). Далее указываем адрес файла, а заканчивается строка, как и в CSS ;
Как правило боковые колонки (sidebar
) и подвал (footer
) остаются неизменными на всех страницах сайта. Следовательно коды
include
("sidebar.htm")
;
include
("content.htm")
;
include
("footer.htm")
;
?>
содержимое sidebar.htm
Аналогично с файлами content.htm и footer.htm .
При такой генерации страниц Вам достаточно внести изменения в один файл "sidebar.htm" , что бы изменились все страницы сайта. Что очень удобно если Ваш сайт состоит из сотни или тысячи страниц.
Чтобы Вы могли работать с PHP-скриптами и просматривать результаты выполнения в браузере, вам нужно установить работающий веб сервер с PHP на Вашем локальном компьютере.
Лучше всего для таких задач подойдёт Денвер . (официальный сайт предоставляет всё необходимое бесплатно
) В комплект установки входит - Apache, php и MySQL. Другими словами на Вашем компьютере будет находиться полнофункциональный сервер для хостинга сайтов .
Для того, что бы PHP код работал в HTML страницах необходимо открыть файл .htaccess в любом текстовом редакторе и прописать следующее:
AddHandler application/x-httpd-php .html
Данная запись разрешает выполнение PHP скриптов в HTML страницах.
Или изменить расширение файла.html на.php
PHP способен не только выдавать HTML. Возможности PHP включают формирование изображений, файлов PDF и даже роликов Flash (с использованием libswf и Ming), создаваемых "на лету". PHP также способен выдавать любые текстовые данные, такие, как XHTML и другие XML-файлы. PHP способен осуществлять автоматическую генерацию таких файлов и сохранять их в файловой системе вашего сервера, вместо того, чтобы отдавать клиенту, организуя, таким образом, кеш динамического содержания, расположенный на стороне сервера.
Одним из значительных преимуществ PHP является поддержка широкого круга баз данных. Словом, PHP может предложить вам очень многое! Подробно о преимуществах PHP можно ознакомиться на www.php.su .
February 1, 2015
Я решил описать способы закрыть паролем часть сайта. Тема, на самом деле, большая, поэтому на первый раз ограничусь авторизацией php+mysql.
Самый первый вопрос, который обычно встаёт — как закрыть директорию со скриптами администрирования паролем. При этом не нужно никаких изысков — один или несколько администраторов имеют одни и те же права, а персоналии меняются редко. Проще всего в данной ситуации использовать стандартную серверную авторизацию — положить файлы.htaccess и.htpasswd и прописать в них нужные параметры. Про это уже написано много, поэтому я ничего особо нового не скажу, лучше посмотрите сюда.
Добавлю две вещи. Первое — это куда класть файл.htpasswd. Экспериментальным путем я выяснил, что если, например, путь к документу с сообщением об ошибке (ErrorDocument) пишется относительно системной переменной DocumentRoot. Но путь к файлу с паролями (UserFile) пишется относительно ServerRoot. Насколько я понял, выше ServerRoot положить.htpasswd нельзя — «../» не воспринимается. Всё это сделано для того, чтобы можно было поместить файл с паролями, например, одним уровнем выше корневой директории сайта, чтобы из сети доступа к файлу не было вообще.
Второе — это то, что скрипт может узнать, кто его открывает и пароль: переменные $PHP_AUTH_USER и $PHP_AUTH_PW.
Главный недостаток этого способа — сервер не может блокировать подбор пароля (это после нескольких неудачных попыток входа пользователю предлагается подождать часок-другой, а в течение этого времени обращения с его IP-адреса игнорируются). Это написано в официальной документации по Апачу.
Ещё один недостаток — необходимость переписывать файлы с паролями при удалении пользователя или введении нового. Но если это происходит нечасто, этого способа вполне достаточно, к тому же не придётся забивать голову написанием механизма авторизации.
Это нужно не только для упрощения работы с большим количеством пользователей и их большой «текучкой». Если нужно держать дополнительную информацию о пользователях, либо необходимо гибкое разграничение прав, лучше перенести авторизацию в базу.
Каждая страница закрытой территории подключает файл с вот таким кодом:
$result = mysql_query("SELECT * FROM person WHERE login="". preg_replace("/[^\w_-]/","",$PHP_AUTH_USER). "" AND pass="". md5($PHP_AUTH_PW). """); if (@mysql_num_rows($result)!=1) { header("WWW-Authenticate: Basic realm="User area""); header("HTTP/1.0 401 Unauthorized"); print("Чтобы войти в пользовательскую часть сайта, надо ввести имя и пароль."); exit(); }; $user_row = mysql_fetch_array($result);
В первой строке из логина удаляются все символы кроме букв, цифр, тире и символа подчеркивания. Затем проверяется количество полученных строк, и только если это одна строка, дается доступ. В остальных случаях пользователь увидит в броузере окно, предлагающее ввести логин и пароль. Если же пользователь вошел успешно, в массиве $user_row мы имеем всю информацию о нем.
Конечно же, пример, который я привёл, имеет ряд существенных недостатков. Не переписывайте его один-в-один, чтобы потом не пасть жертвой попыток подбора пароля, потому что
И последний на сегодня способ — хранение зашифрованных данных в куках.
Есть скрипт для входа, остальные подключают код, позволяющий только продолжить действия в закрытой области — если куки истекут, или он выйдет оттуда, придётся возвращаться на страницу для входа.
Входной скрипт проверяет логин и пароль и выдает две куки. В первой — логин, чтобы сразу опознать пользователя (в базе поле логина, естественно, уникальное или даже ключевое). Во второй куке — хэш от времени входа и пароля (для полноты конспирации я добавляю к этим строкам букву «Ы» — тогда хэш подобрать почти невозможно:).
Все остальные программы подключают код, который делает следующее. Делает запрос в базу — выбирает строку с полученным логином. Из этой строки берет поле «log_time» и пароль и делает из них, как и описано выше, хэш. Сравнивает его с тем, что получил, и если они совпадают, выдает новую куку хэша, опять же, от пароля, времени и буквы «Ы» и делает запрос в базу данных «UPDATE user SET log_time=’…’ WHERE login=’$cookie_login"».
if (isset($HTTP_COOKIE_VARS[$cookie_login]) &&isset($HTTP_COOKIE_VARS[$cookie_code])) { $login = $HTTP_COOKIE_VARS[$cookie_login]; $code = $HTTP_COOKIE_VARS[$cookie_code]; $result = mysql_query("SELECT date_format(log_date,"%Y%m%d%H%i%s") as log_date1, pass,uid FROM user WHERE email="$login" AND log_date>"DATE_SUB(NOW(),INTERVAL 15 MINUTE)""); if (!mysql_error() && @mysql_num_rows($result)==1) { $log_time0 = time(); $log_time1 = date("YmdHis", $log_time0); $log_time2 = date("Y-m-d H:i:s", $log_time0); $current_user = mysql_fetch_array($result); if (md5($current_user["pass"].$current_user["log_date1"].$md5letter) == $code) { mysql_query("UPDATE user SET log_date="$log_time2" WHERE uid=".$current_user["uid"]); setcookie($cookie_code, md5($current_user["pass"].$log_time1.$md5letter), time()+900, $site_path); $auth = true; } else unset($current_user); } }
Когда я выложил этот выпуск в прошлый раз, меня запинали на месте, мол такой блокировкой можно и сервер «пустить под откос».
Но сначала о блокировке подбора. Банальности, но всё-таки. Пароль длинной десять символов из букв латиницы и цифр — это очень много вариантов. Если подбирать пароль по 1 000 000 вариантов в секунду, понадобится несколько тысяч лет. Но поскольку такую абракадабру запомнить сложно, мы чаще делаем пароль из осмысленных слов. Несколько лет назад оказалось, что большинство паролей можно подобрать при помощи словаря из 10 000 слов. В своё время в сети появился червь (вирус такой), который лазил по юниксовым серверам, используя их дырки в защите, и подбирал пароли привелигированых пользователей при помощи… системного орфографического словаря Юникса. Ничего таскать не надо было!
Каждый пользователь, пока он не ввёл правильный логин и пароль, считается злобным хакером. С чем же мы имеем дело, когда пользователь вводит что-либо неправильно?
Я долго думал, как можно вызвать перегрузку на сервере, если механизм защиты стоит на файлах. Оказалось, несложно (сколько это будет стоить — другой вопрос). Итак, допустим, сервер не выдержит, если скрипт будет пытаться 1000 раз в секунду открывать файлы на запись и писать в них данные. Поскольку после 5 неудачных попыток войти в систему пользователь будет сразу получать отказ в доступе (без какой-либо записи данных в файл), надо найти 200 уникальных IP, с которых по пять раз и обратиться. Это возможно. Вешаем в баннерокрутилке html-баннер с пятью тегами:
Пользователь моментально делает пять обращений сервер пять раз пишет в файл (кстати, в некоторых броузерах, возможно, выскочит окно для ввода логина и пароля). Можно сделать html-страницу с пятью такими картинками, а саму страницу вставить через iframe на посещаемый сайт (через iframe — чтобы по полю referer не нашли. Вряд ли служба поддержки халявного хостинга будет заниматься такими вещами как копание в лог-файлах в поисках рефереров). Те примеры, которые я привёл, разумеется, натянуты, но сам факт того, что можно воспользоваться таким недостатком системы, доказан. Кстати, нечто подобное уже было.
Но всё-таки приведу этот способ — зря писал, что ли? Его, кстати, можно без особого страха применять для ограниченного количества адресов (например, для локальной сети фирмы), положив в директорию файл.htaccess такого содержания:
order deny,allow deny from all allow from xxx.xxx.xxx
А вот код программы:
$errors = 0; $fn = "ignore/". preg_replace("[^d.]", "", $REMOTE_ADDR. ".". $HTTP_FORWARDED_FOR); if (is_file($fn)) { if (filectime($fn) < time()-3600) unlink($fn); } else $errors = fread(fopen($fn, "r"), 2); if ($errors>5) { print ("Доступ закрыт. Зайдите через час."); exit(); } // здесь происходит установка связи с сервером БД. // чтобы не трогать зря, если пользователя сразу же "отлупили". $result = mysql_query("SELECT * FROM user WHERE login="". preg_replace("/[^w_-]/", "", $PHP_AUTH_USER). "" AND pass="". md5($PHP_AUTH_PW). """); if (@mysql_num_rows($result)!=1) { header("WWW-Authenticate: Basic realm="secret area""); header("HTTP/1.0 401 Unauthorized"); print ("Authorization required"); fwrite(fopen($fn, "w"), ++$errors); exit(); } $current_user = mysql_fetch_array($result); mysql_free_result($result);
Впрочем, грех работать с файлами, если есть база. Шутка. Для не прошедших авторизации создаём таблицу:
CREATE TABLE unauth (username VARCHAR(64) NOT NULL, pass VARCHAR(64) NOT NULL, ip VARCHAR(255), logintime TIMESTAMP)
И вместо обращения к файлам работаем с базой.
$errors = @mysql_result(mysql_query("SELECT count(username) as falses FROM unauth WHERE logintime>DATE_SUB(NOW(),INTERVAL 1 HOUR) AND ip="$REMOTE_ADDR""),0); if (mysql_error()) die(mysql_error()); if ($errors>5) { print ("Доступ закрыт. Зайдите через час."); exit(); } $result = mysql_query("SELECT * FROM user WHERE login="". preg_replace("/[^w_-]/", "", $PHP_AUTH_USER). "" AND pass="". md5($PHP_AUTH_PW). """); if (@mysql_num_rows($result)!=1) { header("WWW-Authenticate: Basic realm="secret area""); header("HTTP/1.0 401 Unauthorized"); print ("Authorization required"); mysql_query("INSERT INTO unauth (username, pass, ip) VALUES ("$PHP_AUTH_USER", "$PHP_AUTH_PW", "$REMOTE_ADDR $HTTP_X_FORWARDED_FOR")"); exit(); } $current_user = mysql_fetch_array($result); mysql_free_result($result);
Хранить ли старые записи для статистики или нет — дело хозяйское. Если что, их можно удалять, выполняя перед авторизацией запрос:
Такой механизм при больших нагрузках будет работать быстрее и надёжнее, чем файлы — в базе часто используемые данные буферизуются и обрабатываются непосредственно в оперативной памяти.
Была у меня в своё время проблема: надо закрыть администрационную часть сайта, но при этом я не могу положить файл.htpasswd выше корневой директории сайта. Врождённая подозрительность не позволяла положить файл с паролем и отдельную директорию и заблокировать доступ к ней по http. Решил попробовать сделать защиту как в phpMyAdmin: у пользователя спрашиваются логин и пароль, с которыми скрипт соединяется с базой. В своём анализаторе логов я сделал именно так. Удобство метода в том, что файл можно складывать куда угодно — никаких кук, никаких директив сервера для директории. Заодно, если поменяется пароль в базе данных, не надо ничего исправлять в скрипте.
Шаблоны в PHP
Разделение оформления и содержания – извечная проблема веб-разработчика. Для держателя небольшого сайта в несколько страниц такой проблемы не возникает и изменение дизайна, либо другая правка внешнего вида страниц для него не представляет трудностей. Однако для крупных веб-ресурсов и порталов смешение этих двух важнейших компонентов сайта – оформления и содержания – просто недопустимо. Иначе сайт становится настолько неповоротлив, что владелец ресурса теряет над ним управление.
Столкнувшись однажды с такой проблемой, сайтостроители начали ломать голову над тем, как сделать так, чтобы информация не привязывалась никоем образом к дизайну и наоборот, чтобы внешний вид всего сайта менялся буквально одним движением руки.
Необходимо сказать, что способа идеального разделения оформления и содержания в наши дни пока не найдено. Но все же созданы определенные наработки и технологии, которые позволяют максимально приблизиться к этому идеалу. Прежде всего это технология использования шаблонов.
Понятие "шаблон" довольно обширно. Но чаще всего под шаблоном понимается некий документ (обычно в формате HTML), содержащий в себе всё оформление ресурса, либо только его части, а также специальные метки, которые в процессе генерации страницы заменяются на информационные данные.
Для работы с шаблонами используются специальные веб-приложения (если говорить о веб-разработках), которые могут обладать различными свойствами и функциями. Но чаще всего их роль сводится к тому, чтобы заменять вышеуказанные метки на информационные блоки и соединять полученные части страниц в единое целое.
Наверное, во всех языках вебпрограммирования есть подобные инструменты для работы с шаблонами: в Perl это FastTemplate (который, кстати, существует и для PHP, но его использование не рекомендуется, так как приемлемые для работы версии относятся еще к третьей версии PHP), в отношении PHP – это крупный и многофункциональный Smarty, а также ряд других более мелких "шаблонизаторов".
Smarty – одна из самых крупных разработок подобного рода. Реализован он, как и практически все приложения подобного типа, в виде класса.
Этот "шаблонизатор" имеет огромное количество возможностей: он не только осуществляет замену выделенных участков шаблона указанными данными, но и предоставляет использование внутри шаблона исполняемых участков, функций, конфигурационных файлов и т.д.
Описывать все его возможности и правила использвования не имеет смысла из-за экономии времени, к тому же к нему написана довольно хорошая документация, а примеры использования прилагаются к самому Smarty.
Smarty – это настоящий монстр по работе с шаблонами. Но, как понимаете, за столь широкую функциональность приходится платить ресурсами сервера и временем исполнения скрипта на его основе. В некоторых случаях из-за своей громоздкости Smarty кажется неповоротливым. Поэтому для сравнительно небольших проектов использование Smarty – обычно далеко не лучший выбор. В этом случае следует обратить внимание на более мелкие и менее функциональные, но тем не менее достойные инструменты.
Рассмотрим более простой пример шаблонов.
Код шаблона помещается внутрь HTML страницы и занимается генерацией динамического содержимого.
Пример 10.1.1:
Страница 1 | Страница 2 | Страница 3 |
// Начало пункта меню
$menuItemCellStart = "
// Конец пункта меню
$menuItemCellEnd = "
// Начало content"а страницы
$pageContentStart = "
// Конец content"а страницы
$pageContentEnd = "
";// Footer страницы
$pageFooter = "
(с) 2001 Вася Пупкин
";// Заголовок страницы
// Содержимое меню
// Content страницы
// Подгружаем темплейты
include("templates.php");
// Выводим заголовок
echo $pageHeaderStart.$title.$pageHeaderEnd;
// Выводим меню
echo $menuStart;
for($i=0;$i echo $menuItemCellStart."".$menu[$i]."".$menuItemCellEnd; // Выводим content страницы echo $pageContentStart.$content.$pageContentEnd; // Выводим footer echo $pageFooter; Конечно этот код выглядит просто ужасно, но основную идею "собирания" HTML кода страницы из кусочков этот пример демонстрирует достаточно хорошо. На самом деле основная проблема приведенного выше кода состоит в том, что он не позволяет вам полностью избавиться от HTML кода внутри PHP кода, ведь здесь каждая частичка HTML кода хранится в отдельной переменной. Представьте, сколько пришлось бы иметь подобных переменных для более-менее сложной страницы. И, кроме того, несмотря на то, что непосредственно HTML код вынесен в отдельный файл, но его связь с результатами работы PHP кода жестко задана внутри самого PHP кода (ведь все объединения HTML и PHP кода жестко прописаны). Большинство этих проблем могут быть решены путём использования несложной системы для подстановок данных в HTML-шаборны. Основным отличием систем, основанных на подстановке данных, является то, что они позволяют, используя определенный синтаксис, определять места вставки данных в HTML-шаблоны. По сути, все имеющиеся системы работы с шаблонами основаны именно на этом принципе и единственное, что их различает – синтаксис, используемый для задания шаблонов и набор возможностей, предоставляемый системой. Приведём одну из самых простых систем, основанных на этом принципе. Это всего лишь одна небольшая функция (чуть больше 40 строчек кода), но, тем не менее, она позволяет делать практически всё то же, что и большинство систем "среднего уровня", имеющиеся в Интернет. Сначала – краткое описание синтаксиса для описания шаблонов, применяемых в данной системе. "Ключ" для подстановки: Ключом для подстановки здесь называется часть текста шаблона, которая будет впоследствии заменена на некоторые данные, переданные функции – обработчику шаблонов. Он состоит из двух основных частей: имени (уникального в пределах данного шаблона) и необязательного значения по умолчанию. Оно будет использоваться в случае, если при обработке шаблона для него не было задано значение. В случае, если значение по умолчанию также не было задано - этот ключ будет заменен на пустую строку. Значение по умолчанию может также быть использовано для задания специальной обработки. Ниже приведены 3 различных типа синтаксиса, допустимые для значения по умолчанию: Как видите, тип обработки для значения по умолчанию указывается в первом символе. Если это символ "#", то все значение рассматривается как "вставить результат обработки шаблона с именем с заданными параметрами в качестве значения для этого ключа подстановки". Т.е. обработчик шаблонов будет вызван рекурсивно для обработки шаблона с заданным именем и заданным списком данных для подстановки, а результаты обработки этого шаблоны будут использованы в качестве значения для подстановки. Если это символ "!", то процесс обработки похож на предыдущий, с той лишь разницей, что вместо вызова обработчика шаблонов производится вызов пользовательской функции с заданным именем и ей в качестве параметра передается массив данных, заданных в этом ключе (структура массива такая же, как и для самой функции обработки шаблонов). Результаты работы функции будут использованы в качестве значения для подстановки. Символы, имеющие специальное значение могут быть вставлены в текст, используя их escaping sequences: Вне ключей для подстановки Внутри ключей для подстановки Ниже приведен текст функции, которая непосредственно занимается обработкой шаблонов, используя описанный выше синтаксис. Пример 10.1.3 (файл templates.function.php): // Вставка в страницу HTML кода на основе темплейтов // Параметры: // $template - темплейт с HTML кодом, который будет использоваться как основа // $params - массив с данными, которые будут использоваться для подстановки. function insertTemplate($template,$params=array()) // Убираем из текста темплейта все escaped символы (они будут заменены // на необходимые значения позже) Это необходимо, чтобы облегчить задачу // разбиения темплейтов с помощью регулярных выражений $template = strtr($template,array("{{"=>"\x03","}}"=>"\x04")); // Используем регулярное выражение чтобы получить массив всех мест внутри темплейта, // которые должны быть заменены на результаты подстановки. preg_match_all("/\{([^\}]+)\}/i",$template,$matches); // Если не было найдено ни одного места для подстановки - // просто возвращаем исходный текст темплейта. if (sizeof($matches)==0) return($template); // В этот массив мы будем собирать тексты, которые будут исползованы для // подстановок в темплейт. $replaces = array(); // Нам необходимо преобразовать все найденные места для подстановок внутри темплейта // в регулярные выражения для их поиска. Тогда мы сможем впоследствии выполнить // все подстановки одновременно, используя замену по массиву регулярных выражений. for ($i=0;$i $matches[$i] = "/".preg_quote($matches[$i],"/")."/"; // Теперь нам необходимо подготовить тексты для замены // Для этого нам необходимо обработать содержимое каждого из найденных // мест для подстановок внутри темплейта. for ($i=0;$i // Преобразуем все escaped символы в нормальные. Символ разделения " " при этом // заменяем на символ с кодом 0x01, чтобы не перепутать. $match = strtr(strtr($matches[$i],array(" "=>"\x02"," "=>"\x01")),"\x02"," "); // Проверяем, что из себя представляет строка, которую мы пытаемся обработать if (strpos($match,"\x01")!==false) // Эта строка содержит в себе несколько частей. Это значит, что кроме имени эта // строка содержит какие-то параметры, которые требуют дополнительной обработки. // Поскольку основная синтаксическая структура у нас состоит из 2 частей - имени // и значения по-умолчанию - получаем эти две основные части в виде отдельных переменных list($key,$default) = explode("\x01",$match,2); // Исправляем regular expression для дальнейшей замены $matches[$i] = "/\{$key\ [^\}]+\}/"; // Проверяем, чем является параметр, переданный внутри темплейта. Если он начинается // с одного из специальных символов, то необходима дополнительная обработка этого значения. // Однако это необходимо делать толлько в случае, если в переданных в функцию данных для // замены нет текста для этой подстановки (потому что данные, переданные в качестве // аргумента имеют более высокий приоритет). if ((in_array($default,array("#","!"))) && (!isset($params[$key]))) // Получаем список аргументов. Первый символ отбраcываем, потому что это признак // спеуиальной обработки и не относится к имени. $words = explode("\x01",substr($default,1)); // Поскольку первым в полученном списке стоит имя, которое будет использоваться // обработчиком - берем его в отдельную переменную и убираем из массива аргументов. // Теперь в массиве $words - только список аргументов. $name = array_shift($words); // Проверяем, если количество аргументов - нечетное (т.е. нам необходим еще один, поскольку // все аргументы рассматриваются как пары "имя-значение"), то добавляем пустую строку. if ((sizeof($words)%2)!=0) // Формируем массив параметров. Он должен быть в том же виде, в котором он передается // в данную функцию (т.е. имя параметра задается в виде ключа ассоциативного массива). $params = array(); for ($j=0;$j $params[$words[$j]] = $words[$j+1]; if ($default=="#") // Символ "#" указывает на необходимость вставки темплейта с заданным именем $default = insertTemplate($GLOBALS[$name],$params); elseif ($default=="!") // Символ "#" указывает на необходимость вставки результатов работы пользовательской // функции с заданным именем $default = call_user_func($name,$params); // Если в списке текстов для подстановки, переданных в качестве параметра в эту функцию, // есть текст для подстановки с таким же именем, то используем его, потому что параметры, // переданные в качестве аргумента имеют более высокий приоритет. Если же такого текста // нет, то используем текст, имеющийся у нас в качестве значения. $replaces = (isset($params[$key]))?$params[$key]:$default; elseif ($match=="l") // Эта строка - escaping для левой фигурной скобки, имеющей специальное значение. $replaces = "{"; elseif ($match=="r") // То же самое для правой фигурной скобки $replaces = "}"; // Эта строка имеет только имя. Если в списке текстов для подстановки, переданных // в качестве параметра в эту функцию, есть текст для подстановки с таким именем, // то используем его, в противном случае используем в качестве замены пустую строку. $replaces = (isset($params[$match]))?$params[$match]:""; // Теперь у нас есть все необходимые данные и мы можем выполнить замену. Поскольку все // строки, которые необходимо заменить в данном темплейте сконвертированы в регулярные // выражения - необходимо просто выполнить замену по имеющимся массивам. Кроме того // здесь же мы возвращаем нормальные значения escaped символам, которые мы убирали в начале. return(strtr(preg_replace($matches,$replaces,$template),array("\x03"=>"{","\x04"=>"}"))); Теперь посмотрим, как можно сгенерировать ту же самую простейшую страничку, используя приведенную выше функцию. Файл templates.php содежит описание всех необходимых шаблонов. Очень похоже на предыдущий вариант этого файла, но здесь в шаблонах используется описанный выше синтаксис для вставки текста. Пример 10.1.4: // Основной темплейт для страницы $tplPage = <<
{content #tplContent} {footer #tplFooter} // Темплейт для меню сайта $tplMenu = <<
{menuItems !createMenu} // Темплейт для пункта меню для меню сайта $tplMenuItem = <<
// Темплейт для основного content"а страницы $tplContent = <<
{content !createPageContent} // Темплейт footer"а сайта $tplFooter = <<
{footer (с) 2001 Вася Пупкин} Файл index.php содержит сам код построения страницы // Подгружаем все необходимые файлы include("templates.function.php"); include("templates.php"); // Заголовок страницы $title = "Простейшая страничка"; // Содержимое меню array("page1.php","Страница 1"), array("page2.php","Страница 2"), array("page3.php","Страница 3") // Content страницы $content = "Динамический content страницы"; // Функция генерации меню сайта. Она вызывается парсером темплейтов // во время обработки темплейта $tplMenu. function createMenu() // Вся генерация содержимого меню сводится все к тому же вызову парсера темплейтов. // При этом в качестве аргументов передаются данные для каждого из имеющихся пунктов меню. foreach($menu as $item) $html .= insertTemplate($GLOBALS["tplMenuItem"],array("url"=>$item,"name"=>$item)); // Функция генерации содержимого страницы. В нашем случае она просто возвращает переменную. function createPageContent() return($GLOBALS["content"]); // Как видите, после всех подготовительных шагов весь код программы сводится к одной строчке:-) // Мы просто вызываем парсер темплейтов для обработки основного темплейта страницы, а все // необходимые связи между темплейтами у нас прописаны непосредственно внутри них, что позволит // впоследствии легко изменить их не меняя кода. Что, собственно, нам и требовалось. echo insertTemplate($tplPage,array("title"=>$title)); Как видите – код становится намного более компактным и логичным с применением шаблонов. И, кроме того, даже такая простейшая система обработки шаблонов значительно упрощает вам работу. Вы получаете возможность контролировать отдельно логику программы и отдельно – её визуальную часть, чего мы, собственно, и добивались. Кстати, эту функцию можно применять не только для генерации HTML (все же она слишком проста для этого), а и для других целей. Например таких, как генерация e-mail. Ведь иногда бывает необходимо сгенерировать текст письма по шаблону, добавив в него какую-то информацию. Использование этой простой функции поможет вам решить эту задачу быстро и легко. В Интернет вы можете обнаружить множество систем для работы с шаблонами разной степени "навороченности". Наиболее распространёнными являются: · Cached Fast Template · PowerTemplate Одно из главнейших достоинств PHP - то, как он работает с формами HTML.
Здесь основным является то, что каждый элемент формы автоматически
становится доступным вашим программам на PHP. Для подробной информации об
использовании форм в PHP читайте раздел . Вот пример формы HTML: Пример #1 Простейшая форма HTML
В этой форме нет ничего особенного. Это обычная форма HTML без каких-либо
специальных тегов. Когда пользователь заполнит форму и нажмет кнопку
отправки, будет вызвана страница action.php . В
этом файле может быть что-то вроде: Пример #2 Выводим данные формы
Здравствуйте,
. Пример вывода данной программы: Здравствуйте, Сергей.
Вам 30 лет. Если не принимать во внимание куски кода с htmlspecialchars()
и
(int)
, принцип работы данного кода должен быть прост и понятен.
htmlspecialchars()
обеспечивает правильную кодировку "особых"
HTML-символов так, чтобы вредоносный HTML или Javascript не был вставлен на вашу
страницу. Поле age, о котором нам известно, что оно должно быть число, мы можем просто
преобразовать в integer
,
что автоматически избавит нас от нежелательных символов. PHP также может сделать это
автоматически с помощью расширения filter . Переменные
$_POST["name"] и $_POST["age"]
автоматически установлены для вас средствами PHP. Ранее мы использовали
суперглобальную переменную $_SERVER , здесь же мы точно так же
используем суперглобальную переменную $_POST , которая содержит
все POST-данные. Заметим, что метод отправки
(method) нашей
формы - POST. Если бы мы использовали метод GET
, то
информация нашей формы была бы в суперглобальной переменной
$_GET .
Кроме этого, можно использовать переменную $_REQUEST , если
источник данных не имеет значения. Эта переменная содержит смесь данных GET, POST,
COOKIE. 15 years ago
According to the HTTP specification, you should use the POST method when you"re using the form to change the state of something on the server end. For example, if a page has a form to allow users to add their own comments, like this page here, the form should use POST. If you click "Reload" or "Refresh" on a page that you reached through a POST, it"s almost always an error -- you shouldn"t be posting the same comment twice -- which is why these pages aren"t bookmarked or cached. You should use the GET method when your form is, well, getting something off the server and not actually changing anything. For example, the form for a search engine should use GET, since searching a Web site should not be changing anything that the client might care about, and bookmarking or caching the results of a search-engine query is just as useful as bookmarking or caching a static HTML page.
1 year ago
Worth clarifying: POST is not more secure than GET. The reasons for choosing GET vs POST involve various factors such as intent of the request (are you "submitting" information?), the size of the request (there are limits to how long a URL can be, and GET parameters are sent in the URL), and how easily you want the Action to be shareable -- Example, Google Searches are GET because it makes it easy to copy and share the search query with someone else simply by sharing the URL. Security is only a consideration here due to the fact that a GET is easier to share than a POST. Example: you don"t want a password to be sent by GET, because the user might share the resulting URL and inadvertently expose their password. However, a GET and a POST are equally easy to intercept by a well-placed malicious person if you don"t deploy TLS/SSL to protect the network connection itself. All Forms sent over HTTP (usually port 80) are insecure, and today (2017), there aren"t many good reasons for a public website to not be using HTTPS (which is basically HTTP + Transport Layer Security). As a bonus, if you use TLS you minimise the risk of your users getting code (ADs) injected into your traffic that wasn"t put there by you.
{name}
Вам
лет.