PHP и HTML
PHP и HTML тесно взаимодействуют: PHP может генерировать HTML, а HTML может передавать информацию PHP. Перед чтением вопросов в этом разделе важно чтобы вы понимали как получать переменные извне PHP. Страницы руководства по этой теме содержат много примеров. Обращайте особое внимание на то, что register_globals значит для вас.
- Какое кодирование/декодирование я должен выполнять при передаче значения через форму/URL?
- Я пытаюсь использовать <input type="image">, но переменные $foo.x и $foo.y недоступны. $_GET['foo.x'] тоже не существует. Где они?
- Как создать массивы в HTML <form>?
- Как получить все результаты из HTML тэга select с опцией multiple?
- Как я могу передать переменную из JavaScript в PHP?
- Какое кодирование/декодирование я должен выполнять при передаче значения через форму/URL?
-
Здесь несколько этапов, на которых кодировка важна. Предположим, что у вас есть $data типа string, содержащая строку, которую вы хотите передать без кодирования. Вот эти этапы:
-
Интерпретация HTML. Для того, чтобы задать произвольную строку, вы должны заключить её в двойные кавычки и вызвать htmlspecialchars() на все значение.
-
URL: URL состоит из нескольких частей. Если вы хотите чтобы ваши данные были восприняты как один элемент, вы должны закодировать их с помощью urlencode().
Пример #1 Скрытый элемент HTML формы
<?php
echo '<input type="hidden" value="' . htmlspecialchars($data) . '" />'."\n";
?>Замечание: Использовать urlencode() для $data неправильно, так как кодировать данные в urlencode() это обязанность браузера. Все популярные браузеры делают это правильно. Отметьте, что это происходит вне зависимости от метода (например, GET или POST). Однако, вы заметите это только в случае GET запроса, так как POST запросы обычно скрыты.
Пример #2 Данные, редактируемые пользователем
<?php
echo "<textarea name='mydata'>\n";
echo htmlspecialchars($data)."\n";
echo "</textarea>";
?>Замечание: Данные показываются браузером как предполагается, потому что браузер будет интерпретировать экранированные HTML символы. При отправке через GET или POST данные будут закодированы (urlencoded) браузером для передачи и раскодированы (urldecoded) PHP. Поэтому вам не надо выполнять какое-либо url-кодирование/раскодирование самим, все выполняется автоматически.
Пример #3 В URL
<?php
echo '<a href="' . htmlspecialchars("/nextpage.php?stage=23&data=" .
urlencode($data)) . '">'."\n";
?>Замечание: На самом деле вы представляетесь HTML GET запросом, поэтому необходимо вручную закодировать (urlencode()) данные.
Замечание: Вам надо применить htmlspecialchars() на полный URL, потому что URL появляется как значение HTML атрибута. В этом случае, браузер сначала раскодирует все значение (де-htmlspecialchars()) и затем URL. PHP поймет URL правильно, так как вы закодировали данные с urlencode(). Вы заметите, что & в URL заменяется на &. Хотя большинство браузеров это исправляют, если вы забудете об этом, но все же это не всегда возможно. Поэтому, даже если ваш URL не динамический, вам надо закодировать его с помощью htmlspecialchars().
-
- Я пытаюсь использовать <input type="image">, но переменные $foo.x и $foo.y недоступны. $_GET['foo.x'] тоже не существует. Где они?
-
При отправке формы, вместо стандартной кнопки отправки возможно использовать изображение с тэгом как:
<input type="image" src="image.gif" name="foo" />
Так как имена foo.x и foo.y нелегальны в PHP, они автомагически превращаются в foo_x и foo_y. То есть, точки заменяются на подчеркивания. Вы обращаетесь к этим переменным так же как и к любым другим, описанным в разделе о получении переменных извне PHP. Например, $_GET['foo_x'].
Замечание:
Пробелы в именах переменных запроса преобразуются в подчеркивания.
- Как создать массивы в HTML <form>?
-
Для того, чтобы результаты <form> были переданы вашему PHP скрипту как массив, именуйте элементы <input>, <select> или <textarea> следующим образом:
<input name="MyArray[]" /> <input name="MyArray[]" /> <input name="MyArray[]" /> <input name="MyArray[]" />
<input name="MyArray[]" /> <input name="MyArray[]" /> <input name="MyOtherArray[]" /> <input name="MyOtherArray[]" />
<input name="AnotherArray[]" /> <input name="AnotherArray[]" /> <input name="AnotherArray[email]" /> <input name="AnotherArray[phone]" />
Замечание:
Определять ключи массивов в HTML необязательно. Если вы не задаете ключи, массив заполняется в порядке появления элементов в форме. Наш первый пример будет содержать ключи 0, 1, 2 и 3.
Также смотрите Функции для работы с массивами и Переменные извне PHP.
- Как получить все результаты из HTML тэга select с опцией multiple?
-
HTML тэг select с multiple позволяет пользователю выбрать несколько элементов из списка. Эти элементы затем передаются обработчику формы. Проблема в том, что они все переданы с одним и тем же именем. Например:
<select name="var" multiple="yes">
Каждая опция будет затирать содержимое предыдущей переменной $var. Решение - воспользоваться возможностью PHP "массив из элемента формы". Должно быть задано следующее:var=option1 var=option2 var=option3
<select name="var[]" multiple="yes">
Заметьте, что если вы используете JavaScript, то [] в имени элемента может вызвать проблемы, если вы пытаетесь обращаться к элементу по имени. Вместо этого используйте числовой ID элемента формы или заключите имя переменной в одиночные кавычки и используйте как индекс массива элементов, например:
variable = documents.forms[0].elements['var[]'];
- Как я могу передать переменную из JavaScript в PHP?
-
Так как JavaScript является (обычно) клиентской технологией, а PHP является (обычно) серверной технологией, и так как HTML - протокол "без состояния", эти два языка не могут разделять переменные напрямую.
Однако, возможно передавать переменные между ними. Один из способов достичь этого - сгенерировать JavaScript код из PHP и заставить браузер обновиться, посылая определенные переменные назад PHP скрипту. Нижеприведенный пример показывает как это сделать -- он позволяет PHP коду получить высоту и ширину экрана, что, обычно, возможно только на стороне клиента.
Пример #4 Генерирование Javascript из PHP
<?php
if (isset($_GET['width']) AND isset($_GET['height'])) {
// выводим переменные с размерами
echo "Ширина экрана: ". $_GET['width'] ."<br />\n";
echo "Высота экрана: ". $_GET['height'] ."<br />\n";
} else {
// передаем переменные с размерами
// (сохраняем оригинальную строку запроса
// -- post переменные нужно будет передавать другим способом)
echo "<script language='javascript'>\n";
echo " location.href=\"${_SERVER['SCRIPT_NAME']}?${_SERVER['QUERY_STRING']}"
. "&width=\" + screen.width + \"&height=\" + screen.height;\n";
echo "</script>\n";
exit();
}
?>
Коментарии
While previous notes stating that square brackets in the name attribute are valid in HTML 4 are correct, according to this:
http://www.w3.org/TR/xhtml1/#C_8
the type of the name attribute has been changed in XHTML 1.0, meaning that square brackets in XHTML's name attribute are not valid.
Regardless, at the time of writing, the W3C's validator doesn't pick this up on a XHTML document.
If you have a really large form, be sure to check your max_input_vars setting. Your array[] will get truncated if it exceeds this. info.configuration#ini.max-input-vars
The (at least that I've found) best way to pass data from PHP to JS is json_encode. Doing so will convert arrays, strings, numbers, etc. as best as possible.
<?php
$myInt = 7;
// a bunch of special characters to demonstrate proper encoding
$myString = <<<EOF
" ' ; &\ $
EOF;
$myArr = [1, "str", 2];
$myAssocArr = ["foo" => "bar"];
?>
<script>
var myInt = <?= json_encode($myInt) ?>;
var myString = <?= json_encode($myString) ?>;
var myArr = <?= json_encode($myArr) ?>;
var myAssocArr = <?= json_encode($myAssocArr) ?>;
</script>
This will render the following JS code, which correctly stores the variables:
<script>
var myInt = 7;
var myString = "\" ' ; &\\ $";
var myArr = [1,"str",2];
var myAssocArr = {"foo":"bar"};
</script>
Do note that there are no "s or anything like that around the json_encode output; json_encode handles that for you.
Why use such a complicated example for js to php? why not do this..so we can understand:
javascript:
const variable = "A"
php:
do whatever it takes to get A from javascript
The scenario:
1. There is a php script which (possibly complemented by a direct written HTML code) consrtucts a HTML page via its echo command, based on whatever algoritmus eventually based on supplementary data from server files or databases.
2. This php script leads to data being saved into string variable(s), which (possibly) can contain arbitrary characters, including control codes (newline, tab...), HTML special characters (&,<...) and non-ASCII (international) characters.
3. These non-ASCII characters are UTF-8 encoded, as well as the HTML page (I do highly recommend) *)
4. The values of these PHP string variables have to be transferred into javascript variables for further processing by javascript (or exposing these values in HTML directly)
The problem:
it is not safe to PHP-echo such variables into HTML (javascript) directly, because some of characters possily contained in them cause malfunction of the HTML. These strings need some encoding/escaping in order to become strings of non-conflicting characters
The solution
There may be a big lot of ways of this encoding. The following one seems to me the easiest one:
The PHP variable with unpredictable value can originate from some file, as an example (or from user input as well):
$variable=file_get_content(...)
1. Convert all bytes of that string into hex values and prepend all hex-digit-pairs with %
$variable_e=preg_replace("/(..)/","%$1",bin2hex($variable))
The new variable is now guarantied to contain only %1234567890abcdefABCDEF chracters (e.g. %61%63%0a...) and can safely be directly echoed into HTML:
var variable="<?php echo $variable_e;?>" //that's NOT all folks
But now the value is still encoded. To get the original value of the variable, it has te be decoded: *)
var variable=decodeURIComponent("<?php echo $variable_e;?>")
The value of the variable is now the same as the original value.
*) I have no idea about non-UTF-8 encoded pages/data, espetially how the decodeURIComponent works in such a case, because i have no reason to use other encodings and handle them as highly deprecatad.
WARNING: this approach is not (generally) safe against code injection. I highly recommend some further check (parsing) of the value depending on the particular case.
P.S. For very large amount of data, I would recomment to save them into file on the PHP side (file_put_content) and read them by javascript via HTTP Request.
I use this approach as it needs one line of code on server as well as client side. I do agree with arguement that not all chaeacters have to be encoded.
Do not enjoy my possibly stupid solution, if you have a better idea
murphy
I think the last example on this page may have a XSS vulnreability, e.g. sending the query string ?a="+alert('XSS')+" might cause alert('XSS') to be executed in the browser. The problem with that is that " will be percent encoded by the browser, but there could be some way to bypass the percent encoding and i think it's not good to rely on the percent encoding for security.
There is also a very easy XSS with the width and height parameters - they should be passed through htmlspecialchars