Чат PHP-разработчиков
Cookie в PHP: основы работы

Учимся работать с cookie в PHP

В сегодняшнем уроке мы поговорим о работе с cookie в PHP. Начнём с того, что же это такое, для чего это нужно и почему оно вообще появилось.

Для чего нужны cookie

Как мы с вами уже знаем, в PHP мы можем работать с GET- и POST-запросами. Они позволяют нам передавать серверу данные, чтобы как-то повлиять на работу кода. Мы можем передать скрипту логин и пароль, он их проверит и разрешит нам доступ к какой-либо информации. Однако, это не позволит создать сессию между нами и сервером. То есть сервер не может нас «запомнить», и каждый раз, как мы хотим сказать что это мы, придется отправлять отдельный новый запрос с логином и паролем.

В качестве решения придумали cookie. Это такие записи с типом ключ-значение, типа массива в PHP, только хранятся они в браузере у пользователя сайта. Для каждого сайта cookie хранятся отдельно. Каждый раз, когда пользователь обращается с запросом на сайт, браузер проверяет наличие этих записей для данного сайта. И если они имеются, то он отправляет их в заголовке каждого запроса к этому сайту.

Откуда берутся cookie

Cookie создаются в браузере по «просьбе» сервера. В какой-то момент мы решаем, что нужно в браузере посетителя создать cookie с каким-то значением. Для этого нужно чтобы сервер передал в ответе клиенту специальный заголовок, в котором указано, какую запись нужно создать в браузере для данного сайта.

Всё это происходит в фоне и не заметно для пользователя. По этому принципу работает авторизация на любом сайте. В простейшем случае, после того как вы ввели логин и пароль на сайте, сервер проверяет, верны ли они. И если да, то сервер может попросить браузер сохранить эти данные в cookie и при каждом запросе отправлять их ему.

То есть сервер примерно говорит: «Эй, браузер, создай запись для меня с ключом “login” и значением “admin”, и ещё одну с ключом “password” и значением “123”». После этого браузер при любом запросе к серверу начинает отправлять дополнительные данные типа:

Код доступен только после покупки курса PHP для начинающих.

После этого в других местах сайта, где нужна авторизация, теперь можно будет проверить эти данные из cookie, не заставляя пользователя заполнять форму заново. И если они являются верными логином и паролем, то давать пользователю доступ к чему-либо.

То есть, например, на странице с формой авторизации при верном логине и пароле будем устанавливать cookie, а на остальных страницах уже проверять данные из cookie, переданные клиентом.

Про время жизни

При этом у cookie есть TTL (Time To Live – время жизни). То есть эти записи могут быть временными. Это время жизни так же указывается сервером во время установки cookie в браузер. Благодаря этому можно сделать так, чтобы сессия длилась пол часа. А после этого времени пользователю надо будет авторизоваться снова. Наверняка вы замечали это в действии на многих сайтах.

Как работать с cookie в PHP

Итак, мы в общих чертах разобрались с тем, как работают cookie. Давайте теперь посмотрим, как с ними можно работать в языке PHP.

Давайте создадим в нашем проекте файл с именем viewCookies.php. Поместим в него следующий код.

Код доступен только после покупки курса PHP для начинающих.

Как вы уже должны были догадаться, $_COOKIE — это еще один глобальный массив в PHP, аналогично массивам $_GET и $_POST. Только в нём хранятся все cookie, которые были отправлены браузером в рамках текущего запроса.

Давайте посмотрим на работу данного скрипта, открыв в браузере страницу: http://myproject.loc/viewCookies.php

Вывод массива $_COOKIE

Как мы видим, в данный момент этот массив пуст. Давайте же его наполним :) Для этого нам нужно установить какую-нибудь cookie в браузер. В PHP для этого используется функция setcookie($name, $value, $ttl, $path)

Передаваемые параметры:

  • $name – название cookie
  • $value – её значение
  • $ttl – время жизни. Если указать 0, то cookie будет установлена навсегда (пока её не удалят).
  • $path – путь в адресной строке. Если задать '/', cookie будут доступны из всех директорий сайта. Например, и в http://myproject.loc/ и в http://myproject.loc/posts/. Если задать '/posts/', cookie будут доступны только из директории http://myproject.loc/posts/ и всех ее поддиректорий (например, http://myproject.loc/posts/new/). По умолчанию значением является текущая директория, в которой cookie устанавливается. Если мы хотим, чтобы cookie была доступна на всём сайте, то нужно устанавливать это значение в '/'.

