Files
php-doc-ru/language/variables.xml
Sergey Panteleev fe3a5e7e09 docs(ru): Updated to English revision
git-svn-id: https://svn.php.net/repository/phpdoc/ru/trunk@350724 c90b9560-bf6c-de11-be94-00142212c4b1
2020-10-01 05:00:25 +00:00

1169 lines
48 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: e293d971f5687a0809c514c7f7db9ed4e5cdfa20 Maintainer: sergey Status: ready -->
<!-- Reviewed: no -->
<chapter xml:id="language.variables" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Переменные</title>
<sect1 xml:id="language.variables.basics">
<title>Основы</title>
<simpara>
Переменные в PHP представлены знаком доллара с последующим
именем переменной. Имя переменной чувствительно к регистру.
</simpara>
<para>
Имена переменных соответствуют тем же правилам, что и
остальные наименования в PHP. Правильное имя переменной должно
начинаться с буквы или символа подчеркивания и состоять из
букв, цифр и символов подчеркивания в любом количестве.
Это можно отобразить регулярным выражением:
<code>^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$</code>
</para>
<note>
<simpara>
Под буквами здесь подразумеваются символы a-z, A-Z и байты от
128 до 255 (<literal>0x80-0xff</literal>).
</simpara>
</note>
<note>
<simpara>
<literal>$this</literal> - это специальная переменная, которой
нельзя ничего присваивать.
До PHP 7.1.0 было возможно косвенное присвоение (например, с использованием
<link linkend="language.variables.variable">переменных переменных</link>)).
</simpara>
</note>
&tip.userlandnaming;
<para>
Для информации о функциях работы с переменными обращайтесь
к разделу
<link linkend="ref.var">функций работы с переменными</link>.
</para>
<para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$var = 'Боб';
$Var = 'Джо';
echo "$var, $Var"; // выведет "Боб, Джо"
$4site = 'еще нет'; // неверно; начинается с цифры
$_4site = 'еще нет'; // верно; начинается с символа подчеркивания
$täyte = 'mansikka'; // верно; 'ä' это (Расширенный) ASCII 228.
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
По умолчанию переменные всегда присваиваются по значению. То есть,
когда вы присваиваете выражение переменной, все значение
оригинального выражения копируется в эту переменную. Это
означает, к примеру, что после того как одной переменной присвоено
значение другой, изменение одной из них не влияет на
другую. Дополнительную информацию об этом способе присвоения
смотрите в разделе <link linkend="language.expressions">Выражения</link>.
</para>
<para>
PHP также предлагает иной способ присвоения значений переменным:
<link linkend="language.references">присвоение по ссылке</link>.
Это означает, что новая переменная просто ссылается (иначе говоря,
"становится псевдонимом" или "указывает") на оригинальную
переменную. Изменения в новой переменной отражаются на оригинале,
и наоборот.
</para>
<para>
Для присвоения по ссылке, просто добавьте амперсанд (&amp;) к
началу имени присваиваемой (исходной) переменной. Например,
следующий фрагмент кода дважды выводит '<literal>Меня зовут Боб</literal>':
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$foo = 'Боб'; // Присваивает $foo значение 'Боб'
$bar = &$foo; // Ссылка на $foo через $bar.
$bar = "Меня зовут $bar"; // Изменение $bar...
echo $bar;
echo $foo; // меняет и $foo.
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Важно отметить, что по ссылке могут быть присвоены только
именованные переменные.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$foo = 25;
$bar = &$foo; // Это верное присвоение.
$bar = &(24 * 7); // Неверно; ссылка на неименованное выражение.
function test()
{
return 25;
}
$bar = &test(); // Неверно.
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Хорошей практикой считается инициализировать переменные, хотя в PHP
это и не является обязательным требованием. Неинициализированные переменные
принимают значение по умолчанию в зависимости от их типа, который
определяется из контекста их первого использования: булевы
принимают значение &false;, целые числа и числа с плавающей точкой -
ноль, строки (например, при использовании в <function>echo</function>)
- пустую строку, а массивы становятся пустыми массивами.
</para>
<para>
<example>
<title>Значения по умолчанию в неинициализированных переменных</title>
<programlisting role="php">
<![CDATA[
<?php
// Неустановленная И не имеющая ссылок (то есть без контекста использования) переменная; выведет NULL
var_dump($unset_var);
// Булевое применение; выведет 'false' (Подробнее по этому синтаксису смотрите раздел о тернарном операторе)
echo($unset_bool ? "true\n" : "false\n");
// Строковое использование; выведет 'string(3) "abc"'
$unset_str .= 'abc';
var_dump($unset_str);
// Целочисленное использование; выведет 'int(25)'
$unset_int += 25; // 0 + 25 => 25
var_dump($unset_int);
// Использование в качестве числа с плавающей точкой (float/double); выведет 'float(1.25)'
$unset_float += 1.25;
var_dump($unset_float);
// Использование в качестве массива; выведет array(1) { [3]=> string(3) "def" }
$unset_arr[3] = "def"; // array() + array(3 => "def") => array(3 => "def")
var_dump($unset_arr);
// Использование в качестве объекта; создает новый объект stdClass (см. http://www.php.net/manual/ru/reserved.classes.php)
// Выведет: object(stdClass)#1 (1) { ["foo"]=> string(3) "bar" }
$unset_obj->foo = 'bar';
var_dump($unset_obj);
?>
]]>
</programlisting>
</example>
</para>
<para>
Полагаться на значения по умолчанию неинициализированных переменных
довольно проблематично при включении файла в другой файл,
использующий переменную с таким же именем. Это также большой
<link linkend="security.globals">риск в системе безопасности</link> при
включенной опции <link linkend="ini.register-globals">register_globals</link>.
В случае работы с неинициализированной переменной вызывается ошибка уровня
<link linkend="errorfunc.constants.errorlevels.e-notice">E_NOTICE</link>,
за исключением случая добавления элементов в неинициализированный массив.
Для обнаружения инициализации переменной может быть использована
языковая конструкция <function>isset</function>.
</para>
</sect1>
<sect1 xml:id="language.variables.predefined">
<title>Предопределенные переменные</title>
<para>
Любому запускаемому скрипту PHP предоставляет большое количество
предопределенных переменных. Однако многие из этих переменных не
могут быть полностью задокументированы, поскольку они зависят от
запускающего скрипт сервера, его версии и настроек, а также других факторов.
Некоторые из этих переменных недоступны, когда PHP запущен из
<link linkend="features.commandline">командной строки</link>.
Перечень этих переменных смотрите в разделе
<link linkend="reserved.variables">Зарезервированные
предопределенные переменные</link>.
</para>
<para>
PHP предоставляет дополнительный набор
предопределенных массивов, содержащих переменные сервера (если
они доступны), окружения и пользовательского ввода. Эти
массивы являются особыми, поскольку они становятся глобальными автоматически
- то есть, автоматически доступны в любой области видимости. По этой
причине они также известны как 'автоглобальные' или 'суперглобальные'
переменные. (В PHP нет механизма определяемых пользователем
суперглобальных переменных.) О суперглобальных переменных можно
прочитать <link linkend="language.variables.superglobals">здесь</link>;
однако, перечисление их содержимого и дальнейшее обсуждение
предопределенных переменных PHP и их сути смотрите в разделе
<link linkend="reserved.variables">Зарезервированные
предопределенные переменные</link>.
</para>
<note>
<para>
До PHP 5.4, доступен старый способ доступа к информации связанной с
HTTP-запросом, с помощью переменных <literal>HTTP_*_VARS</literal>.
Эта возможность может быть отключена с помощью директивы
<link linkend="ini.register-long-arrays">register_long_arrays</link>
начиная с PHP 5.0.0.
</para>
</note>
<note>
<title>Переменные переменных</title>
<para>
Суперглобальные переменные не могут быть
<link linkend="language.variables.variable">переменными переменных</link>
внутри функций или методов класса.
</para>
</note>
<para>
Если некоторые из переменных в
<link linkend="ini.variables-order">variables_order</link> не установлены,
соответствующие им предопределенные массивы также останутся пустыми.
</para>
</sect1>
<sect1 xml:id="language.variables.scope">
<title>Область видимости переменной</title>
<simpara>
Область видимости переменной - это контекст, в котором эта переменная определена.
В большинстве случаев все переменные PHP имеют только одну область
видимости. Эта единая область видимости охватывает также
включаемые (include) и требуемые (require) файлы. Например:
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$a = 1;
include 'b.inc';
?>
]]>
</programlisting>
</informalexample>
<simpara>
Здесь переменная <varname>$a</varname> будет доступна внутри
включенного скрипта <filename>b.inc</filename>. Однако определение (тело)
пользовательской функции задает локальную область видимости данной функции.
Любая используемая внутри функции переменная
по умолчанию ограничена локальной областью видимости функции.
Например:
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$a = 1; /* глобальная область видимости */
function test()
{
echo $a; /* ссылка на переменную в локальной области видимости */
}
test();
?>
]]>
</programlisting>
</informalexample>
<simpara>
Этот скрипт не сгенерирует никакого вывода, поскольку выражение
echo указывает на локальную версию переменной
<varname>$a</varname>, а в пределах этой области видимости ей
не было присвоено значение. Возможно вы заметили, что это немного
отличается от языка C в том, что глобальные переменные в C
автоматически доступны функциям, если только они не были
перезаписаны локальным определением. Это может вызвать некоторые
проблемы, поскольку люди могут нечаянно изменить глобальную
переменную. В PHP, если глобальная переменная будет использоваться
внутри функции, она должна быть объявлена глобальной внутри определения функции.
</simpara>
<sect2 xml:id="language.variables.scope.global">
<title>Ключевое слово <literal>global</literal></title>
<simpara>
Сначала пример использования <literal>global</literal>:
</simpara>
<para>
<example>
<title>Использование <literal>global</literal></title>
<programlisting role="php">
<![CDATA[
<?php
$a = 1;
$b = 2;
function Sum()
{
global $a, $b;
$b = $a + $b;
}
Sum();
echo $b;
?>
]]>
</programlisting>
</example>
</para>
<simpara>
Вышеприведенный скрипт выведет <literal>3</literal>. После определения
<varname>$a</varname> и <varname>$b</varname> внутри функции как
global все ссылки на любую из этих переменных будут указывать на
их глобальную версию. Не существует никаких ограничений на
количество глобальных переменных, которые могут обрабатываться
функцией.
</simpara>
<simpara>
Второй способ доступа к переменным глобальной области видимости -
использование специального, определяемого PHP массива
<varname>$GLOBALS</varname>. Предыдущий пример может быть переписан
так:
</simpara>
<para>
<example>
<title>Использование <varname>$GLOBALS</varname> вместо global</title>
<programlisting role="php">
<![CDATA[
<?php
$a = 1;
$b = 2;
function Sum()
{
$GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
}
Sum();
echo $b;
?>
]]>
</programlisting>
</example>
</para>
<simpara>
<varname>$GLOBALS</varname> - это ассоциативный массив, ключом
которого является имя, а значением - содержимое глобальной
переменной. Обратите внимание, что <varname>$GLOBALS</varname>
существует в любой области видимости, это объясняется тем, что
<varname>$GLOBALS</varname> является
<link linkend="language.variables.superglobals">суперглобальным</link>.
Ниже приведен пример, демонстрирующий возможности
суперглобальных переменных:
</simpara>
<para>
<example>
<title>Суперглобальные переменные и область видимости</title>
<programlisting role="php">
<![CDATA[
<?php
function test_superglobal()
{
echo $_POST['name'];
}
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
Использование ключевого слова <literal>global</literal> вне
функции не является ошибкой. Оно может быть использовано в файле,
который включается внутри функции.
</para>
</note>
</sect2>
<sect2 xml:id="language.variables.scope.static">
<title>Использование статических (<literal>static</literal>) переменных</title>
<simpara>
Другой важной особенностью области видимости переменной является
<emphasis>статическая</emphasis> переменная. Статическая
переменная существует только в локальной области видимости
функции, но не теряет своего значения, когда выполнение программы
выходит из этой области видимости. Рассмотрим следующий пример:
</simpara>
<para>
<example>
<title>Демонстрация необходимости статических переменных</title>
<programlisting role="php">
<![CDATA[
<?php
function test()
{
$a = 0;
echo $a;
$a++;
}
?>
]]>
</programlisting>
</example>
</para>
<simpara>
Эта функция довольно бесполезна, поскольку при каждом вызове она
устанавливает <varname>$a</varname> в <literal>0</literal> и
выводит <literal>0</literal>. Инкремент переменной <varname>$a</varname>++
здесь не играет роли, так как при выходе из функции переменная
<varname>$a</varname> исчезает. Чтобы написать полезную
функцию подсчета, которая не будет терять текущего значения счетчика,
переменная <varname>$a</varname> объявляется как static:
</simpara>
<para>
<example>
<title>Пример использования статических переменных</title>
<programlisting role="php">
<![CDATA[
<?php
function test()
{
static $a = 0;
echo $a;
$a++;
}
?>
]]>
</programlisting>
</example>
</para>
<simpara>
Теперь <varname>$a</varname> будет проинициализирована только при
первом вызове функции, а каждый вызов функции <literal>test()</literal>
будет выводить значение <varname>$a</varname> и инкрементировать его.
</simpara>
<simpara>
Статические переменные также дают возможность работать с
рекурсивными функциями. Рекурсивной является функция, вызывающая
саму себя. При написании рекурсивной функции нужно быть
внимательным, поскольку есть вероятность сделать рекурсию
бесконечной. Вы должны убедиться, что существует адекватный
способ завершения рекурсии. Следующая простая функция рекурсивно
считает до 10, используя для определения момента остановки
статическую переменную <varname>$count</varname>:
</simpara>
<para>
<example>
<title>Статические переменные и рекурсивные функции</title>
<programlisting role="php">
<![CDATA[
<?php
function test()
{
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
test();
}
$count--;
}
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
Статические переменные могут быть объявлены так, как показано в предыдущем примере.
Начиная с PHP 5.6 стало возможным присвоить этим переменным значения, являющиеся
результатом выражения, но нельзя использовать для этого функцию, так это
вызовет ошибку разбора.
</para>
<para>
<example>
<title>Объявление статических переменных</title>
<programlisting role="php">
<![CDATA[
<?php
function foo() {
static $int = 0; // верно
static $int = 1+2; // верно (начиная с PHP 5.6)
static $int = sqrt(121); // неверно (поскольку это функция)
$int++;
echo $int;
}
?>
]]>
</programlisting>
</example>
</para>
</note>
<note>
<para>
Статические объявления вычисляются во время компиляции скрипта.
</para>
</note>
</sect2>
<sect2 xml:id="language.variables.scope.references">
<title>Ссылки с глобальными (<literal>global</literal>) и статическими (<literal>static</literal>) переменными</title>
<simpara>
PHP использует модификаторы переменных
<link linkend="language.variables.scope.static">static</link> и
<link linkend="language.variables.scope.global">global</link> как
<link linkend="language.references">ссылки</link>. Например, реальная
глобальная переменная, внедренная в область видимости функции указанием
ключевого слова <literal>global</literal>, в действительности создает
ссылку на глобальную переменную. Это может привести к неожиданному
поведению, как это показано в следующем примере:
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
function test_global_ref() {
global $obj;
$new = new stdclass;
$obj = &$new;
}
function test_global_noref() {
global $obj;
$new = new stdclass;
$obj = $new;
}
test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?>
]]>
</programlisting>
</informalexample>
&example.outputs;
<screen>
<![CDATA[
NULL
object(stdClass)#1 (0) {
}
]]>
</screen>
<simpara>
Аналогично ведет себя и выражение <literal>static</literal>. Ссылки не
хранятся статично:
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
function &get_instance_ref() {
static $obj;
echo 'Статический объект: ';
var_dump($obj);
if (!isset($obj)) {
$new = new stdclass;
// Присвоить ссылку статической переменной
$obj = &$new;
}
if (!isset($obj->property)) {
$obj->property = 1;
} else {
$obj->property++;
}
return $obj;
}
function &get_instance_noref() {
static $obj;
echo 'Статический объект: ';
var_dump($obj);
if (!isset($obj)) {
$new = new stdclass;
// Присвоить объект статической переменной
$obj = $new;
}
if (!isset($obj->property)) {
$obj->property = 1;
} else {
$obj->property++;
}
return $obj;
}
$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();
?>
]]>
</programlisting>
</informalexample>
&example.outputs;
<screen>
<![CDATA[
Статический объект: NULL
Статический объект: NULL
Статический объект: NULL
Статический объект: object(stdClass)#3 (1) {
["property"]=>
int(1)
}
]]>
</screen>
<simpara>
Этот пример демонстрирует, что при присвоении ссылки статической
переменной она не <emphasis>запоминается</emphasis>, когда вы
вызываете функцию <literal>&amp;get_instance_ref()</literal> во
второй раз.
</simpara>
</sect2>
</sect1>
<sect1 xml:id="language.variables.variable">
<title>Переменные переменных</title>
<simpara>
Иногда бывает удобно иметь переменными имена переменных. То есть,
имя переменной, которое может быть определено и изменено
динамически. Обычная переменная определяется примерно таким
выражением:
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$a = 'hello';
?>
]]>
</programlisting>
</informalexample>
<simpara>
Переменная переменной берет значение переменной и рассматривает
его как имя переменной. В вышеприведенном примере
<emphasis>hello</emphasis> может быть использовано как имя
переменной при помощи двух знаков доллара. То есть:
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$$a = 'world';
?>
]]>
</programlisting>
</informalexample>
<simpara>
Теперь в дереве символов PHP определены и содержатся две
переменные: <varname>$a</varname>, содержащая "hello" и
<varname>$hello</varname>, содержащая "world". Таким образом,
выражение
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
echo "$a ${$a}";
?>
]]>
</programlisting>
</informalexample>
<simpara>
выведет то же, что и
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
echo "$a $hello";
?>
]]>
</programlisting>
</informalexample>
<simpara>
то есть, они оба выведут: <computeroutput>hello world</computeroutput>.
</simpara>
<simpara>
Для того чтобы использовать переменные переменных с массивами, вы должны решить
проблему двусмысленности. То есть, если вы напишете <varname>$$a[1]</varname>,
обработчику необходимо знать, хотите ли вы использовать <varname>$a[1]</varname> в
качестве переменной, либо вам нужна как переменная <varname>$$a</varname>, а затем
ее индекс [1]. Синтаксис для разрешения этой двусмысленности таков: <varname>${$a[1]}
</varname> для первого случая и <varname>${$a}[1]</varname> для второго.
</simpara>
<simpara>
К свойствам класса также можно получить доступ динамически. Переменное имя свойства
будет разрешено в том контексте, в котором произойдет вызов к нему. Например, в случае
выражения <varname>$foo->$bar</varname>, локальная область видимости будет
просканирована на наличие переменной <varname>$bar</varname>, значение которой
будет использовано в качестве имени свойства объекта <varname>$foo</varname>.
Это также работает и в том случае, если <varname>$bar</varname> осуществляет доступ
к элементу массива.
</simpara>
<caution>
<simpara>
Разыменование свойства, которое представляет собой массив имеет разную семантику
в PHP 5 и PHP 7. <link linkend="migration70.incompatible.variable-handling.indirect">руководство по миграции на PHP 7.0</link>
включает в себя более подробную информацию о типах выражений, которые были
изменены и как правильно использовать фигурные скобки, чтобы избежать
неоднозначности.
</simpara>
</caution>
<simpara>
Фигурные скобки могут также использоваться, чтобы четко разграничить имя
свойства. Они наиболее полезны при получении доступа к значениям внутри свойства,
которое содержит массив, когда имя свойства состоит из нескольких частей,
либо когда имя свойства содержит символы, которые иначе не
действительны (например, из функции <function>json_decode</function>
или из <link linkend="book.simplexml">SimpleXML</link>).
</simpara>
<para>
<example>
<title>Пример переменного имени свойства</title>
<programlisting role="php">
<![CDATA[
<?php
class foo {
var $bar = 'I am bar.';
var $arr = array('I am A.', 'I am B.', 'I am C.');
var $r = 'I am r.';
}
$foo = new foo();
$bar = 'bar';
$baz = array('foo', 'bar', 'baz', 'quux');
echo $foo->$bar . "\n";
echo $foo->{$baz[1]} . "\n";
$start = 'b';
$end = 'ar';
echo $foo->{$start . $end} . "\n";
$arr = 'arr';
echo $foo->{$arr[1]} . "\n";
?>
]]>
</programlisting>
&example.outputs;
<screen>
I am bar.
I am bar.
I am bar.
I am r.
</screen>
</example>
</para>
<warning>
<simpara>
Обратите внимание, что переменные переменных не могут
использоваться с
<link linkend="language.variables.superglobals">cуперглобальными массивами</link>
PHP. Переменная <literal>$this</literal> также является особой, на нее
нельзя ссылаться динамически.
</simpara>
</warning>
</sect1>
<sect1 xml:id="language.variables.external">
<title>Переменные извне PHP</title>
<sect2 xml:id="language.variables.external.form">
<title>HTML-формы (GET и POST)</title>
<simpara>
Когда происходит отправка данных формы PHP-скрипту, информация из
этой формы автоматически становится доступной ему. Существует
несколько способов получения этой информации, например:
</simpara>
<para>
<example>
<title>Простая HTML-форма</title>
<programlisting role="html">
<![CDATA[
<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>
]]>
</programlisting>
</example>
</para>
<para>
С версии PHP 5.4.0, есть только два способа получить доступ к данным из форм HTML.
Доступные сейчас способы приведены ниже:
</para>
<para>
<example>
<title>Доступ к данным из простой HTML-формы, отправленной через POST</title>
<programlisting role="php">
<![CDATA[
<?php
echo $_POST['username'];
echo $_REQUEST['username'];
?>
]]>
</programlisting>
</example>
</para>
<para>
В старых версиях PHP также существовало несколько других способов.
Они приведены ниже. Смотрите также список изменений внизу страницы.
<example>
<title>Старые способы получения пользовательских данных</title>
<programlisting role="php">
<![CDATA[
<?php
// ВНИМАНИЕ: эти методы больше НЕ поддерживаются.
// Использование import_request_variables() - эта функция удалена в PHP 5.4.0
import_request_variables('p', 'p_');
echo $p_username;
// Эти длинные предопределенные массивы удалены в PHP 5.4.0
echo $HTTP_POST_VARS['username'];
// Использование register_globals. Эта функциональность удалена в PHP 5.4.0
echo $username;
?>
]]>
</programlisting>
</example>
</para>
<para>
GET-форма используется аналогично, за исключением того, что вместо
POST, вам нужно будет использовать соответствующую предопределенную
переменную GET. GET относится также к <literal>QUERY_STRING</literal>
(информация в URL после '?'). Так, например,
<literal>http://www.example.com/test.php?id=3</literal> содержит
GET-данные, доступные как <varname>$_GET['id']</varname>. Смотрите
также <varname>$_REQUEST</varname>.
</para>
<note>
<para>
Точки и пробелы в именах переменных преобразуется в знаки
подчеркивания. Например, <literal>&lt;input name="a.b" /&gt;</literal> станет
<literal>$_REQUEST["a_b"]</literal>.
</para>
</note>
<simpara>
PHP также понимает массивы в контексте переменных формы
(смотрите <link linkend="faq.html">соответствующие ЧАВО</link>).
К примеру, вы можете сгруппировать связанные переменные вместе
или использовать эту возможность для получения значений списка
множественного выбора select. Например, давайте отправим форму
самой себе, а после отправки отобразим данные:
</simpara>
<para>
<example>
<title>Более сложные переменные формы</title>
<programlisting role="php">
<![CDATA[
<?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>
]]>
</programlisting>
</example>
</para>
<note>
<simpara>
Если внешнее имя переменной начинается с корректного синтаксиса массива,
завершающие символы молча игнорируются.
Например, <literal>&lt;input name="foo[bar]baz"&gt;</literal>
becomes <literal>$_REQUEST['foo']['bar']</literal>.
</simpara>
</note>
<sect3 xml:id="language.variables.external.form.submit">
<title>Имена переменных кнопки-изображения</title>
<simpara>
При отправке формы вместо стандартной кнопки можно использовать
изображение с помощью тега такого вида:
</simpara>
<informalexample>
<programlisting role="html">
<![CDATA[
<input type="image" src="image.gif" name="sub" />
]]>
</programlisting>
</informalexample>
<simpara>
Когда пользователь щелкнет где-нибудь на изображении,
соответствующая форма будет передана на сервер с двумя
дополнительными переменными - <varname>sub_x</varname> и <varname>sub_y</varname>.
Они содержат координаты нажатия пользователя на изображение. Опытные
программисты могут заметить, что на самом деле имена переменных,
отправленных браузером, содержат точку, а не подчеркивание, но
PHP автоматически преобразует точку в подчеркивание.
</simpara>
</sect3>
</sect2>
<sect2 xml:id="language.variables.external.cookies">
<title>HTTP Cookies</title>
<simpara>
PHP прозрачно поддерживает HTTP cookies как определено в <link
xlink:href="&url.rfc;6265">RFC 6265</link>. Cookies - это
механизм для хранения данных в удаленном браузере и, таким образом, отслеживание и
идентификации вернувшихся пользователей. Вы можете
установить cookies, используя функцию <function>setcookie</function>.
Cookies являются частью HTTP-заголовка, поэтому функция SetCookie
должна вызываться до того, как браузеру будет отправлен какой бы то
ни было вывод. Это то же ограничение, что и для функции
<function>header</function>. Данные, хранящиеся в cookie, доступны
в соответствующих массивах данных cookie, таких как
<varname>$_COOKIE</varname> и <varname>$_REQUEST</varname>. Подробности и примеры
смотрите в справочной странице <function>setcookie</function>.
</simpara>
<note>
<simpara>
Начиная с PHP 7.2.34, 7.3.23 и 7.4.11, соответственно, <emphasis>имена</emphasis>
входящих cookie больше не декодируются из URL-закодированной строки из соображений безопасности.
</simpara>
</note>
<simpara>
Если вы хотите присвоить множество значений одной переменной cookie,
вы можете присвоить их как массив. Например:
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
setcookie("MyCookie[foo]", 'Testing 1', time()+3600);
setcookie("MyCookie[bar]", 'Testing 2', time()+3600);
?>
]]>
</programlisting>
</informalexample>
<simpara>
Это создаст две разные cookie, хотя в вашем скрипте <varname>MyCookie</varname> будет
теперь одним массивом. Если вы хотите установить именно одну cookie
со множеством значений, сначала рассмотрите возможность использования к
значениям такие функции, как <function>serialize</function> или
<function>explode</function>.
</simpara>
<simpara>
Обратите внимание, что cookie заменит предыдущую cookie с тем же
именем в вашем браузере, если только путь или домен не отличаются.
Так, для приложения корзины покупок вы, возможно, захотите
сохранить счетчик. То есть:
</simpara>
<example>
<title>Пример использования <function>setcookie</function></title>
<programlisting role="php">
<![CDATA[
<?php
if (isset($_COOKIE['count'])) {
$count = $_COOKIE['count'] + 1;
} else {
$count = 1;
}
setcookie('count', $count, time()+3600);
setcookie("Cart[$count]", $item, time()+3600);
?>
]]>
</programlisting>
</example>
</sect2>
<sect2 xml:id="language.variables.external.dot-in-names">
<title>Точки в именах приходящих переменных</title>
<para>
Как правило, PHP не меняет передаваемых скрипту имен переменных.
Однако следует отметить, что точка не является корректным
символом в имени переменной PHP. Поэтому рассмотрим такую запись:
<programlisting role="php">
<![CDATA[
<?php
$varname.ext; /* неверное имя переменной */
?>
]]>
</programlisting>
В данном случае интерпретатор видит переменную
<varname>$varname</varname>, после которой идет оператор
конкатенации, а затем голая строка (то есть, не заключенная в
кавычки строка, не соответствующая ни одному из ключевых или
зарезервированных слов) 'ext'. Очевидно, что это не даст
ожидаемого результата.
</para>
<para>
По этой причине важно отметить, что PHP будет автоматически
заменять любые точки в именах, приходящих переменных на символы
подчеркивания.
</para>
</sect2>
<sect2 xml:id="language.variables.determining-type-of">
<title>Определение типов переменных</title>
<para>
Поскольку PHP определяет типы переменных и преобразует их (как правило) по мере необходимости,
не всегда очевидно, какой тип имеет данная переменная в любой момент времени. PHP
содержит несколько функций, позволяющих определить тип
переменной, таких как: <function>gettype</function>,
<function>is_array</function>, <function>is_float</function>,
<function>is_int</function>, <function>is_object</function> и
<function>is_string</function>. Смотрите также раздел
<link linkend="language.types">Типы</link>.
</para>
<para>
HTTP является текстовым протоколом, и большинство, если не всё, содержимое,
которое приходит в <link linkend="language.variables.superglobals">cуперглобальные массивы</link>,
например <varname>$_POST</varname> и <varname>$_GET</varname>, останется в виде строк.
PHP не будет преобразовывать значения в определенный тип.
В приведенном ниже примере <varname>$_GET["var1"]</varname>
будет содержать строку "null", а <varname>$_GET["var2"]</varname> строку "123".
<programlisting>
<![CDATA[
/index.php?var1=null&var2=123
]]>
</programlisting>
</para>
</sect2>
<sect2 xml:id="language.variables.external.changelog">
&reftitle.changelog;
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>7.2.34, 7.3.23, 7.4.11</entry>
<entry>
<emphasis>имена</emphasis> входящих cookie больше не декодируются
из URL-закодированной строки из соображений безопасности.
</entry>
</row>
<row>
<entry>5.3.0, 5.4.0</entry>
<entry>
<link linkend="security.globals">Регистрация глобальных переменных</link>,
<link linkend="security.magicquotes">Магические кавычки</link> и
<link linkend="ini.register-long-arrays">register_long_arrays</link>
стали устаревшими
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</sect2>
</sect1>
</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
-->