Files
php-doc-ru/reference/network/functions/setcookie.xml

441 lines
22 KiB
XML
Raw Permalink 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"?>
<!-- EN-Revision: 1ad4e2d550953000e2441b663226300596962ef2 Maintainer: tmn Status: ready -->
<!-- Reviewed: no -->
<refentry xml:id="function.setcookie" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>setcookie</refname>
<refpurpose>Отправляет cookie</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<type>bool</type><methodname>setcookie</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
<methodparam choice="opt"><type>string</type><parameter>value</parameter><initializer>""</initializer></methodparam>
<methodparam choice="opt"><type>int</type><parameter>expires_or_options</parameter><initializer>0</initializer></methodparam>
<methodparam choice="opt"><type>string</type><parameter>path</parameter><initializer>""</initializer></methodparam>
<methodparam choice="opt"><type>string</type><parameter>domain</parameter><initializer>""</initializer></methodparam>
<methodparam choice="opt"><type>bool</type><parameter>secure</parameter><initializer>&false;</initializer></methodparam>
<methodparam choice="opt"><type>bool</type><parameter>httponly</parameter><initializer>&false;</initializer></methodparam>
</methodsynopsis>
<para>Альтернативная сигнатура появилась в PHP 7.3.0 (именованные параметры не поддерживаются):</para>
<methodsynopsis>
<type>bool</type><methodname>setcookie</methodname>
<methodparam><type>string</type><parameter>name</parameter></methodparam>
<methodparam choice="opt"><type>string</type><parameter>value</parameter><initializer>""</initializer></methodparam>
<methodparam choice="opt"><type>array</type><parameter>options</parameter><initializer>[]</initializer></methodparam>
</methodsynopsis>
<para>
Функция <function>setcookie</function> определяет блок данных cookie, который PHP отправит клиенту вместе
с остальными HTTP-заголовками. Как и другие заголовки, блоки данных cookies требуется отправлять
<emphasis>до</emphasis> вывода скрипта (это
ограничение протокола). Поэтому требуется вызывать функцию
перед любым выводом, включая вывод тегов <literal>&lt;html&gt;</literal>
и <literal>&lt;head&gt;</literal>, а также пустые строки и пробельные символы.
</para>
<para>
Как только функция установит cookies, доступ к ним откроется
при следующей загрузке страницы
через суперглобальную переменную <varname>$_COOKIE</varname>.
Значения блоков данных cookie также может содержать суперглобальная переменная <varname>$_REQUEST</varname>.
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
Стандарт <link xlink:href="&url.rfc;6265">RFC 6265</link> даёт нормативные ссылки
на интерпретацию значений каждого параметра
функции <function>setcookie</function>.
<variablelist>
<varlistentry>
<term><parameter>name</parameter></term>
<listitem>
<para>
Название cookie.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>value</parameter></term>
<listitem>
<para>
Значение cookie. Это значение хранится на компьютере клиента;
не записывайте в cookie конфиденциальную информацию. Значение cookie
с именем <literal>'cookiename'</literal>, которое установили
через параметр <parameter>name</parameter>, получают
через элемент массива <varname>$_COOKIE['cookiename']</varname>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>expires_or_options</parameter></term>
<listitem>
<para>
Время истечения срока действия cookie — метка времени Unix, то есть
количество секунд с начала эпохи.
Один из способов установить значение — добавить количество секунд до истечения срока действия cookie
к результату вызова функции <function>time</function>.
Например, выражение <literal>time() + 60 * 60 * 24 * 30</literal> установит
срок действия cookie, который закончится через 30 дней.
Другой вариант — вызвать функцию <function>mktime</function>.
Срок действия cookie закончится с окончанием сессии (при закрытии браузера),
если задать значение <literal>0</literal> или опустить аргумент.
</para>
<para>
<note>
<para>
Видно, что параметр <parameter>expires_or_options</parameter> принимает
значение как метку времени Unix, а хранит значение в формате
<literal>'Wdy, DD-Mon-YYYY HH:MM:SS GMT'</literal>, причина состоит в том, что PHP
преобразовывает значение автоматически.
</para>
</note>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>path</parameter></term>
<listitem>
<para>
Путь, по которому сервер откроет доступ к блоку данных cookie. Сервер откроет
доступ к cookie во всём домене <parameter>domain</parameter>, если задать
значение <literal>«/»</literal>.
Сервер откроет доступ к блоку данных cookie в домене <parameter>domain</parameter>
только в каталоге <literal>/foo/</literal> и каждом подкаталоге вроде <literal>/foo/bar/</literal>,
если задать значение <literal>«/foo/»</literal>.
Значение по умолчанию — текущий каталог, в которой PHP устанавливает cookie.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>domain</parameter></term>
<listitem>
<para>
Домен или поддомен, у которого будет доступ к блоку данных cookie.
При установке параметра на поддомен <literal>www.example.com</literal>
сервер откроет доступ к cookie для этого поддомена и каждого его поддомена
наподобие w2.www.example.com.
Чтобы открыть доступ к cookie для всего домена с поддоменами, нужно просто
указать имя домена (для этого примера — <literal>example.com</literal>).
</para>
<para>
Старым браузерам, которые до сих пор следуют устаревшему стандарту <link
xlink:href="&url.rfc;2109">RFC 2109</link>, иногда требуется символ <literal>.</literal>
перед доменом для соответствия каждому поддомену.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>secure</parameter></term>
<listitem>
<para>
Указывает, что передавать блок данных cookie от клиента требуется
только по защищённому HTTPS-соединению. PHP установит cookie только
через безопасное соединение, если для параметра установили значение &true;.
За отправку cookie с сервера только через безопасное соединение отвечает программист.
Безопасно ли подключение, узнают, например, по значению
суперглобальной переменной <varname>$_SERVER["HTTPS"]</varname>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>httponly</parameter></term>
<listitem>
<para>
PHP предоставит доступ к cookie только через HTTP-протокол,
если для параметра установили значение &true;.
Это означает, что скриптовые языки наподобие JavaScript не получат доступа к cookie.
Отдельные программисты высказывали предположение, что этот параметр в состоянии
эффективно сократить количество краж личных данных через XSS-атаки (хотя
параметр поддерживается не каждым браузером),
но это утверждение часто оспаривается. Параметр принимает
значение &true; или &false;.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>options</parameter></term>
<listitem>
<para>
Ассоциативный массив (<type>array</type>) с произвольным набором ключей из следующего списка:
<literal>expires</literal>, <literal>path</literal>, <literal>domain</literal>,
<literal>secure</literal>, <literal>httponly</literal> и <literal>samesite</literal>.
Функция выдаст ошибку уровня <constant>E_WARNING</constant>, если в массиве окажется другой ключ.
Значения несут тот же смысл, который описали в параметрах с тем же именем.
Элемент <literal>samesite</literal> принимает только следующие значения:
<literal>None</literal>, <literal>Lax</literal> или <literal>Strict</literal>.
Значения разрешённых опций, которые не указали, по умолчанию
совпадают со значениями по умолчанию явных параметров.
Функция не устанавливает cookie-атрибут SameSite,
если элемент <literal>samesite</literal> не указали.
</para>
<para>
<note>
<para>
Блок данных cookie с атрибутами, которых нет в списке ключей,
устанавливают функцией <function>header</function>.
</para>
</note>
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Функция <function>setcookie</function> завершится ошибкой и вернёт &false;,
если перед вызовом функции клиенту уже передали вывод (теги,
пустые строки, пробелы, текст и т. п.).
Функция <function>setcookie</function> вернёт &true; при успешном запуске,
но это не даёт информации о том, принял ли пользователь cookie.
</para>
</refsect1>
<refsect1 role="changelog">
&reftitle.changelog;
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>8.2.0</entry>
<entry>
Дата cookie теперь устанавливается в формате <literal>'D, d M Y H:i:s \G\M\T'</literal>;
раньше дата устанавливалась в формате <literal>«D, d-M-Y H:i:s T»</literal>.
</entry>
</row>
<row>
<entry>7.3.0</entry>
<entry>
Добавили альтернативную сигнатуру, которая поддерживает массив опций <parameter>options</parameter>.
Эта сигнатура поддерживает также установку cookie-атрибута SameSite.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
Следующие примеры показывают отдельные способы отправки cookies.
<example>
<title>Пример использования функции <function>setcookie</function></title>
<programlisting role="php">
<![CDATA[
<?php
$value = 'что-то откуда-то';
setcookie("TestCookie", $value);
setcookie("TestCookie", $value, time()+3600); // Истекает через 1 час
setcookie("TestCookie", $value, time()+3600, "/~rasmus/", "example.com", true);
?>
]]>
</programlisting>
</example>
</para>
<para>
Обратите внимание, что функция автоматически URL-кодирует часть значения cookie перед отправкой клиенту,
а когда получает cookie — автоматически декодирует часть значения и присваивает переменной
с тем же именем, что и имя cookie. Если URL-кодирование значения не нужно,
вызывают функцию <function>setrawcookie</function>.
Просто запустите один из примеров, чтобы просмотреть имена и значения тестовых блоков данных cookie в скрипте:
</para>
<para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
// Вывести одно конкретное значение cookie
echo $_COOKIE["TestCookie"];
// В целях тестирования и отладки может пригодиться вывод каждого блока данных cookie
print_r($_COOKIE);
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
<example>
<title>Пример удаления cookie функцией <function>setcookie</function></title>
<para>
При удалении cookie необходимо убедиться, что срок действия cookie истёк,
чтобы запустить механизм удаления в браузере. Следующие примеры показываю, как удалить cookie,
которые отправили в предыдущем примере:
</para>
<programlisting role="php">
<![CDATA[
<?php
// Устанавливаем даты истечения срока действия на час назад
setcookie("TestCookie", "", time() - 3600);
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", "example.com", 1);
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title>Пример работы функции <function>setcookie</function> с массивами</title>
<para>
Массивы cookie устанавливают через обозначение массива
в имени cookie. В результате функция установит столько блоков данных cookie,
сколько элементов массива, но когда скрипт получит cookie, функция поместит
каждое значение в массив с именем cookie:
</para>
<programlisting role="php">
<![CDATA[
<?php
// Отправляем cookie
setcookie("cookie[three]", "cookiethree");
setcookie("cookie[two]", "cookietwo");
setcookie("cookie[one]", "cookieone");
// Выведем cookie после перезагрузки страницы
if (isset($_COOKIE['cookie'])) {
foreach ($_COOKIE['cookie'] as $name => $value) {
$name = htmlspecialchars($name);
$value = htmlspecialchars($value);
echo "$name : $value <br />\n";
}
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
three : cookiethree
two : cookietwo
one : cookieone
]]>
</screen>
</example>
<note>
<simpara>
Символы-разделители вроде <literal>«[»</literal> и <literal>«]»</literal>
в составе имени cookie не соответствуют требованиям 4-го раздела стандарта RFC 6265, но предполагается,
что такие символы поддерживаются агентами пользователя по правилам 5-го раздела стандарта RFC 6265.
</simpara>
</note>
</para>
</refsect1>
<refsect1 role="notes">
&reftitle.notes;
<note>
<para>
Разрешается буферизировать вывод для отправки вывода до вызова функции,
при этом вывод в браузер буферизируется на сервере до тех пор, пока сервер не отправит вывод.
Вывод буферизируют вызовом в скрипте функций
<function>ob_start</function> и <function>ob_end_flush</function>,
или включают директиву конфигурации <literal>output_buffering</literal> в файле
&php.ini; или в файлах конфигурации сервера.
</para>
</note>
<para>
Общие замечания:
<itemizedlist>
<listitem>
<simpara>
Клиент увидит блоки данных cookie только после перезагрузки страницы, для которой
открыли видимость cookie. Чтобы узнать, правильно ли установились cookie,
проверяют наличие cookie при следующей загрузке страницы до истечения срока
действия cookie. Срок действия cookie задают в параметре
<parameter>expires_or_options</parameter>. Хороший способ проверить существование cookie при отладке —
просто вызывать функцию <literal>print_r($_COOKIE);</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Удалять cookie необходимо с теми же параметрами, с которыми
cookie установили. Если значение аргумента <parameter>value</parameter> — пустая строка,
а все остальные параметры соответствуют предыдущему вызову функции <function>setcookie</function>,
блок данных cookie c заданным именем удалится на удалённом клиенте.
Внутренне для этого блок данных cookie получает значение
<literal>«deleted»</literal>, а время истечения переносится на год в прошлое.
</simpara>
</listitem>
<listitem>
<simpara>
Поскольку установка блока данных cookie со значением &false; приведёт к попытке удаления cookie,
не нужно устанавливать для cookie логические значения. Вместо этого указывают
значение <emphasis>0</emphasis> для замены значения &false; и <emphasis>1</emphasis> для замены значения &true;.
</simpara>
</listitem>
<listitem>
<simpara>
Имена cookie разрешается устанавливать массивом имён. У PHP-скриптов будет доступ
к именам cookie как к массивам, но в системе пользователя cookie будут храниться как
отдельные записи. Чтобы установить cookie c набором имён и значений,
вызывают функцию <function>explode</function>. Не рекомендуется
вызывать для этих целей функцию <function>serialize</function>, поскольку иногда
это нарушает безопасность.
</simpara>
</listitem>
</itemizedlist>
</para>
<simpara>
Множественные вызовы функции <function>setcookie</function>
выполняются в порядке вызова.
</simpara>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><function>header</function></member>
<member><function>setrawcookie</function></member>
<member><link linkend="features.cookies">раздел cookies</link></member>
<member><link xlink:href="&url.rfc;6265">RFC 6265</link></member>
<member><link xlink:href="&url.rfc;2109">RFC 2109</link></member>
</simplelist>
</para>
</refsect1>
</refentry>
<!-- 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
-->