PHP Conference Nagoya 2025

Переменные из внешних источников

HTML-формы. Методы GET и POST

PHP-скрипт автоматически получает доступ к данным формы после отправки формы скрипту. Данные формы получают несколькими способами, например:

Пример #1 Простая HTML-форма

<form action="foo.php" method="post">
    Имя:  <input type="text" name="username" /><br />
    Email: <input type="text" name="email" /><br />
    <input type="submit" name="submit" value="Отправь меня!" />
</form>

Доступ к данным HTML-формы получают только двумя способами. Следующие параграфы перечисляют эти способы:

Пример #2 Доступ к данным несложной HTML-формы, которую отправили методом POST

<?php

echo $_POST['username'];
echo
$_REQUEST['username'];

?>

GET-формы обрабатывают аналогично, за исключением того, что вместо суперглобальной переменной POST обрабатывают предопределённую суперглобальную переменную GET. Суперглобальная переменная GET также умеет работать с элементом QUERY_STRING (информация в URL-адресе после знака вопроса «?»). Так, например, адрес http://www.example.com/test.php?id=3 содержит GET-данные, к которым получают доступ через $_GET['id']. О переменных HTTP-запроса рассказывает раздел $_REQUEST.

Замечание:

Точки и пробелы в именах переменных преобразовываются в знаки подчёркивания. Например, <input name="a.b" /> станет $_REQUEST["a_b"].

PHP также понимает массивы в контексте переменных формы (смотрите раздел PHP и HTML). Связанные переменные, например, группируют по имени или получают значения из полей ввода с множественным выбором. Отправим форму сами себе и отобразим данные:

Пример #3 Более сложные переменные формы

<?php

if ($_POST) {
echo
'<pre>';
echo
htmlspecialchars(print_r($_POST, true));
echo
'</pre>';
}

?>
<form action="" method="post">
Имя: <input type="text" name="personal[name]" /><br />
Email: <input type="text" name="personal[email]" /><br />
Пиво: <br />
<select multiple name="beer[]">
<option value="warthog">Warthog</option>
<option value="guinness">Guinness</option>
<option value="stuttgarter">Stuttgarter Schwabenbräu</option>
</select><br />
<input type="submit" value="Отправь меня!" />
</form>

Замечание: PHP без предупреждения проигнорирует конечные символы, если имя внешней переменной начинается с корректного синтаксиса массива. Например, <input name="foo[bar]baz"> станет $_REQUEST['foo']['bar'].

Имена переменных кнопки с картинкой для отправки формы

Чтобы у формы вместо стандартной кнопки отправки появилось изображение, формируют тег наподобие такого:

<input type="image" src="image.gif" name="sub" />

Когда пользователь щёлкнет по изображению, браузер передаст форму на сервер с двумя дополнительными переменными — sub_x и sub_y. Эти переменные содержат координаты места, по которому пользователь нажал на изображении. Программисты с опытом, наверное, заметили, что имена переменных, которые отправил браузер, содержат точку, а не подчёркивание, но PHP автоматически преобразует точку в подчёркивание.

HTTP Cookies

PHP прозрачно поддерживает блоки данных cookies по HTTP-протоколу в соответствии с требованиями стандарта » RFC 6265. Cookies — механизм хранения данных в удалённом браузере, по которым сервер отслеживает или идентифицирует пользователей, которые вернулись на сайт. Cookies устанавливают функцией setcookie(). Cookies — часть HTTP-заголовка, поэтому функцию SetCookie требуется вызывать перед отправкой вывода браузеру. Это же ограничение касается функции header(). Данные, которые хранят cookie, доступны в массивах данных cookie наподобие суперглобальных переменных $_COOKIE или $_REQUEST. Подробности и примеры даёт описание функции setcookie().

Замечание: Начиная с PHP 7.2.34, 7.3.23 и 7.4.11 по соображениям безопасности имена входящих cookie больше не декодируются из URL-кодированной строки.

Когда одной переменной cookie требуется присвоить больше одного значения, значения присваивают как массив. Например:

<?php

setcookie
("MyCookie[foo]", 'Testing 1', time() + 3600);
setcookie("MyCookie[bar]", 'Testing 2', time() + 3600);

?>

Такой вызов создаст два разных блока данных cookie, хотя в скрипте переменная MyCookie теперь будет одним массивом. Если требуется установить только один блок данных cookie с несколькими значениями, сначала обдумывают вызов для таких значений функции наподобие serialize() или explode().

Обратите внимание, что блок данных cookie заменит в браузере предыдущий блок данных cookie с тем же именем, если только путь или домен не отличаются. Так в приложении с корзиной покупок можно сохранить количество товаров:

Пример #4 Пример использования функции setcookie()

<?php

