Хирургия add php htm. PHP: делаем "мини-БД" на текстовом файле. PHP в HTML — расширения файлов

💖 Нравится? Поделись с друзьями ссылкой

Как и во всяком ремесле, в PHP существует масса всевозможных хитростей, ощутимо помогающих облегчить жизнь простого программиста. Вот некоторые из этих хитростей.

Трюк 1: передача массивов из формы.

Из HTML-формы можно передавать не только значения (переменные), но и массивы. Предположим, у нас есть форма со следующим полем:

При отправке данных из формы PHP-скрипт получит значение из поля cargo как переменную $cargo. Но если вместо "cargo" указать "cargo", то из поля будет отправлена скрипту уже не переменная, а массив $cargo, единственный элемент которого будет иметь единицу в качестве ключа и содержимое поля в качестве значения. При автоматическом формировании формы (скажем, при генерации прайс-листа со множеством наименований) — трюк поистине незаменимый, да и обработку массива скриптом куда проще организовать, чем анализ кучи переменных с названиями вроде tovar1, tovar2 и т. д.

Трюк 2: сокращённая форма записи условия в PHP.

Конструкцию...

echo "param=";~^~if($a==1)~^~{ echo "1"; }~^~else { echo "2"; }

Гораздо проще (и короче) изложить в сокращённой форме:

echo "param=".($a==1?"1":"2");

Трюк 3: анализ HTML-кнопок типа «submit».

HTML-кнопка «submit», как известно, отправляет данные HTML-формы серверу (в нашем случае на обработку PHP-скрипту). А как быть, если в форме нужны несколько кнопок, предусматривающих разные варианты обработки данных? Столкнувшись с этой задачей, почему-то мало кто вспоминает, что у кнопок типа «submit» есть собственный атрибут «value». Нет, конечно, всем известно, что этот атрибут выводит надпись на кнопке, иного же значения ему, как правило, не придают. Между тем в случае наличия у кнопок типа «submit» атрибута «name» текст подписей на кнопках отправляется из формы на сервер наряду с прочими данными и может быть проанализирован скриптом, что и позволит произвести столько разных обработок данных по нажатию разных кнопок типа «submit», сколько душе заблагорассудится. Преимущество трюка в том, что никаких полей типа «hidden» в этом случае не требуется.

Трюк 4: несуществующие параметры функций PHP.

Общеизвестно, что при обращении к функциям в PHP необходимо указывать ровно столько же переменных, сколько должна принимать функция:

$hour=16;~^~$minute=35;~^~echo today_is($hour,$minute);~^~...~^~function today_is($hour,$minute);~^~{~^~...~^~}

Куда менее известно, что для переменных в заголовке функции можно указывать значения по умолчанию (для использования в случае отсутствия значений переменных или самих переменных при обращении извне), что позволит обращаться к функции с любым количеством переменных или вообще не указывать их:

function today_is($hour=16,$minute=0)~^~{~^~...~^~}

Трюк 5: предотвращение кэширования JS-скриптов и CSS-стилей.

Сколько народу ежедневно ругается, изменив содержимое JS-скрипта или стилей CSS и обнаружив, что браузер прочно закешировал старую версию и ни в какую не желает показывать результаты работы новой. Особенно те, у кого в компании доступ в интернет осуществляется через прокси-сервер. Чего только не предпринимается в подобных случаях: в meta-раздел ставятся заголовки с истекшим сроком давности, meta-теги антикеширования и т. д. Между тем иногда достаточно поставить после упоминания соответствующего файла псевдопараметр в виде случайного числа, генерируемого коротеньким кусочком кода PHP:

Чтобы при открытии страницы всегда подгружалась исключительно свежая версия файла.

Трюк 6: кавычки, апострофы и интепретация текста.

