Установка куки php. Setcookie - Посылает cookie. Эффективное использование сессий

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

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

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

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

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

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

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

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

Login: admin password: 123

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

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

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

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

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

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

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

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

Как мы видим, в данный момент этот массив пуст. Давайте же его наполним:) Для этого нам нужно установить какую-нибудь 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 и запишем в него следующий код:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Последнее обновление: 1.11.2015

Cookie (куки) представляют небольшие наборы данных (не более 4 кБайт), с помощью которых веб-сайт может сохранить на компьютере пользователя любую информацию. С помощью куки можно отслеживать активность пользователя на сайте: залогинен пользователь на сайте или нет, отслеживать историю его визитов и т.д.

Сохранение cookie

Для сохранения куки на компьютере пользователя используется функция setcookie() . Она имеет следующее определение:

Bool setcookie(string $name, string $value, int $expire, string $path, string $domain, bool $secure, bool $httponly);

Функция setcookie() может принимать следующие параметры:

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

    value: значение или содержимое cookie - любой алфавитно-цифровой текст не более 4 кБайт

    expire (необязательный параметр): срок действия, после которого cookie уничтожаются. Если данный параметр не установлен или равен 0, то уничтожение cookie происходит после закрытия браузера.

    path (необязательный параметр): путь к каталогу на сервере, для которого будут доступны cookie. Если задать "/", cookie будут доступны для всего сайта. Если задать, например, "/mydir/" , cookie будут доступны только из каталога /mydir/" и всех его подкаталогов. По умолчанию значением является текущий каталог, в котором устанавливаются cookie.

    domain (необязательный параметр): задает домен, для которого будут доступны cookie. Если это домен второго уровня, например, localhost.com , то cookie доступны для всего сайта localhost.com, в том числе и для его поддоменов типа blog.localhost.com .

    Если задан поддомен blog.localhost.com , то cookie доступны только внутри этого поддомена.

    secure (необязательный параметр): указывает на то, что значение cookie должно передаваться по протоколу HTTPS. Если задано true , cookie от клиента будет передано на сервер, только если установлено защищенное соединение. По умолчанию равно false .

    httponly (необязательный параметр): если равно true , cookie будут доступны только через http протокол. То есть cookie в этом случае не будут доступны скриптовым языкам, например, JavaScript. По умолчанию параметр равен false

Сохраним cookie:

$value1 = "Сингапур"; $value2 = "китайский"; setcookie("city", $value1); setcookie("language", $value2, time()+3600); // срок действия 1 час

Здесь устанавливаются две куки: "city" и "language". Первая куки уничтожается после закрытия браузера, а вторая - через 3600 секунд, то есть через час

Получение cookie

Чтобы получить cookie, можно использовать глобальный ассоциативный массив $_COOKIE , например, $_COOKIE["city"] . Так, получим ранее сохраненные куки:

If (isset($_COOKIE["city"])) echo "Город: " . $_COOKIE["city"] . "
"; if (isset($_COOKIE["language"])) echo "Язык: " . $_COOKIE["language"];

Сохранение массивов в cookie

Сохранение в куки массивов имеет некоторые особенности. Например, сохраним следующий массив:

Setcookie("lan", "PHP"); setcookie("lan", "C#"); setcookie("lan", "Java");

Теперь получим его и выведем на страницу:

If (isset($_COOKIE["lan"])) { foreach ($_COOKIE["lan"] as $name => $value) { $name = htmlspecialchars($name); $value = htmlspecialchars($value); echo "$name. $value
"; } }

Удаление cookie

Для удаления cookie достаточно в качестве срока действия указать какое-либо время в прошлом:

Setcookie ("city", "", time() - 3600);

int setcookie (string name [, string value [, int expire [, string path [, string domain [, int secure]]]]])

Setcookie() определяет куку для отправки вместе с остальной header-информацией.Куки обязаны быть отправлены до любых других шапок/headers (это ограничение кук, а не РНР). Это требует, чтобы вы помещали вызовы этой функции перед тэгами или. Все аргументы, кроме name , являются необязательными.Если имеется только аргумент name, кука с этим именем будет удалена с удалённого клиента.Вы можете также заместить любой аргумент пустой строкой (""), чтобы пропустить этот аргумент.Аргументы expire и secure это целые числа/integer и они не могут быть пропущены с помощью пустой строки. В них используйте нуль (0).Аргумент expire это обычное Unix time integer, возвращаемое функциями time() или mktime() .Аргумент secure указывает, что данная кука должна передаваться только через секретное HTTPS-соединение. После того как куки установлены, доступ к ним может быть получен при загрузке следующей страницы через массив $_COOKIE (который вызывается $HTTP_COOKIE_VARS в версиях PHP до 4.1.0). Обычные ловушки:Куки будут невидимы до тех пор, пока не будет загружена следующая страница.Куки обязаны быть удалены с теми же параметрами, с которыми были установлены. В PHP 3 множественные вызовы setcookie() в том же скрипте могут быть выполнены в реверсном порядке. Если вы пытаетесь удалить одну куку до вставки другой, вы должны сделать вставку до удаления. В PHP 4 множественные вызовы setcookie() выполняются в порядке вызова. Далее идут примеры отправки кук:
Обратите внимание, что часть value куки будет автоматически urlencoded при отправке куки, и, когда она получена, она автоматически декодируется и присваивается переменной с тем же именем, что и имя куки. Для просмотра содержимого нашей тестовой куки в скрипте просто используйте один из следующих примеров: О куках дополнительно см. спецификацию Netscape по адресу: http://www.netscape.com/newsref/std/cookie_spec.html . Microsoft Internet Explorer 4 с Service Pack 1 некорректно работает с куками, которые имеют установленный параметр path. Netscape Communicator 4.05 и Microsoft Internet Explorer 3.x обрабатывают куки некорректно, если path и time не установлены.

PHP transparently supports HTTP cookies. Cookies are a mechanism for storing data in the remote browser and thus tracking or identifying return users. You can set cookies using the setcookie() or setrawcookie() function. Cookies are part of the HTTP header, so setcookie() must be called before any output is sent to the browser. This is the same limitation that header() has. You can use the output buffering functions to delay the script output until you have decided whether or not to set any cookies or send any headers.

Any cookies sent to server from the client will automatically be included into a $_COOKIE auto-global array if variables_order contains "C". If you wish to assign multiple values to a single cookie, just add to the cookie name.

15 years ago

Just a general comment on Wilton"s code snippet: It"s generally considered very bad practice to store usernames and/or passwords in cookies, whether or not they"re obsfucated. Many spyware programs make a point of stealing cookie contents.

A much better solution would be to either use the PHP built in session handler or create something similar using your own cookie-based session ID. This session ID could be tied to the source IP address or can be timed out as required but since the ID can be expired separately from the authentication criteria the authentication itself is not compromised.

Stuart Livings

9 months ago

unset($_COOKIE [ "cookie" ]);
?>

Apenas apaga um índice de uma variável, os cookies ainda vão existir e continuar a ser enviados do servidor pro cliente e vice-versa.
Assim como isso:

$_COOKIE [ "cookie" ] = "foo bar" ;
?>

Não cria ou altera o valor do cookie, apenas durante a execução atual, o valor que será passado do servidor pro cliente e vice-versa será o original

Para excluir ou alterar deve SEMPRE sobre escrever o valor antigo com setcookie(), setrawcookie() ou header(), sendo este último não muito comum e dificilmente terá um uso justificável

13 years ago

13 years ago

In response to the solution posted in the comment below, there are some practical issues with this solution that must be kept in mind and handled by your code. I developed an application using a similar "use-it-once" key to manage sessions and it worked great but we got some complaints about legitimate users getting logged out without reasons. Turns out the problem was not tentative highjacking, it was either:

A- Users double click on links or make 2 clicks very fast. The same key is sent for the 2 clicks because the new key from the first click didn"t get to the browser on time for the second one but the session on the server did trash the key for the new one. Thus, the second click causes a termination of the session. (install the LiveHttpHeaders extension on firefox and look at the headers sent when you click twice very fast, you"ll see the same cookie sent on both and the new cookie getting back from the server too late).

B- For any given reason, the server experiences a slow down and the response with the new key (which has replaced the old one on the server) is not returned to the browser fast enough. The user gets tired of waiting and clicks somewhere else. He gets logged out because this second click send the old key which won"t match the one you have on your server.

Our solution was to set up a grace period where the old key was still valid (the current key and the previous key were both kept at all times, we used 15 seconds as a grace period where the old key could still be used). This has the drawback of increasing the window of time for a person to highjack the session but if you tie the validity of the old key to an IP address and/or user agent string, you still get pretty good session security with very very few undesired session termination.

10 years ago

It is better to note not to attach your cookies to and IP and block the IP if it is different as some people use Portable Browsers which will remember the cookies. It is better to show a login screen instead if the IP does not correspond to the session cookie"s IP.

14 years ago

I found a solution for protecting session ID without tying them to client"s IP. Each session ID gives access for only ONE querry. On the next querry, another session ID is generated and stored. If somebody hacks the cookie (or the session ID), the first one of the user and the pirate that will use the cookie will get the second disconnected, because the session ID has been used.

If the user gets disconnected, he will reconnect: as my policy is not to have more than one session ID for each user (sessions entries have a UNIQUE key on the collomn in which is stored user login), every entries for that user gets wiped, a new session ID is generated and stored on users dirve: the pirate gets disconnected. This lets the pirate usually just a few seconds to act. The slower visitors are browsing, the longer is the time pirates get for hacking. Also, if users forget to explicitly end their sessions .... some of my users set timeout longer than 20 minutes !

IMPORTANT NOTE: This disables the ability of using the back button if you send the session ID via POST or GET.

12 years ago

If you want a secured session not tied to the client IP you can use the valid-for-one-query method below, but to safeguard against a scenario where the legitimate user clicks twice, you can use a shutdown function (register_shutdown_function)*.

It will check to see if the script terminated prematurely (connection_aborted), and reset the valid session ID. That way, it"s still valid when the user makes the second request. If the script ends properly, the new session ID will be used instead.

Now, since you can"t set a cookie from the shutdown function (after output has been sent), the cookie should contain both the previous valid session ID and the new one. Then the server script will determine (on the next request) which one to use.

:: Pseudo example:
::
::
::
:: 1. Get the session ID(s) from cookie
:: 2. If one of the session ID"s is still valid (that is, if there"s a storage associated with it - in DB, file or whatever)
:: ____2.1. Open the session
:: 3. Generate a new session ID
:: 4. Save the new session ID with the one just used in cookie
:: 5. Register shutdown function
::
::
::
:: 1. If script ended prematurely
:: ____1.1. Save session data using the old Session ID
:: 2. Else
:: ____2.1. Save session data using the new Session ID
:: ____2.2. Make sure the old session ID is added to a list of ID"s (used for the purpose described below)
:: ____2.3. Trash the old session storage