Есть еще несколько параметров, о них вы можете прочитать в официальной документации.

А теперь давайте попробуем эту функцию в деле. Создадим файл setCookies.php и запишем в него следующий код:

Код доступен только после покупки курса PHP для начинающих.

После этого перейдём по адресу http://myproject.loc/setCookies.php, где увидим пустую страницу. Как мы уже говорили, работа с cookie не видна пользователю.

Однако, эту работу всегда можно увидеть в консоли разработчика Google Chrome. Давайте откроем её (нажатием F12), перейдём во вкладку Network, обновим страницу в браузере и найдём её в списке загруженных данных (она там одна).

Список запросов в консоли разработчика Google Chrome

Нажмем на эту запись и в открывшемся справа окне выберем вкладку Headers. Здесь, в секции Response Headers мы можем видеть заголовок Set-Cookie с указанными нами данными.

Смотрим заголовки ответа

Таким образом, cookie были успешно установлены в браузере. Давайте теперь перейдём на нашу страничку, выводящую массив $_COOKIE - http://myproject.loc/viewCookies.php

Вывод cookie из массива

Как мы видим, теперь на сервер передаются cookie, ранее установленные в браузере. Увидеть их можно и в запросе, посмотрев в консоли разработчика секцию Request Headers.

Заголовки запроса

Если вам нужно посмотреть все cookie, которые имеются в браузере для данного сайта — можно посмотреть их в той же консоли разработчика Google Chrome. Для этого перейдем во вкладку Application, выберем в левом списке пункт Cookies, а внутри него наш сайт.

Список всех cookie для сайта в консоли разработчика

Все cookie будут представлены в виде удобного списка.

Что еще нужно знать про cookie

И в заключение данного урока нужно добавить, что cookie устанавливаются с помощью заголовка в ответе сервера по протоколу HTTP. Протокол HTTP устроен таким образом, что заголовок должен всегда идти перед данными, и никак иначе. Таким образом, функция setcookie и любые другие функции в PHP, изменяющие заголовок в HTTP-ответе, должны вызываться до любого вывода данных.

Можно сначала задать cookie, а затем вывести текст.

Код доступен только после покупки курса PHP для начинающих.

Сначала заголовок а потом тело

Всё прекрасно отработает.

Но нельзя вывести текст (являющийся телом HTTP-ответа), а затем пытаться установить cookie.

Код доступен только после покупки курса PHP для начинающих.

Ошибка при попытке изменить заголовок после начала передачи тела

Как мы видим, это приведет к ошибке. Так устроен протокол HTTP. Сначала — заголовок, затем — тело. Только так и никак иначе.

Установка нескольких cookie

Нет ничего проще, чем установить несколько cookie. Для этого нужно просто несколько раз вызвать функцию setcookie.

Код доступен только после покупки курса PHP для начинающих.

Установка нескольких cookie в браузер

Они успешно будут переданы клиенту.

Пример полноценного взаимодействия с пользователем через cookie мы рассмотрим в следующем уроке. А пока — за домашку.

Домашнее задание

Укажите параметр $ttl в функции setcookie равным 20.

Запустите этот скрипт и посмотрите, что изменилось в заголовке Set-Cookie в консоли разработчика.

Сразу после установки cookie перейдите на страничку http://myproject.loc/viewCookies.php и убедитесь что эта cookie сейчас содержится в массиве и выводится.

Спустя 20 секунд обновите эту страницу снова и убедитесь, что cookie пропала из массива.

Читайте также
Комментарии (22)


1nSide

Значения время выставляю на 0 работает на 20 не работает


setcookie('login' , 'admin' , 20 , '/');
setcookie('Password' , '123' , 20 , '/');
echo 'Cookie отработало';
1nSide