К выбору контейнера для стринговых (текстовых) значений зачастую принято подходить несколько небрежно. А зря: многие забывают, что содержимое двойных текстовых кавычек (") интерпретатор PHP всегда анализирует на предмет наличия переменных, тогда как к содержимому контейнеров из одиночкых кавычек (апострофов) он абсолютно равнодушен, отображая их точно символ в символ без интерпретации.

Поэтому тексты с переменными удобнее заключать в неразрывные двойные кавычки:

$text="Здравствуйте, ${client}!";

Зато неудобочитаемый код с апострофами выполняется заметно быстрее, особенно в циклах:

$text=Здравствуйте, .$client.!;

Трюк 7: мгновенный вывод.

Ещё один отличный способ ускорить выполнение сценария — вместо того, чтобы немедленно и каждый раз выводить всё попавшееся под руку командой echo , накапливать тестовое содержимое в переменной, а затем вывести эту переменную один раз:

$mytext="variant 1";~^~$mytext.=" encode";~^~$mytext.=" access";~^~echo $mytext;

Обратите внимание, что операция конкатенации записана в сокращённом виде: $mytext.= , а не $mytext=$mytext. . Экономия времени — до десятикратного сокращения времени вывода. Впечатляет?

Трюк 8: передача массива из полей типа checkbox .

Трюк № 1 позволяет нам передавать из HTML-формы массивы. А в данном трюке проанализируем другую ситуацию: преположим, нам надо передать массив из формы, в которой есть только поля типа checkbox (это такой маленький квадратик, в котором при нажатии появляется галочка). К примеру, у нас имеется список городов, из которого пользователь может выбирать нужные ему города, но при отправке данных мы хотим отправлять не только идентификаторы выбранных пользователем городов, но и названия последних. А скрытые поля типа hidden рядом с чекбоксами нам делать очень не хочется (чтобы не утяжелять код страницы и массу отправляемых на сервер данных). Как быть?

Выход очень прост. Как известно, по умолчанию поле типа checkbox (вот такое, можете даже нажать на него: ) обычно может иметь значение «on» (поле выбрано, то есть в нём стоит галочка) или «off» (поле не выбрано). Для поля также можно указать альтернативное значение, например, 1. Однако далеко не все задумываются о том, что для этого поля можно указать вообще любое значение, да хоть текст романа «Война и мир». И это значение будет аккуратно передано серверным скриптам на анализ и обработку:

Пользователь выбирает нужные пункты, нажимает кнопку «Отправить», и на сервер отправляется массив из выбранных чекбоксов, в котором опция name чекбоксов является названием переменной, а опция value — её значением. Применительно к PHP это равнозначно строке:

$id548=Toyota Landcruiser;

А теперь снова вспомним про трюк № 1. Предположим, мы не хотим анализировать кучу переменных, а хотим вместо этого проанализировать один-единственный массив. Тоже несложно:

И в результате появления двух квадратных скобок вокруг цифры в аргументе опции name чекбокса на сервер отправляется уже не переменная $id548 , а элемент массива $id с ключом 548.

Итог? Весьма неплохой: из одного чекбокса мы передали серверу аж целых три параметра — наименование массива, ключ элемента и его значение, безо всяких дополнительных скрытых полей и лишнего HTML-кода.


echo "";
echo "";
echo "";
echo "Hello, today is ";
echo date("l, F jS, Y"); //other php code here echo "";
echo "";
?>

This will, however, affect the HTML Code Coloring option in most HTML/PHP editors, which allows for easy understanding of the role of HTML tags. You should escape each double quote within the HTML code with a backslash.

PHP in HTML - file extensions

When a given file contains PHP code, it must have a PHP extension. In most cases this is .php, but you can also configure the .htaccess file to read the PHP code in the HTML file without renaming it or changing its extension. Below you can view the "handlers", which will have to be added in order to achieve this

For a normally configured web server:

AddHandler cgi-script .html .htm

A web server running FastCGI:

AddHandler fcgid-script .html .htm Note: this is tested and works with the NTC web hosting servers. If you are using a different hosting provider, consult them for assistance. Additionally, if you are faced with constant problems there, you can consider switching to NTC Hosting in order to get the PHP optimized stable servers you need.

HTML in PHP

You can also use HTML code in a PHP script . This can be very useful if you have built your whole page in PHP, but want to include a custom HTML form, for example. All that you need to do is reverse the order of the HTML and PHP opening tags, opening the page with PHP:

Using HTML in PHP:


$Fname = $_POST["Fname"];
$Lname = $_POST["Lname"];
?>


Personal INFO



First Name:

Last Name:


echo "Hello, ".$Fname." ".$Lname.".
";
?>

While this looks a bit complicated, it actually saves you a lot of code. Here, we are using the $PHP_SELF super global, which allows us to use the value of the fields, specified under it, in the same file. Usually, for such forms two files are created - the first one is the HTML form itself and the second one is the backend PHP file, which does all the work.

If you already have a complicated PHP application , which relies on a great number of files, and you just want to keep everything as simple as possible, this can be of great assistance.

PHP with NTC Hosting

NTC Hosting offers its clients an ultimate web hosting solution . All our web hosting plans provide support for HTML and give you the possibility to choose between

(PHP 4, PHP 5, PHP 7)

htmlspecialchars — Преобразует специальные символы в HTML-сущности

Описание

String htmlspecialchars (string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = ini_get("default_charset") [, bool $double_encode = true ]]])

