Библиотека php для работы с cookies. Работа с файлами сессий и cookies в PHP и MYSQL

Определяет куку для отправки вместе с остальной header-информацией. Куки обязаны быть отправлены до любых других шапок/headers (это ограничение кук, а не РНР). Это требует, чтобы вы помещали вызовы этой функции перед первым выводом на страницу, т.е. до тэга.

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

Все аргументы, кроме 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() выполняются в порядке вызова.

Пример 1. Отправка кук функцией setcookie()
setcookie ("TestCookie", $value); setcookie ("TestCookie", $value,time()+3600); // период действия - 1 час setcookie ("TestCookie", $value,time()+3600, "/~rasmus/", ".utoronto.ca", 1);

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

Пример 2. Удаление куки с помощью setcookie()
// установить дату окончания действия на один час назад setcookie ("TestCookie", "", time() - 3600); setcookie ("TestCookie", "", time() - 3600, "/~rasmus/", ".utoronto.ca", 1);
Пример 3. Удаление всех кук
foreach($_COOKIE as $ind=>$val) @setcookie($ind,"",time()-999, "/", ".".$_SERVER["SERVER_NAME"]);
Пример 4.

Обратите внимание, что часть value куки будет автоматически urlencoded при отправке куки, и, когда она получена, она автоматически декодируется и присваивается переменной с тем же именем, что и имя куки. Для просмотра содержимого нашей тестовой куки в скрипте просто используйте один из следующих примеров:

Echo $TestCookie; echo $_COOKIE["TestCookie"];

Пример 5.

Вы можете также установить куки массива, используя нотацию в имени куки. Это даёт эффект установки стольких кук, сколько элементов в этом массиве, но, когда кука получается скриптом, значения помещаются в массив с именем куки:

Setcookie ("cookie", "cookiethree"); setcookie ("cookie", "cookietwo"); setcookie ("cookie", "cookieone"); foreach($_COOKIE as $name=>$val) { echo "$name = $value
\n"; }

Пример 6.

Если у Вашего сервера два доменных имени: "www.domain.com" и "other.domain.com", и Ваш аккаунт позволяет Вам обслуживать страницы из каталога ~/myhome, Вы должны вызывать функцию setcookie() следующим образом:

Setcookie("name", $value, time()+3600, "~/myhome", ".domain.com ");

Пример 7. Счетчик в куки с помощью setcookie()

О куках дополнительно


В этой статье я расскажу вам о том, что такое Cookie (в переводе с английского - печенье, к слову об изображении), как их используют, насколько они важны в современном Рунете и как с ними работать средствами PHP.

Теперь немного сухой, но обязательной информации, которая после будет объяснена на примерах)

Cookie - это набор данных (сохраняемый как текстовый файл), который создаётся web-сервером и который отсылается при каждом обращении к серверу. Cookie хранятся в браузере пользователя и составляются для определённого сайта.

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

Примеры записи cookie на PHP

Первое и самое главное - запись куки в браузер. Ниже приведены примеры записи, продления, сокращения на PHP.
Для записи, продления, сокращения срока действия куки используется setcookie .

// создаём куку
setcookie("Name", "Value",time()+3600); // создали cookie с названием Name, значением Value на 1 час (3600 секунд)

// сокращаем срок действия
setcookie ("Name", "", time() - 3600); // срок действия куки сокращён на час
?>

Как проверить, записалось ли значение для cookie?

setcookie("Name", "Value",time()+3600); // создаём куку
if (SetCookie("Test","Value")) echo "

Cookies успешно установлены!

";
// при следующем запросе выведет "Value":
echo @$_COOKIE["Test"]; // выводим куку. Напоминаю, знак @ не выводить ошибку в случае отсутствия куки
?>
В последнем примере при выводе куки мы используем специальный для этого массив $_COOKIE.

Как удалить Cookie в PHP?

Для удаления куки используется также setcookie или unset .

unset($_COOKIE["Name"]); // первый способ удалить куку
setcookie("Name","Value",time()-1); // второй способ - возьмём и просрочим действие куки
setCookie("Name",""); // третий способ - оставляем значение пустым
?>

