mirror of
https://github.com/php/doc-ru.git
synced 2026-03-23 23:32:16 +01:00
360 lines
16 KiB
XML
360 lines
16 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- EN-Revision: 9e6c3416c5c285f807a734e4663c399612777d7e Maintainer: shein Status: ready -->
|
||
<!-- Reviewed: no -->
|
||
<chapter xml:id="faq.html" xmlns="http://docbook.org/ns/docbook">
|
||
<title>PHP и HTML-разметка</title>
|
||
<titleabbrev>PHP и HTML</titleabbrev>
|
||
|
||
<para>
|
||
Язык программирования PHP и язык гипертекстовой разметки HTML тесно взаимодействуют:
|
||
PHP умеет генерировать HTML, а HTML умеет передавать информацию PHP. Перед чтением вопросов в этом разделе
|
||
важно понимать, как получать <link linkend="language.variables.external">
|
||
переменные из внешних источников</link>. Страницы руководства по этой теме
|
||
содержат много примеров.
|
||
</para>
|
||
|
||
<qandaset>
|
||
<qandaentry xml:id="faq.html.encoding">
|
||
<question>
|
||
<para>
|
||
Какое кодирование или декодирование я должен выполнять при передаче значения
|
||
через форму или URL-адрес?
|
||
</para>
|
||
</question>
|
||
<answer>
|
||
<para>
|
||
Есть несколько этапов, на которых кодировка важна. Предположим, что у вас
|
||
есть переменная <varname>$data</varname> с типом <type>string</type>, которая содержит
|
||
строку, которую вы хотите передать без кодирования. Вот эти этапы:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
Интерпретация HTML. Чтобы задать произвольную строку,
|
||
вы <emphasis>должны</emphasis> заключить её в двойные кавычки и
|
||
использовать функцию <function>htmlspecialchars</function> для кодирования.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
URL: URL-адрес состоит из нескольких частей. Если вы хотите, чтобы
|
||
данные были восприняты как один элемент, <emphasis>нужно</emphasis>
|
||
закодировать их функцией <function>urlencode</function>.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Скрытый элемент HTML-формы</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
echo '<input type="hidden" value="' . htmlspecialchars($data) . '" />'."\n";
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<note>
|
||
<simpara>
|
||
Кодировать перменную <varname>$data</varname> функцией
|
||
<function>urlencode</function> неправильно, поскольку кодировать данные
|
||
<function>urlencode</function> это обязанность браузера. Популярные
|
||
браузеры делают это правильно.
|
||
Заметьте, что это произойдёт независимо от метода (например,
|
||
GET или POST). Это заметно только в случае GET-запроса,
|
||
поскольку POST-запросы обычно скрыты.
|
||
</simpara>
|
||
</note>
|
||
<example>
|
||
<title>Данные, которые редактирует пользователь</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
echo "<textarea name='mydata'>\n";
|
||
echo htmlspecialchars($data) . "\n";
|
||
echo "</textarea>";
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<note>
|
||
<simpara>
|
||
Браузер показывает данные как предполагалось, потому что браузер
|
||
интерпретирует экранированные HTML-символы.
|
||
</simpara>
|
||
<simpara>
|
||
При отправке через GET- или POST-метод браузер закодирует (urlencoded)
|
||
данные для передачи, а PHP декодирует (urldecoded). Поэтому
|
||
не нужно выполнять какое-либо кодирование или декодирование,
|
||
всё обрабатываются автоматически.
|
||
</simpara>
|
||
</note>
|
||
<example>
|
||
<title>В URL</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
echo '<a href="' . htmlspecialchars("/nextpage.php?stage=23&data=" .
|
||
urlencode($data)) . '">' . "\n"
|
||
;
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<note>
|
||
<simpara>
|
||
На самом деле вы подделываете HTML-запрос GET, поэтому необходимо
|
||
вручную закодировать (<function>urlencode</function>) данные.
|
||
</simpara>
|
||
</note>
|
||
<note>
|
||
<simpara>
|
||
Вам надо применить функцию <function>htmlspecialchars</function>
|
||
к полному URL-адресу, потому что URL-адрес появляется как значение HTML-атрибута.
|
||
При этом браузер сначала раскодирует всё значение
|
||
(операция, обратная действию функции <function>htmlspecialchars</function>) и затем передаст URL.
|
||
PHP поймёт URL-адрес правильно, поскольку вы закодировали данные
|
||
функцией <function>urlencode</function>.
|
||
</simpara>
|
||
<simpara>
|
||
Вы заметите, что символ <literal>&</literal> в URL-адресе заменяется на
|
||
мнемонику <literal>&amp;</literal>. Хотя большинство браузеров это исправит,
|
||
если вы забудете об этом, но всё же это не всегда возможно. Поэтому,
|
||
даже если ваш URL-адрес не динамический, <emphasis>нужно</emphasis>
|
||
закодировать его функцией <function>htmlspecialchars</function>.
|
||
</simpara>
|
||
</note>
|
||
</para>
|
||
<!-- TODO: a note about addgpcslashes? -->
|
||
</answer>
|
||
</qandaentry>
|
||
|
||
<qandaentry xml:id="faq.html.form-image">
|
||
<question>
|
||
<para>
|
||
Я пытаюсь использовать <input type="image">, но переменные
|
||
<varname>$foo.x</varname> и <varname>$foo.y</varname>
|
||
недоступны. Значение <varname>$_GET['foo.x']</varname> тоже не существует.
|
||
Где они?
|
||
</para>
|
||
</question>
|
||
<answer>
|
||
<para>
|
||
При отправке формы, вместо стандартной кнопки отправки допустимо использовать
|
||
изображение с тэгом вроде такого:
|
||
<programlisting role="html">
|
||
<![CDATA[
|
||
<input type="image" src="image.gif" name="foo" />
|
||
]]>
|
||
</programlisting>
|
||
Когда пользователь кликает по изображению, серверу будет послана
|
||
сопутствующая форма с двумя дополнительными переменными:
|
||
<varname>foo.x</varname> и <varname>foo.y</varname>.
|
||
</para>
|
||
<para>
|
||
Поскольку имена <varname>foo.x</varname> и <varname>foo.y</varname>
|
||
не разрешены в PHP, они автоматически преобразовываются в
|
||
<varname>foo_x</varname> и <varname>foo_y</varname>. То есть
|
||
точки заменяются на подчёркивания. Таким образом, вы обращаетесь к этим переменным
|
||
так же, как и к любым другим, описанным в разделе о получении
|
||
<link linkend="language.variables.external">переменных извне
|
||
PHP</link>. Например, <varname>$_GET['foo_x']</varname>.
|
||
<note>
|
||
<para>
|
||
Пробелы в именах переменных запроса преобразовываются в подчёркивания.
|
||
</para>
|
||
</note>
|
||
</para>
|
||
</answer>
|
||
</qandaentry>
|
||
|
||
<qandaentry xml:id="faq.html.arrays">
|
||
<question>
|
||
<para>Как создать массивы в HTML <form>?</para>
|
||
</question>
|
||
<answer>
|
||
<para>
|
||
Чтобы браузер передал результат <form> в PHP-скрипт
|
||
как <link linkend="language.types.array">массив</link>,
|
||
элементы <input>, <select> или <textarea> называют
|
||
следующим образом:
|
||
<programlisting role="html">
|
||
<![CDATA[
|
||
<input name="MyArray[]" />
|
||
<input name="MyArray[]" />
|
||
<input name="MyArray[]" />
|
||
<input name="MyArray[]" />
|
||
]]>
|
||
</programlisting>
|
||
Обратите внимание на квадратные скобки после имени переменной: они делают переменную массивом.
|
||
Разработчику доступна группировка элементов в массив за счёт присваивания одинакового имени
|
||
разным элементам:
|
||
<programlisting role="html">
|
||
<![CDATA[
|
||
<input name="MyArray[]" />
|
||
<input name="MyArray[]" />
|
||
<input name="MyOtherArray[]" />
|
||
<input name="MyOtherArray[]" />
|
||
]]>
|
||
</programlisting>
|
||
Это создаст два массива, MyArray и MyOtherArray, которые браузер передаст
|
||
PHP-скрипту. Можно также задать конкретные ключи для массивов:
|
||
<programlisting role="html">
|
||
<![CDATA[
|
||
<input name="AnotherArray[]" />
|
||
<input name="AnotherArray[]" />
|
||
<input name="AnotherArray[email]" />
|
||
<input name="AnotherArray[phone]" />
|
||
]]>
|
||
</programlisting>
|
||
Массив AnotherArray теперь будет содержать ключи 0, 1, email и phone.
|
||
</para>
|
||
<para>
|
||
<note>
|
||
<para>
|
||
Определять ключи массивов в HTML необязательно. Если вы не установите
|
||
ключи, массив заполнится в порядке появления элементов в форме.
|
||
Первый пример будет содержать ключи 0, 1, 2 и 3.
|
||
</para>
|
||
</note>
|
||
</para>
|
||
<para>
|
||
Также смотрите
|
||
<link linkend="ref.array">Функции для работы с массивами</link> и
|
||
<link linkend="language.variables.external">Переменные извне PHP</link>.
|
||
</para>
|
||
</answer>
|
||
</qandaentry>
|
||
|
||
<qandaentry xml:id="faq.html.select-multiple">
|
||
<question>
|
||
<para>
|
||
Как получить все результаты из HTML-тега select с атрибутом multiple?
|
||
</para>
|
||
</question>
|
||
<answer>
|
||
<para>
|
||
HTML-тег select с атрибутом multiple разрешает пользователю выбрать
|
||
элементы из списка. Эти элементы затем передаются обработчику
|
||
формы. Проблема в том, что они переданы с одним и тем же именем.
|
||
Например:
|
||
<programlisting role="html">
|
||
<![CDATA[
|
||
<select name="var" multiple="yes">
|
||
]]>
|
||
</programlisting>
|
||
Каждая выбранная опция поступит обработчику формы как:
|
||
<programlisting>
|
||
var=option1
|
||
var=option2
|
||
var=option3
|
||
</programlisting>
|
||
Каждая опция будет перезаписывать содержимое предыдущей переменной
|
||
<varname>$var</varname>. Решение — использовать функцию
|
||
PHP «массив из элемента формы». Как в следующем примере:
|
||
<programlisting role="html">
|
||
<![CDATA[
|
||
<select name="var[]" multiple="yes">
|
||
]]>
|
||
</programlisting>
|
||
Это говорит PHP рассматривать переменную <varname>$var</varname> как массив и
|
||
каждое присваивание значения для var[] добавляет элемент в массив.
|
||
Первым элементом будет <varname>$var[0]</varname>, следующим —
|
||
<varname>$var[1]</varname> и т. д. Можно использовать функцию <function>count</function>,
|
||
чтобы определить, сколько элементов было выбрано,
|
||
а функцию <function>sort</function> — для сортировки массива опций, если это необходимо.
|
||
</para>
|
||
<para>
|
||
Заметьте, если вы используете JavaScript, есть риск того, что запись <literal>[]</literal>
|
||
в имени элемента вызовет проблемы, если вы пытаетесь обращаться к
|
||
элементу по имени. Вместо этого указывайте числовой идентификатор элемента формы или
|
||
возьмите имя переменной в одинарные кавычки и используйте его как
|
||
индекс массива элементов, например:
|
||
<programlisting>
|
||
variable = document.forms[0].elements['var[]'];
|
||
</programlisting>
|
||
</para>
|
||
</answer>
|
||
</qandaentry>
|
||
|
||
<qandaentry xml:id="faq.html.javascript-variable">
|
||
<question>
|
||
<para>
|
||
Как передать переменную из JavaScript в PHP?
|
||
</para>
|
||
</question>
|
||
<answer>
|
||
<para>
|
||
Поскольку JavaScript — обычно клиентская технология,
|
||
а PHP, как правило, серверная, и поскольку
|
||
HTML — протокол «без состояния», эти два языка не умеют обмениваться
|
||
переменными напрямую.
|
||
</para>
|
||
<para>
|
||
Однако можно передавать переменные между ними.
|
||
Один из способов добиться этого — сгенерировать JavaScript-код
|
||
из PHP и принудительно обновлять браузер, посылая определённые
|
||
переменные обратно PHP-скрипту. Пример показывает,
|
||
как это сделать — он разрешает PHP-коду захватывать высоту и ширину
|
||
экрана, что обычно возможно только на стороне клиента.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Генерирование JavaScript из PHP</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
if (isset($_GET['width']) AND isset($_GET['height'])) {
|
||
// Выводим переменные с размерами
|
||
echo "Ширина экрана: " . $_GET['width'] . "<br />\n";
|
||
echo "Высота экрана: " . $_GET['height'] . "<br />\n";
|
||
} else {
|
||
// Передаём переменные с размерами
|
||
// (сохраняем оригинальную строку запроса
|
||
// — POST-переменные нужно будет передавать другим способом)
|
||
|
||
echo "<script>\n";
|
||
echo " location.href = \"{$_SERVER['SCRIPT_NAME']}?{$_SERVER['QUERY_STRING']}"
|
||
. "&width=\" + screen.width + \"&height=\" + screen.height;\n";
|
||
echo "</script>\n";
|
||
exit;
|
||
}
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
</answer>
|
||
</qandaentry>
|
||
|
||
</qandaset>
|
||
</chapter>
|
||
<!-- Keep this comment at the end of the file
|
||
Local variables:
|
||
mode: sgml
|
||
sgml-omittag:t
|
||
sgml-shorttag:t
|
||
sgml-minimize-attributes:nil
|
||
sgml-always-quote-attributes:t
|
||
sgml-indent-step:1
|
||
sgml-indent-data:t
|
||
indent-tabs-mode:nil
|
||
sgml-parent-document:nil
|
||
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
||
sgml-exposed-tags:nil
|
||
sgml-local-catalogs:nil
|
||
sgml-local-ecat-files:nil
|
||
End:
|
||
vim600: syn=xml fen fdm=syntax fdl=2 si
|
||
vim: et tw=78 syn=sgml
|
||
vi: ts=1 sw=1
|
||
-->
|