Работа с cookie в PHP
Cookie - это набор данных, который создаётся Web-сервером и который отсылается при каждом обращении к серверу. Cookie хранятся в браузере пользователя. Как правило, cookie используется для: сохранения различных настроек, уникальных для пользователя, аутентификации пользователя, различной статистики и других подобных вещей. И о работе с cookie в PHP мы и поговорим в этой статье.
Начнём с простейших вещей: с записи cookie в браузер пользователя. Для этого существует функция setcookie():
<?php
setcookie("Name", "Value");
?>
После запуска скрипта, Вы сможете посмотреть cookie. Посмотреть их можно следующим образом: либо поискать в настройках браузера, либо поискать прямо на жёстком диске, где хранятся cookie Вашего браузера, либо (самый простой способ) ввести в адресной строке: "javascript:document.cookie". Только вводите в той же вкладке, в которой Вы запускали скрипт, потому что браузеры отделяют cookie одного сайта от другого.
Теперь встаёт вопрос: "Как вывести cookie?". Выводятся они с помощью массива $_COOKIE:
<?php
echo $_COOKIE["Name"];
?>
В результате, Вы увидите "Value". Как видите всё элементарно.
И давайте сейчас с Вами решим такую задачу: если пользователь авторизован на сайте, то поздороваться с ним, иначе вывести форму входа. Причём, если данные, введённые в форму, неправильные, то вывести соответствующее предупреждение. Реализация выглядит следующим образом:
<?php
function showForm() {
$string = "<form action = '".$_SERVER["SCRIPT_NAME"]."' method='post'>";
$string .= "<label>Логин: </label>";
$string .= "<input type = 'text' name = 'login'>";
$string .= "<br />";
$string .= "<label>Пароль: </label>";
$string .= "<input type = 'password' name = 'pass'>";
$string .= "<br />";
$string .= "<input type = 'submit' name = 'log' value = 'Войти'>";
$string .= "</form>";
return $string;
}
function check($login, $pass) {
if (($login == "Admin") && ($pass == md5("123456"))) 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 "Неверные данные";
}
?>
<html>
<head>
</head>
<body>
<?php
$login = $_COOKIE['login'];
$pass = $_COOKIE['pass'];
if (check($login, $pass)) echo "Здравствуйте, $login";
else echo showForm();
?>
</body>
</html>
Код достаточно прозрачный, однако, данную статью могут читать и новички, поэтому давайте этот код разберём более подробно. Вначале мы пишем две функции: одна для вывода формы входа, а вторая функция возвращает true, если данные корректны (то есть, если логин - "Admin", а пароль - "123456"), иначе возвращает false. Обратите внимание на $_SERVER["SCRIPT_NAME"]. Данная константа содержит путь к текущему файлу. То есть мы хотим, чтобы обработчик формы (значение атрибута action) был этот же файл.
Далее мы проверяем: была ли отправлена форма (существует ли переданное значение "log"). Если существует, значит, форма была отправлена и начинаем проверять полученные данные. Обратите внимание, что пароль мы пропускаем через функцию md5(), чтобы не хранить пароль в cookie в открытом виде. Используя функцию check() мы проверяем: верны ли данные. Если данные верны, то записываем их в cookie, иначе выводим строку: "Неверные данные".
Далее мы начинаем выводить HTML-теги. Обратите внимание, что мы не можем использовать функцию setcookie() после того, как вывели что-то в браузер. То есть нельзя, например, вывести HTML-теги, а потом воспользоваться функцией setcookie(), иначе возникнет ошибка. И, поверьте, её очень многие новички допускают.
После вывода HTML-тегов мы приходим к моменту, когда надо проверять cookie. Мы считываем их, а затем проверяем. Если они верные, то здороваемся с пользователем, иначе выводим форму входа.
Вот и весь скрипт, как видите, разобраться можно. Однако, он имеет один изъян, связанный с тем, что мы выводим "Неверные данные" до тега "<html>". Поэтому домашнее задание: исправить эту ошибку, чтобы не было нарушения валидности HTML-кода. Сделать это очень просто, однако, будет крайне полезно, так как Вам придётся разобраться в этом коде, а, следовательно, разобраться с тем, как работать с cookie в PHP. А использовать cookie в PHP приходится очень часто, и я постараюсь в следующих статьях закрепить Ваши знания о них.
-
- Михаил Русаков
Комментарии (59):
Столкнулся с такой проблемой. Если за раз попытаться установить куки и тут же прочитать его, то куки будет пустым. И только если обновить страничку, браузер его подхватит. То же самое и с вышеприведенным примером. Логинишься под Админом - пустая форма. Обновляешь - "Здравствуйте, Админ".
Ответить
У cookie есть одно очень важное ограничение. Нельзя их создать и использовать на той же странице. Если брать пример в статье, то подобные вещи делаются так: добавление cookie происходит на другой странице, а затем идёт редирект на нужную (например, обратно). Тогда cookie будут считываться сразу.
Ответить
Большое спасибо за ответ!
Ответить
Саму регистрацию точно также делать? Только там добавить "Зарегистрироваться", и несколько полей? Тоесть PHP-код не меняется в регистрации?
Ответить
Нет, регистрация делается совсем по-другому. Сам алгоритм описан в этой статье: http://myrusakov.ru/php-regauth-user.html
Ответить
А какой скрипт нужен для того чтобы перейти на стиль php? <script type="text/php"> не получается.
Ответить
Для работы PHP нужен интерпретатор. Поэтому установите Denwer, а дальше создайте PHP-файл, в котором можно использовать PHP-код и HTML-теги. PHP-код начинается с <?php и заканчивается ?>
Ответить
А как установить куки навсегда?
Ответить
Они по умолчанию устанавливаются и так навсегда, однако, нужно понимать, что cookie хранятся у пользователя. Поэтому если он их удалит (либо его браузер), то cookie удалятся.
Ответить
А разве куки не удаляются после закрытия браузера пользователем???
Ответить
Если пользователь настроил браузером таким образом, то удалятся. Но по умолчанию они при закрытии не удаляются.
Ответить
Спасибо
Ответить
Похоже, при вводе логина форма чувствительна к регистру. При вводе в поле "Логин" не получалось ввести Admin с большой буквы, возвращал только с маленькой и выдавал "неверные данные". Изменил в скрипте Admin на admin - заработало. Может быть проблема в настройках браузера (хотя в 2-ух разных проверил) или Денвера?
Ответить
В данном случае, да, проверка регистрозависимая. Но сделать её нерегистрозависимой очень просто, достаточно использовать функцию strtolower().
Ответить
Будет ли корректно сделать это в функции проверки, например так: function check($login, $pass) { if (($login == "Rama"|| strtolower($login) == "rama") && ($pass == md5("777"))) return true; else return false; Вроде работает
Ответить
Надо просто strtolower($login) == "rama", никаких $login == "Rama" || - не нужно.
Ответить
Перестраховался))),спасибо!
Ответить
Я правильно понял? Cookie хрянятся в браузере пользователя и гдето на его компе в файле? Можно эти прокл... Cookie запустить на очень долгое время? Как в контакте, например. Как это сделать
Ответить
Да, всё правильно поняли. Запустить их надолго можно, например, так: setcookie("name", $value, 0x6FFFFFFF);
Ответить
А как сделать так, чтобы при нажатии на Выход, удалялась не только переменная с логином и паролем, но и этот файл на его компе?
Ответить
setcookie ("name", "", time() - 3600); - как пример. Тогда cookie удалится сразу.
Ответить
а каким образом можно удалить например куки при разлогинивании на сайте? Ведь уже были выведены данные, в частности та же форма авторизации и при использовании setCookie() будет ошибка Cannot modify header information — headers already sent by…
Ответить
Здравствуйте! Я столкнулся с необходимостью применить cookies для защиты от повторного голосования!!! Гугл внятных ответов не дал...(или я не смог понять...) Конечна защита так себе, но для такого вида вполне подходит! Я прописал каждой фотографии уникальный id и отправляю после обработки формы его в куки вот таким образом: setcookie("vote",$uniq_id,time()+9999999); Но при повторном голосование они не действуют хотя я прописываю условие в начале обработчика формы: if (isset($_COOKIE['vote'])) { echo "Вы уже голосовали!"; echo "<html><head> <meta http-equiv='Refresh' content='1; URL=photo_viewer.php?title=$title'> </head></html>"; exit(); } Подскажите пожалуйста что тут не так... Я уже просто в тупике... Ну или если есть другие варианты защиты от повторного голосования - я бы с радостью почитал! Заранее спасибо!
Ответить
Проверьте для начала, устанавливается ли cookie вообще. Выведите её значение.
Ответить
Попробовал вывести - ничего не выводит... хотя если попробовать вывести переменную $uniq_id - то выводит...
Ответить
Но если отправлять в форме несколько скрытых переменных, то $uniq_id пропадает... Может быть я не правильно написал форму??? printf ("<div id = 'preview'> <a href ='%s'> <img class='smallpics' src='%s' /> </a> <br> <p class='rate'>PR<img src='objects/%s.png' height='15px' width='90px'></p> <form action='vote_res.php' method='post' name='vv'> <p class='vote'>PR: <input name='score' type='radio' value='1'>1<input name='score' type='radio' value='2'>2<input name='score' type='radio' value='3'>3<input name='score' type='radio' value='4'>4<input name='score' type='radio' value='5' checked>5 <input id='okBut' type='image' src='objects/ok2.png' name='submit' value='V'> <input name='id' type='hidden' value='%s'> <input name='title' type='hidden' value='%s'> <input name='vote' type='hidden' value='%s'> </p> </form> </div>", $myrow ["link"], $myrow ["thumbnail"], $r, $myrow["id"], $myrow["title"], $myrow["uniq_id"]);
Ответить
cookie устанавливается только после перезагрузки страницы.
Ответить
Пробовал и после перезагрузки страницы вывести - нет результата... Может быть я допустил ошибку в отправке формы?
Ответить
В форме cookie не устанавливаются, попробуйте setcookie("var", 15); - и проверьте устанавливаются ли cookie вообще.
Ответить
Мне нужно чтобы они установились после обработки формы, т.е. форма отправляется для подсчёта голосов, а с ней отправляется $uniq_id, которая и должна во время обработки попасть в массив COOKIE через setcookies("vote", $uniq_id) но к сожалению ничего не выходит...
Ответить
setcookie(), а не setcookies().
Ответить
Всё правильно... Это здесь я допустил ошибочку! Прошу прощения!)
Ответить
а зачем вообще HTML-теги? без них работает так же как и с ними..
Ответить
В данной статье не обязательны (браузеры, к сожалению, и мусорный код отображают, порой, неплохо), но нужны, раз этот сайт обучает грамотному кодированию.
Ответить
С добавление cookies вопрос решился, но возникла другая проблема - голосование идёт в галерее фото, и соответственно name у cookie всегда одинаковый и при добавление setcookie("vote",$uniq_id,time()+9999999) значение кУкис просто заменяется и появляется возможность голосовать за предыдущее фото... можно ли сделать что то вроде setcookie("vote" + $id,$uniq_id,time()+9999999) или добавлять к значению vote дополнительное значение чтобы не происходила замена старых cookies... Заранее спасибо за ответ!
Ответить
Зачем тогда вообще $uniq_id подставлять? Просто поставьте в cookie какой-нибудь vote=1 и всё. И если vote=1, то голосовать уже запрещено.
Ответить
Тогда за остальные фото тоже не проголосуешь... Нужно чтобы после каждой обработки формы, за каждое фото складывались уникальный cookies и повторно уже за это фото голосовать было невозможно!
Ответить
Если допустим проголосовали за фото с $uniq_id = vesna5 то vote получит такое значение и при повторном голосование сравнив vote и $uniq_id выдаст сообщение вы уже голосовали! А проголосовать за другое фото будет можно! Но при этом значение vote изменится и голосование за предыдущее фото снова станет возможным... А этого нельзя допускать! Как мне сделать чтобы vote получало каждый раз новое имя типа vote1, vote2 и т.д. Заранее спасибо за ответ!
Ответить
Не могу вывести cookie на странице <?php echo $_COOKIE['name'] ?> пишет: Undefined index: name в браузере кука присутствует что делать?
Ответить
cookie выводится этим скриптом?
Ответить
да
Ответить
При установке cookie указывайте ещё домен сайта (4-й параметр в setcookie()).
Ответить
Здравствуйте, Михаил. у меня возникла проблема следующего содержания: есть xml из которого я получаю номер заказа, и хочу создать куки с именем номер заказа и не получается ((( может подскажете?) code: preg_match("/<PersonalAccount>(.*)<\/PersonalAccount>/i", $_POST['XML'], $matches); foreach($matches as $key=>$val){ $n_order = $val; } $mame_cookie = $$n_order; setcookie($mame_cookie, "1", time()+1200); echo '<?xml version="1.0" encoding="windows-1251"?> <ServiceProvider_Response> <TransactionStart> <ServiceProvider_TrxId>xxx</ServiceProvider_TrxId> <Info xml:space="preserve"> <InfoLine>Оплачено!</InfoLine> <InfoLine>' . $_COOKIE["$mame_cookie"] . '</InfoLine> </Info> </TransactionStart> </ServiceProvider_Response>';
Ответить
А что именно не получилось? Регулярное выражение не срабатывает, или куки не выставились?
Ответить
куки не выставились. дело в том, что если я создаю куки с переменными которым задаю значения я сам,все работает, а когда пытаюсь впихнуть значение полученное из xml, не работает( я проверял тип полученой переменной - это просто строка то есть все должно работать но не работает...почему??? не понятно
Ответить
Здравствуйте, Михаил. У меня на сайте есть главный файл index.php и папка class, в ней лежат классы. Я создал класс для авторизации и подключаю его в главном файле с помощью require_once. Сначала, когда я вставил ваш код, появилась ошибка: Cannot modify header information - headers already sent by. Поискав в интернете, я понял, в чём заключалась моя ошибка. Там написано, что надо поставить сохранить без BOM. Так вот появилась другая проблема: У меня теперь все символы на сайте в русском языке отображаются какими-то странными символами, то есть проблема с кодировкой, а когда я ставлю как было: кодировать в utf-8, опять появляется проблема с заголовками. Не подскажите, что делать? Я пробовал изменить это и в теге <head> и много чего ещё, но проблема осталась
Ответить
а вы сначала нажмите Преобразовать в UTF-8 без BOM,а потом уже сохранить =)
Ответить
А то есть вы думаете, что я не сохраняю!? Нет, я сохраняю!
Ответить
Я думаю,что Вы не нажимаете Преобразовать в UTF-8 без BOM используя Notepad++ вкладка Кодировки =) и в meta charset потом не меняете кодировку на utf-8 =) такие вот пироги,уважаемый
Ответить
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - она у меня и раньше так и была! А пироги, я надеюсь, яблочные, мои любимые?
Ответить
может и яблочные Закиньте ваши файлы в архив,залейте на rghost потом ссылку мне в тикете службы поддержки с указанием,что это Вы Посмотрю,что там у Вас)
Ответить
Все, получилось. Оказывается, в файле .htaccess нужно было добавить строку: AddDefaultCharset UTF-8
Ответить
Михаил, здравствуйте! А как сделать кнопку выхода в данном скрипте?
Ответить
Вы имеете ввиду закрыть сессию? Сессия закрывается с помощью session_destroy();
Ответить
Здравствуйте! В приведенном Вами Коде $_COOKIE устанавливаются только после повторного вызова формы. Сумел это исправить только заменив setcookie("login", $login); setcookie("pass", $pass); на $_COOKIE['login'] = $login; $_COOKIE['pass'] = $pass; Как бы Вы это объяснили. Спасибо.
Ответить
а как удалить кукис? в статье об этом не написано. у меня задача такая: я сделал вход пользователя, и когда он на сайте, то сверху показывается кнопочка "выйти", и если на неё нажать, то кукис удаляется и пользователю надо вновь заходить. как удалить кукис?
Ответить
<h1>Домашнее задание решено </h1> - дело в кадировке
Ответить
Михаил такая проблема форму сделал обработчик тоже я использовал ваш код но вот проблема на странице отображается только форма и по вводу данных она возвращается несколько раз обратно к форме после чего, выдаёт ошибку 404(думаю все знают). Как исправить сей конфуз?
Ответить
Привет. При выводе перед setcookie() header() в том числе при кодировки utf-8 без bom в версиях php 5.6 и 7 не выскакивает Warning: Cannot modify header information - headers already sent by (output started at ... связан ноли это с версиями ?
Ответить
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.