В HTML некоторые символы имеют особый смысл и должны быть представлены в виде HTML сущностей, чтобы сохранить их значение. Эта функция возвращает строку, над которой проведены эти преобразования. Если вам нужно преобразовать все возможные сущности, используйте htmlentities() .

Если входная строка переданная в эту функцию и результирующий документ используют одинаковую кодировку символов, то этой функции достаточно, чтобы подготовить данные для вставки в большинство частей HTML документа. Однако, если данные содержат символы, не определенные в кодировке символов результирующего документа и вы ожидаете сохранения этих символов (как числовые или именованные сущности), то вам недостаточно будет этой и htmlentities() функций (которые только преобразуют подстроки с соответствующими сущностями). Необходимо использовать функцию mb_encode_numericentity() .

Производятся следующие преобразования:

  • "&" (амперсанд) преобразуется в "&"
  • """ (двойная кавычка) преобразуется в """ в режиме ENT_NOQUOTES is not set.
  • """ (одиночная кавычка) преобразуется в """ (или ") только в режиме ENT_QUOTES .
  • "<" (знак "меньше чем") преобразуется в "<"
  • ">" (знак "больше чем") преобразуется в ">"

Список параметров

Конвертируемая строка (string ).

Битовая маска из нижеуказанных флагов, определяющих режим обработки кавычек, некорректных кодовых последовательностей и используемый тип документа. По умолчанию используется ENT_COMPAT | ENT_HTML401 .

Доступные значения параметра flags
Название константы Описание
ENT_COMPAT Преобразует двойные кавычки, одинарные кавычки не изменяются.
ENT_QUOTES Преобразует как двойные, так и одинарные кавычки.
ENT_NOQUOTES Оставляет без изменения как двойные, так и одинарные кавычки.
ENT_IGNORE Без всяких уведомительных сообщений отбрасывает некорректные кодовые последовательности вместо возврата пустой строки. Использование этого флага не рекомендуется, так как это может привести к » негативным последствиям, связанным с безопасностью .
ENT_SUBSTITUTE Заменяет некорреткные кодовые последовательности символом замены Юникода U+FFFD в случае использования UTF-8 и FFFD; при использовании другой кодировки, вместо возврата пустой строки.
ENT_DISALLOWED Заменяет неверные коды символов для заданного типа документа символом замены юникода U+FFFD (UTF-8) или FFFD; (при использовании другой кодировки) вместо того, чтобы оставлять все как есть. Это может быть полезно, например, для того, чтобы убедиться в формальной правильности XML-документов со встроенным внешним контентом.
ENT_HTML401 Обработка кода в соответствии с HTML 4.01.
ENT_XML1 Обработка кода в соответствии с XML 1.
ENT_XHTML Обработка кода в соответствии с XHTML.
ENT_HTML5 Обработка кода в соответствии с HTML 5.
encoding

Необязательный аргумент определяющий кодировку, используемую при конвертации симоволов.

Если не указан, то значением по умолчанию для encoding зависит от используемой версии PHP. В PHP 5.6 и старше, для значения по умолчанию используется конфигурационная опция default_charset . В PHP 5.4 и 5.5 используется UTF-8 по умолчанию. Более ранние версии PHP используют ISO-8859-1 .

Хотя этот аргумент является технически необязательным, настоятельно рекомендуется указать правильное значение для вашего кода, если вы используете PHP 5.5 или выше, или если ваша опция конфигурации default_charset может быть задана неверно для входных данных.

Для целей этой функции кодировки ISO-8859-1 , ISO-8859-15 , UTF-8 , cp866 , cp1251 , cp1252 и KOI8-R являются практически эквивалентными, предполагая то, что сама строка string содержит корректные символы в указанной кодировке, то символы, изменяемые htmlspecialchars() , останутся на тех же местах во всех этих кодировках.

Поддерживаются следующие кодировки:

Поддерживаемые кодировки
Кодировка Псевдонимы Описание
ISO-8859-1 ISO8859-1 Западно-европейская Latin-1.
ISO-8859-5 ISO8859-5 Редко используемая кириллическая кодировка (Latin/Cyrillic).
ISO-8859-15 ISO8859-15 Западно-европейская Latin-9. Добавляет знак евро, французские и финские буквы к кодировке Latin-1(ISO-8859-1).
UTF-8 8-битная Unicode, совместимая с ASCII.
cp866 ibm866, 866 Кириллическая кодировка, применяемая в DOS.
cp1251 Windows-1251, win-1251, 1251 Кириллическая кодировка, применяемая в Windows.
cp1252 Windows-1252, 1252 Западно-европейская кодировка, применяемая в Windows.
KOI8-R koi8-ru, koi8r Русская кодировка.
BIG5 950 Традиционный китайский, применяется в основном на Тайване.
GB2312 936 Упрощенный китайский, стандартная национальная кодировка.
BIG5-HKSCS Расширенная Big5, применяемая в Гонг-Конге.
Shift_JIS SJIS, SJIS-win, cp932, 932 Японская кодировка.
EUC-JP EUCJP, eucJP-win Японская кодировка.
MacRoman Кодировка, используемая в Mac OS.
"" Пустая строка активирует режим определения кодировки из файла скрипта (Zend multibyte), default_charset и текущей локали (см. nl_langinfo() и setlocale() ), в указанном порядке. Не рекомендуется к использованию.

Замечание : Остальные кодировки не поддерживаются, вместо них будет применена кодировка по умолчанию и сгенерировано предупреждение.

double_encode

Если параметр double_encode выключен, то PHP не будет преобразовывать существующие html-сущности. По умолчанию преобразуется все без ограничений.

Передача данных через массив $_SESSION разрешена однократно, переданные данные сразу удаляются. Это может пригодиться, например, при "возврате" в форму введённых в другом модуле данных.

Хорошо, когда все служебные функции объединены в один модуль, который основные модули подключают через директиву require_once . Мы свой модуль служебных функций назовём function.php и, кроме упомянутых методов trimall и magic , включим туда следующие функции:

  • read() - будет читать текущую базу и возвращать массив записей;
  • write($a) - будет записывать массив записей $a в файл;
  • get_index_by_name ($a,$name) - будет искать по имени $name соответствующую запись и возвращать её номер (с нуля) или значение -1, если запись не найдена. Это пригодится, чтобы отличать добавление новой записи от редактирования существующей.

Кроме того, файл функций подключит файл конфигурации и запустит сессию - эти возможности могут понадобиться любому модулю, который его подключает.

Файл function.php
$item) { list ($myname,$mynumber) = explode (DIV, $item); if ($name == mb_strtolower(trimall($myname),"UTF-8")) return $index; } return -1; } ?>