There"s still the possibility of some deviant network sniffer catching the session cookie as it"s sent to the client, and using it before the client gets the chance to. Thus, successfully hijacking the session.

If an old session ID is used, we must assume the session has been hijacked. Then the client could be asked to input his/her password before data is sent back. Now, since we have to assume that only the legitimate user has the password we won"t send back any data until a password is sent from one request.

And finally, (as a sidenote) we could obscure the login details (if the client has support for javascript) by catching the form as it is sent, take the current timestamp and add it to the form in a dynamically generated hidden form object, replace the password field with a new password that is the MD5 (or similar) of the timestamp and the real password. On the serverside, the script will take the timestamp, look at the user"s real password and make the proper MD5. If they match, good, if not, got him! (This will of course only work when we have a user with a session that"s previously logged in, since we know what password (s)he"s supposed to have.) If the user credentials are saved as md5(username+password), simply ask for both the username and password, md5 them and then md5 the timestamp and the user cred.

If you need a javascript for md5.

Всем привет!

Я снова в строю! В последнее время перемены в жизни вынуждают частенько отдаляться от блога, но тем не менее я здесь и никуда не ухожу! Скоро будет ряд очень полезных и познавательных уроков по заработку! Не пропустите! А пока я расскажу о том, как в php работать с куками. Как можно легко создать, удалить или обновить куки в php?