if (isset($_COOKIE['count'])) {
$count = $_COOKIE['count'] + 1;
} else {
$count = 1;
}

setcookie('count', $count, time() + 3600);
setcookie("Cart[$count]", $item, time() + 3600);

?>

Точки в именах входящих переменных

PHP, как правило, не изменяет имена переменных, которые передали скрипту. Однако следует отметить, что точка — неправильный символ в имени переменной PHP. Поэтому рассмотрим такую запись:

<?php

$varname
.ext; /* Неправильное имя переменной */

?>
В приведённом примере интерпретатор видит переменную $varname, после которой идёт оператор конкатенации, а затем голая строка (то есть строка, которую не заключили в кавычки, и которая не соответствует ни одному из ключевых или зарезервированных слов) «ext». Очевидно, что это не даст ожидаемого результата.

Поэтому важно отметить, что PHP будет автоматически заменять точки в именах входящих переменных на символы подчёркивания.

Определение типов переменных

Поскольку PHP определяет типы переменных и преобразовывает типы (как правило) по мере необходимости, не всегда очевидно, какому типу принадлежит переменная в каждый момент времени. PHP содержит несколько функций, которые умеют определять тип переменной, например: gettype(), is_array(), is_float(), is_int(), is_object() и is_string(). Подробнее о типах данных, которые поддерживает PHP, рассказывает раздел «Типы».

HTTP — текстовый протокол, и большая, если не вся, часть содержимого, которое попадает в суперглобальные массивы наподобие $_POST и $_GET, останется в виде строк. PHP не будет преобразовывать значения в конкретный тип. В приведённом примере элемент $_GET["var1"] будет содержать строку «null», а элемент $_GET["var2"] — строку «123».

/index.php?var1=null&var2=123

Список изменений

Версия Описание
7.2.34, 7.3.23, 7.4.11 По соображениям безопасности имена входящих cookie больше не декодируются из URL-кодированной строки.

Добавить

Примечания пользователей 2 notes

up
22
Anonymous
16 years ago
The full list of field-name characters that PHP converts to _ (underscore) is the following (not just dot):
chr(32) ( ) (space)
chr(46) (.) (dot)
chr(91) ([) (open square bracket)
chr(128) - chr(159) (various)

PHP irreversibly modifies field names containing these characters in an attempt to maintain compatibility with the deprecated register_globals feature.
up
4
krydprz at iit dot edu
19 years ago
This post is with regards to handling forms that have more than one submit button.

Suppose we have an HTML form with a submit button specified like this:

<input type="submit" value="Delete" name="action_button">

Normally the 'value' attribute of the HTML 'input' tag (in this case "Delete") that creates the submit button can be accessed in PHP after post like this:

<?php
$_POST
['action_button'];
?>

We of course use the 'name' of the button as an index into the $_POST array.

This works fine, except when we want to pass more information with the click of this particular button.

Imagine a scenario where you're dealing with user management in some administrative interface. You are presented with a list of user names queried from a database and wish to add a "Delete" and "Modify" button next to each of the names in the list. Naturally the 'value' of our buttons in the HTML form that we want to display will be "Delete" and "Modify" since that's what we want to appear on the buttons' faceplates.

Both buttons (Modify and Delete) will be named "action_button" since that's what we want to index the $_POST array with. In other words, the 'name' of the buttons along cannot carry any uniquely identifying information if we want to process them systematically after submit. Since these buttons will exist for every user in the list, we need some further way to distinguish them, so that we know for which user one of the buttons has been pressed.

Using arrays is the way to go. Assuming that we know the unique numerical identifier of each user, such as their primary key from the database, and we DON'T wish to protect that number from the public, we can make the 'action_button' into an array and use the user's unique numerical identifier as a key in this array.

Our HTML code to display the buttons will become:

<input type="submit" value="Delete" name="action_button[0000000002]">
<input type="submit" value="Modify" name="action_button[0000000002]">

The 0000000002 is of course the unique numerical identifier for this particular user.

Then when we handle this form in PHP we need to do the following to extract both the 'value' of the button ("Delete" or "Modify") and the unique numerical identifier of the user we wish to affect (0000000002 in this case). The following will print either "Modify" or "Delete", as well as the unique number of the user:

<?php
$submitted_array
= array_keys($_POST['action_button']);
echo (
$_POST['action_button'][$submitted_array[0]] . " " . $submitted_array[0]);
?>

$submitted_array[0] carries the 0000000002.
When we index that into the $_POST['action_button'], like we did above, we will extract the string that was used as 'value' in the HTML code 'input' tag that created this button.

If we wish to protect the unique numerical identifier, we must use some other uniquely identifying attribute of each user. Possibly that attribute should be encrypted when output into the form for greater security.

Enjoy!
To Top