Обратите внимание, что функция read дополнительно фильтрует массив записей от пустых строк (на всякий случай, вообще-то их не должно возникать), а trimall сначала заменит любую непустую цепочку разделителей на один пробел (вторая preg_replace), а затем удалит возможные лишние разделители в начале и конце оставшейся строки (первая preg_replace).

Также есть нюанс с функцией read в смысле совместимости кода. Так как в единственной её строке есть анонимная функция , предполагается использование PHP версии не ниже 5.3. Если надо ниже - замените код на такой, где функция фильтрации именована или совсем не используется, как тут:

Function read () { $str=@file_get_contents (FILENAME); $a=explode("\n",$str); return $a; }

Также важно корректное приведение строки в Юникоде к нижнему регистру (см. mb_strtolower в коде). А локалью мы здесь не пользуемся.

Кажется, настало время писать основной файл index.php . Он будет решать следующие задачи:

  • выводить форму для добавления новой записи, которую обрабатывает модуль add.php;
  • рядом с формой добавления выведем дополнительные команды - очистка формы "самовызовом" скрипта без параметров (кнопка здесь не подойдёт, т.к. не передаёт на сервер данных) и ссылку для обращения к модулю сортировки записей по имени sort.php ;
  • получать от других модулей результаты их работы в виде числовой переменной $status и выводить соответствующие сообщения (массив $status_msg). Значение $status , равное нулю, будет принято по умолчанию, ему соответствует вывод краткой справки о работе программы;
  • если база непуста, показать её записи и обеспечить переход к редактированию или удалению.