В последующих статьях мы рассмотрим работу куки в WordPress. А пока для общего развития разберем само понятие куки.

Не буду писать банальщину о том, что куки это в переводе печеньки и все такое. Информация эта, на мой взгляд, совершенно бесполезная. Скажу иначе, куки - это какая-то информация, которая хранится в Вашем браузере.

Например, Вы решили проголосовать в опросе. Далее Вы еще раз захотели проголосовать, но вместо принятия голоса вылезает сообщение: "Вы уже голосовали". Казалось бы, на сайте мы не регистрировались, откуда информация, что мы уже голосовали?

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

Как создать куки в php?

Создаются куки в php благодаря функции setcookie . Эта функция принимает в себя следующие параметры:

setcookie ("Имя" , "Значение" , "Срок" , "Путь" , "Домен" , "Защита" ) ;

  • Обязательный здесь только один параметр - "Имя".
  • "Значение" указывается значение куки, как уже все догадались.
  • Срок - сколько времени куки будут работать? После окончания срока действия, кука автоматически будет удалена. Срок может быть бессрочным, в случае, если мы не указываем значение "срок". Срок устанавливается только в секундах!
  • Путь - из какого каталога будет доступна кука. (обычно не указывается, и доступна из всех каталогов)
  • Домен - Домен указывается автоматически. В случае, если доступ к куки нужно получать и на поддоменах, можно указать ".сайт". В таком случае кука будет доступна на всех сайтах с адресами: name.сайт
  • Защита - если написано TRUE, тогда куки передаются по шифрованному соединению (ssl).

Создание куки на PHP

Теперь если посмотреть в браузере (я использую mozilla), то мы увидим куку в действии:

Как видите, куки установились ровно на 1 день, с нужным, нам, названием, и нужным значением.

Как обновить куки php?

Предположим нам нужно обновить значение куки. Т.е. название будет то же, но значение или срок действия надо изменить. В таком случае нам опять же понадобится функция setcookie .

Операция ничем не отличается от операции создания куков. Точно так же пишем похожий код, но с измененными данными:

Теперь посмотрим, что содержится в браузере:

Как видите, обновление куки произошло успешно!

Как прочитать\получить куку php?

То, что в браузере отображается кука, это хорошо, но мы ведь ее создаем, чтобы впоследствии использовать в наших скриптах. Так как же получить куку? Для этого существует глобальный массив кук $_COOKIE , в котором находятся вообще все созданные куки. Обратиться к ним легко - достаточно знать имя.

Теперь кука удалится!

Одно важное замечание, о котором никто не говорит. Когда я только начинал изучать программирование, я удалил куку этим способом. Зашел в браузер - кука осталась. Перерыл все форумы - такая проблема часто встречается, но все отвечают мол: "Хм, не знаю, у меня работает". А причина вот в чем - кука удаляется, но не из файлов пользователя. Там она остается. И открывая браузер, Вы ее видите, но если мы обратимся к ней посредством $_COOKIE["wpguru"] , то в результате будет 0. Вот так можно легко проверить, удалена ли кука.

На этом у меня все, в ближайшее время будут выходить еще статьи. Скорей всего я опишу в следующей статьи, какие планы ждут блог, и подробно расскажу про серию статей о заработке. Все будет в онлайн-режиме, т.е. я зарабатываю, и пишу статью. А не просто теорию вещаю.

Так что ждите.

До скорых встреч!