хотя во вкладке сеткуки пишется что присутствуют
Set-Cookie: login=admin; expires=Thu, 01-Jan-1970 00:00:20 GMT; Max-Age=0; path=/
Set-Cookie: Password=123; expires=Thu, 01-Jan-1970 00:00:20 GMT; Max-Age=0; path=/

ivashkevich

Всё правильно, куки действительно устаревают спустя 20 секунд от момента начала эпохи unix. Я же не просто так просил ознакомиться с документацией. Почитайте внимательно про параметр expire :)

dom1r

Не знаю как лучше так:

setcookie('login', 'admin', time() + 20, '/');

Или так:

$ttl = time() + 20;
setcookie('login', 'admin', $ttl, '/');
ivashkevich

Хоть как =) Понятно и так и так.

Kostik04

Сделал всё, как вы сказали, но всё равно выдаёт ошибку Warning: Cannot modify header information - headers already sent by (output started at W:\domains\myproject.loc\www\primer_2.php:1) in W:\domains\myproject.loc\www\primer_2.php on line 2
Вот мой код:

<?php
setcookie('login', 'admin', 0, '/');
ivashkevich

Значит что-то выводится перед тем, как вызывается эта функция.

Kostik04

Спасибо большое, оказывается кодировка была не UTF-8.

ArtemijeKA

А почему вашему сайту доступны все мои куки(yandex, mail, vk)? Когда как скажем сайту youtube доступны только youtube.com и googe.com куки?

ivashkevich

Это куки, которые были запрошены с моего сайта в эти сервисы (скрипты статистики, встроенное видео с ютуба). Просто так нельзя получить куки для другого сайта.

ArtemijeKA

Понял, спасибо.

nail_nasyrov@mail.ru

Выходит уже описанная ошибка

Warning: Cannot modify header information - headers already sent by (output started at W:\domains\myproject.loc\www\index.php:1) in W:\domains\myproject.loc\www\index.php on line 3

код

<?php

setcookie('login1', 'admin1', 0, '/');

//var_dump($_COOKIE);

?>

нашел решение
output_buffering = on

demyanovpaul@yandex.ru

Укажите параметр $ttl в функции setcookie равным 20.

setcookie('cooks', 'kakay-to stroka', time() + 20);

Все проверил, отработало через 20 секунд умерла.

virtual2018

В документации третий параметр setcookie($name, $value, $ttl, $path), называется $expire.
"Если указать 0, то cookie будет установлена навсегда (пока её не удалят)" - в документации:
"Если задать 0 или пропустить этот аргумент, срок действия cookie истечет с окончанием сессии (при закрытии браузера)" - не противоречит, но дополняет.

ivashkevich

Угу, при этом в современных браузерах понятие "сессии" у каждого своё =)

Pavel-Tonk

В файле setCookie установил

<?php
setcookie('login','admin',time()+20,'');

В файле getCookie сделал вывод

<?php
var_dump($_COOKIE);

сколько не перезагружаю cookie живы и выводятся, в чем ошибся? в Expires 2018-12-03T22:04:59.363Z
время по серверу 01:01:22 04.12.2018 (date('H:i:s d.m.Y');)

ivashkevich

Потому что этот срок действия для браузера, а не для сервера. Когда подойдет это время на компе пользователя, они удалятся из браузера.

Pavel-Tonk

01:01:22 04.12.2018 Так это время у меня и было по факту, а это уже прошло 2018-12-03T22:04:59.363 3 часа назад.

ivashkevich

Смотрите наличие куки в браузере (загуглите как). Если они там есть, значит не протухли.

Bogdan

вроде поставил, но я так понял что они в куки даже не попадают,ну по крайней мере когда я делаю вывод куки, то у меня ничего не отображает, хотя даже 20 сек не прошло. но в setCookies в нетворке пишет Set-Cookie: login=admin; expires=Thu, 01-Jan-1970 00:00:20 GMT; Max-Age=0; path=/
Set-Cookie: Password=123; expires=Thu, 01-Jan-1970 00:00:20 GMT; Max-Age=0; path=/
так что думаю что все отработало верно

ivashkevich

Потому что вместо 20 нужно написать time() + 20

Популярное за сутки
Сейчас читают
Логические задачи с собеседований