Чтобы не перегружать таблицу дополнительными кнопками и ссылками, сделаем щелчок по имени переходом к редактированию записи модулем edit.php , а щелчку по полю "Число" будет соответствовать удаление записи модулем del.php .

Вот как всё выглядит при нескольких добавленных записях:

Внешний вид скрипта "Мини-БД на текстовом файле"

Файл index.php
Имя: Число: Очистить Сортировать"; $status_msg = array ("Щёлкните по Имени для редактирования или по Числу для удаления записи", "Запись уже существует, исправлено значение в ней", "Не удалось найти запись с указанным номером", "Не переданы данные для добавления"); if (empty($status)) $status = 0; echo "

".$status_msg[$status]."

"; if (count($a)>0) { echo ""."\n". ""."\n"; foreach ($a as $index=>$item) { echo ""."\n"; list ($name, $number) = explode (DIV,$item); echo ""."\n". ""."\n". ""."\n"; } echo "
ИмяЧисло
".htmlspecialchars(trimall($name)). "".intval(trimall($number)). "
"."\n"; } include "foot.php"; ?>

Теперь займёмся недостающими модулями. У add.php , кажется, простая задача - получить от index.php переменные $name и $number и записать их в файл. Однако, модуль должен проверить, что ему переданы непустые данные, а также уметь отличать ситуацию, когда введено уже существующее в базе имя от ввода новой записи (см. if ($id>-1) { ... } else { ... } в коде). В последнем случае запись всегда добавляется в конец, ведь будет модуль сортировки строк по алфавиту.

Также важно, что строка $name , "пропущенная" через обработчик параметров, уже лишена "критичных" для разметки символов вроде ", ", < и >, а в массиве $a , прочитанном из файла данных, все строки лежат "как есть", и <>123 не будет найдена, если $name после обработки превратилась <>123 . Поэтому функции поиска записи, названной нами get_index_by_name , передаётся строка, преобразованная "обратно" к первоначальному виду с помощью стандартной функции htmlspecialchars_decode (доступна с PHP 5.1). В том же виде строка возвращается обратно в index.php через массив $_SESSION . Это обеспечит некоторое удобство работы - после ввода новой записи её данные останутся в форме и можно будет внести ещё одну запись, мало отличающуюся по имени ("Иванова" после "Иванов").