Пишем первый скрипт с использованием Cookie на PHP - форма авторизации

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

// вывод формы для ввода данных
// после нажатия "Войти" страница обновляется
function showForm() {
$string = "

";
$string .= "";
$string .= "";
$string .= "";
$string .= "";
$string .= "";
$string .= "";
$string .= "";
$string .= "
";
return $string;
}
// проверка введённых пользователем данных. Если верно, то возвращает true
function check($login, $pass) {
if (($login == "admin") && ($pass == md5("12345"))) return true;
else return false;
}
// теперь запись
if (isset($_POST["log"])) {
$login = $_POST["login"];
$pass = md5($_POST["pass"]);
if (check($login, $pass)) {
setcookie("login", $login);
setcookie("pass", $pass);
}
else echo "Вы ввели неверные данные. Пожалуйста, попробуйте ещё";
}
?>




setcookie("login", $login);
setcookie("pass", $pass);
// ниже дубль предыдущего кода, который позволяет реализовать сценарий в рамках одной страницы
$login = $_COOKIE["login"];
$pass = $_COOKIE["pass"];
if (check($login, $pass)) echo "Здравствуйте, $login";
else echo showForm();
?>


Смотрим результат работы. После демонстрации обязательно прочитайте описание работы кода.

Код и его логика простые. В верхней части мы создали функции-обработчики: вывод формы для входа, проверка соответствия данных (если успех, то возвращает true, если данные не совпадают, то - false):

После этого производим запись куки.

Обратите внимание на $_SERVER (можно заменить на $_SERVER). Эта константа содержит путь к текущему файлу. В результате обработки формы (значение атрибута action) обращается по этому же пути, к этому файлу.

Следом идёт проверка отправки формы (передавались ли значение log, то есть нажимали ли кнопку Войти). Если да, то проверяются данные login и pass. Стоит обратить внимание, что пароль не передаётся в чистом виде, а зашифровывается встроенной в PHP функцией шифрования данных md5().

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

Спасибо за внимание!

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

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

Для дальнейшего понимания функционирования механизма cookie в PHP вам необходимо ознакомиться со статьей "Интерпретатор PHP. Основы, принципы функционирования" , в особенности, где затрагивается понятие так называемого "первого вывода". Итак, задействовать механизм можно на этапе формирования HTTP-ответа на запрос. Для того, чтобы указать веб-клиенту сохранить у себя какой-то параметр в HTTP-ответ добавляется заголовок со значением вида name=value (имя параметра, значение параметра), например:

Set-Cookie: myname=john

Таких заголовков может быть несколько, если необходимо сохранить более одного параметра. При получении HTTP-ответа веб-браузер проверяет наличие заголовков Set-Cookie и, если таковые имеются, сохраняет их значения в своих внутренних служебных файлах. Куки по умолчанию привязываются к домену сайта. При подготовке HTTP-запроса веб-браузер проверяет, есть ли у него в наличии сохраненные куки, привязанные к домену, к которому выполняется запрос. При наличии в HTTP-запрос добавляется заголовок

Cookie: name=value

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

В куки можно указать время ее жизни. Для этого добавляется специальный атрибут expires следующим образом:

Set-Cookie: name=value; expires=date

Где date - дата и время, когда браузеру следует удалить данную куки, например:

Обратите внимание на формат атрибута expires.

При помощи атрибута path можно ограничить область действия куки. По умолчанию куки применяются ко всем запросам данного домена, что соответствует значению path=/ . Если, допустим, задать path=/doc/ , то куки будут применяться только к запросам к директории /doc/, а также всем ее поддиректориям и документам, например, /doc/images/. Пример с атрибутом path:

Можно также переопределить привязку к домену при помощи атрибута domain . По умолчанию куки привязывается к домену документа, запрос которого инициализировал создание куки. Если указать .domain.ru , то куки будет распространяться на запросы к домену domain.ru, а также ко всем его поддоменам. Можно ограничить действие конкретным поддоменом, например www.domain.ru. Пример с использованием атрибутов expires, path и domain:

Настало время разобраться, как работать с куки в PHP. Для установки куки существует PHP-функция setcookie:

Bool ( string $name [ , string $value [ , int $expire = 0 [ , string $path [ , string $domain [ , bool $secure = false [ , bool $httponly = false ] ] ] ] ] ] )

Большинство параметров функции необязательные. Разберемся на реальном примере (предложенная ранее страница с выбором цвета фона):

"#090" , "синий" => "#009" , "красный" => // Цвет фона по умолчанию (белый). Цвет будет взят из куки, если соответствующая куки будет существовать (реализуем позже) ?>
">
Желаемый фон:

В этом примере еще не задействован механизм куки, лишь создан каркас страницы. Если вы читали предыдущие статьи и уроки, то разобраться в данном коде должно быть вам по силам. В массиве хранится список возможных цветов (можно добавить свои), цвета выводятся в HTML-форме в виде выпадающего списка. Теперь необходимо написать обработчик данных из формы. Традиционно помещаем его сверху, после объявления данных:

"#090" , "синий" => "#009" , "красный" => "#900" ) ; $bgcolor = "#fff" ; // Цвет фона по умолчанию (белый). Цвет будет взят из куки, если соответствующая куки будет существовать (реализуем в следующем примере) //--Сохраняем значение цвета фона в куки. Подробности ниже в статье } ?>

Обработчик получает значение выбранного пользователем цвета и сохраняет его в куки при помощи PHP-функции setcookie. Функция setcookie добавит в формирующийся HTTP-ответ заголовок Set-Cookie с нашей куки. Ее, как и функцию header, можно использовать только до вывода, то есть, как можно выше в коде.

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

if ( isset ([ "bgcolor" ] ) && in_array ([ "bgcolor" ] , $colors ) ) { $bgcolor = [ "bgcolor" ] ; }

Все очень просто. Если вместе с запросом скрипта были отправлены какие-либо куки, PHP помещает их в глобальный массив $_COOKIE. Таким образом, работа с принятыми куки ничем не отличается от, скажем, работы с принятыми GET или POST-параметрами. Полный листинг скрипта:

"#090" , "синий" => "#009" , "красный" => "#900" ) ; $bgcolor = "#fff" ; // Цвет фона по умолчанию (белый) //--Проверяем, есть ли уже сохраненный в куки bgcolor (также проверяем на корректность, т.к. куки легко подменить) if ( isset ([ "bgcolor" ] ) && in_array ([ "bgcolor" ] , $colors ) ) { //--Если есть, используем сохраненное значение $bgcolor = [ "bgcolor" ] ; } //--Проверяем, был ли передан GET-параметр bgcolor и имеется ли он в нашем массиве. А то, знаете ли, могут передать мало ли чего, а нам потом расхлебывать;) if ( isset ($_GET [ "bgcolor" ] ) && in_array ($_GET [ "bgcolor" ] , $colors ) ) { $bgcolor = $_GET [ "bgcolor" ] ; //--Это будет наш новый фон для страницы ("bgcolor" , $bgcolor ) ; } ?> Возможность выбора фона страницы
">
Желаемый фон:

Вникните в работу скрипта, если есть вопросы - welcome в комментарии. Цвет фона сохраняется в так называемую временную куки , которая при закрытии браузера будет удалена. Давайте используем постоянную куки, для этого необходимо в функции setcookie определить третий параметр - время удаления куки, который будет преобразован в атрибут expires HTTP-заголовка Set-Cookie. В параметре указывается отметка времени в Unix формате. Чаще всего для формирования такой отметки используют PHP-функцию time(), которая возвращает текущее время в Unix формате, прибавляя к ней количество секунд, по истечении которых куки должна быть удалена. Например, time()+3600 - удалить куки через час. Сделаем нашу куки активной одну неделю:

("bgcolor" , $bgcolor , time () + 3600 * 24 * 7 ) ; //--Сохраняем значение цвета фона в куки

Все, теперь выбранный цвет фона сайт "помнит" даже после закрытия браузера. Кстати, чтобы удалить куки достаточно указать в качестве expire прошедшую дату, например time()-3600 . Не забывайте просматривать HTTP-заголовки при тестировании примеров.

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

8 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.

Последнее обновление: 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);