Ну а сам возврат из модуля в модуль абсолютно типовой - через стандартную функцию header . Помните, что её можно применять, только если модуль ещё ничего не выводил в браузер.

Файл add.php
-1) { list ($name,$number0) = explode (DIV,$a[$id]); $a[$id] = $new_string;; $status=1; } else { $id = count($a)+1; array_push ($a,$new_string); } write ($a); $_SESSION["id"] = intval($id); } else $status=3; $_SESSION["name"] = htmlspecialchars_decode($name); $_SESSION["number"] = intval($number); header ("Location: index.php".($status==0?"":"?status=".$status)); ?>

Теперь о редактировании, оно будет реализовано в edit.php . Форма редактирования - почти такая же, как форма добавления, мы просто поленились сделать отдельную функцию для вывода формы. Важнее то, что модуль сам будет обработчиком данных, переданных через форму редактирования, а значит, должен отличать ситуацию, когда он только вызван, от той, когда пользователь нажал "Сохранить". Последней задаче служит проверка

If (!empty($_POST["submit"]) && !empty($name) && isset($number) && isset($id)) {

определяющая, была ли нажата кнопка и переданы все данные. Вторая ветка -

Else if (isset($a[$id])) {

предназначена для ситуации, когда в массиве $a есть запись, номер которой передан скрипту и она должна быть отредактирована. Номер записи сохраняется в скрытом HTML-поле .

Файл edit.php
Имя: Число: Назад"; include "foot.php"; exit (0); } else $status = 2; header ("Location: index.php".($status==0?"":"?status=".$status)); ?>

Модуль удаления записи del.php будет достаточно простым, всё, что ему понадобится - получить допустимый $id записи (номер элемента в массиве $a), убрать соответствующий элемент из массива, переписать файл и вернуться на страницу главного модуля.

Файл del.php

Наконец, модуль сортировки sort.php породит новую проблему - как сортировать строки в Юникоде по алфавиту, не различая больших и маленьких букв? "Прямая" сортировка с помощью стандартной функции sort подойдёт едва ли - она считает строчную и прописную букву разными символами. Локаль мы не ставили, тем более, для её установки единой формы записи для всех операционок нет .

Ограничимся тем, что из всего многообразия функций сортировки массивов выберем usort с пользовательской функцией сравнения элементов.

Применяемое "прямое" сравнение односимвольных строк Юникода, думается, не совсем корректно, но strcmp сравнивает строки побайтово и нам не подойдёт, а вообще-то корректное сравнение любых строк в Юникоде - очень непростая задача ... У меня для русского и английского в системе всё сработало, например, после сортировки получались естественные порядки слов, такие как

Абба, Авка, авклит, бася, Боби, Бобик, бобика, Бобина

Файл sort.php
$cb) return 1; } if ($alen<$blen) return -1; else if ($alen>$blen) return 1; else return 0; } usort ($a,"cmp"); write ($a); header ("Location: index.php"); ?>

Нам остаётся создать в папке файл с именем.htaccess , где мы пропишем кодировкой по умолчанию Юникод и укажем директивы настройки кавычек для сайта, чтоб ...

В этой же папке создадим пустой (0 байт) файл data.txt (необязательно, если все права настроены).

Файл.htaccess
AddDefaultCharset utf-8 php_flag magic_quotes_gpc off php_flag magic_quotes_runtime off php_flag magic_quotes_sybase off

Можете посмотреть, что получилось, и о найденных проблемах сообщить мне, я написал скрипт очень оперативно, в 2 приёма, и мог что-то не продумать:)

Рассказать друзьям