Работа с cookies

Просмотров: 12658Комментарии: 10
Старый архив

Сегодня столкнулся с одной «особенностью» CodeIgniter и, как следствие MaxSite CMS. Задача очень простая: нужно выставить куку и потом использовать её значение на сайте.

В начале казалось все очень просто: стандартная setcookie() прекрасно справляется с поставленной задачей, но в процессе отладки выяснилось, что есть один маленький нюанс, который не позволяет вот так просто выставить куку.

Всё дело в том, что кука выставляется для страницы или, если точнее, для всего каталога и его подкаталогов. Я хотел выставлять куку с помощью ссылки вида «http://site/setlang/en». В этом адресе я и ставлю куку, а потом делаю редирект на предыдущую страницу (referer). И тут выясняется, что кука для неё не существует. Мои попытки как-то обмануть и прописать явно домен и каталог ни к чему не привели. По адресу «http://site/» установленная кука недоступна.

Проблема связана с тем, что CodeIgniter просто не понимает запросы вроде index.php?param=val - вместо этого используется разделение слэшами («/»). А для браузера это не что иное как каталог на сервере. Ему же нет дела до CodeIgniter, вот он и понимает такой адрес буквально. ;)

В общем путем гугления и перечитывания php.net придумал «обходной маневр»: если нужно добавить куку для всего сайта (по сути главной страницы), то вначале все эти куки записываются в текущую сессию (которая как раз для всех страниц доступна). После этого делается редирект на главную страницу, с неё уже выставляются куки как положено, и еще раз редиректимся на главную.

Получается немного запутано, зато работает без проблем. Я даже написал функцию mso_add_to_cookie, которая как раз все и сделает автоматом.

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

Комментариев: 10 RSS

1Олег19-08-2008 19:46

Возможно, если бы были определены конечные страницы как *.html то такой броблемы не возникло бы.

3Sam20-08-2008 10:53

У setcookie есть в параметрах и путь и домен…

6Владимир22-08-2008 11:52

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

Дело в том, что при корректной обработке кук в браузере и проблем–то никаких нет. Действительно, если при установке куки параметр path не указан, то кука видна в том каталоге, в котором она установлена, а также во всех вложенных подкаталогах. Если же указать параметр path='/' (корневая кука), то кука будет видна во всех разделах сайта, вне зависимости от того, где была установлена. Никаких дополнительных манипуляций с сессиями здесь не требуется. Кстати о сессиях. PHP по умолчанию записывает ID сессии (SID) как раз в куку. И тот факт, что сессия доступна на всех страницах сайта, означает только то, что PHP устанавливает корневую куку, в которую и записывает SID. Это очень легко проверить: выполняем в любом подкаталоге сайта простейший скрипт, состоящий из одной команды - session_start() – и наблюдаем в FireFox с помощью плагина Web Developer, что создана кука с именем PHPSESSID и паараметром PATH = ‘/’.Но вернемся к вопросу корректной обработки кук в браузерах. Такая (корректная) работа с куками осуществляется в FF, Опере и в IE6. К сожалению, IE7 имеет очень неприятный баг: на некоторых компьютерах этот браузер видит только куку, установленную в текущем каталоге. Все прочие куки игнорируются. И параметр PATH тоже не работает. Вообще, IE7 сильно глючит при работе с куками – см., например, http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1214771&SiteID=1

Из-за багов IE7 в серьезных проектах приходится либо отказываться от кук, либо применять их в пределах одного каталога. То есть, прощай ЧПУ да и CI тоже.

7Максим22-08-2008 12:28

Тут два момента. Указание «/» ни к чему не приводит. Правда я тестировал на localhost и может это связано именно с этим, но даже если это так, то уже вариант не подходит.

А по сессии тут немного по-другому. Я использую сессию CodeIgniter - а это и есть кука, только для всего сайта. Поэтому ваш пример это обычная php-сессия, а CodeIgniter-сессии это чуть другое. Мне кажется, что мой алгоритм всё-таки более универсальный. Ну или как минимум браузеронезависим.

8AngryCATСайт23-08-2008 03:07

А чем в этом случае не подходит использование этого

$this->session->set_flashdata('item', 'value');
$this->session->flashdata('item');

Я тут смотрел исходники Linkster так там для передачи сообщений между методами именно этот способ использован.

9Максим23-08-2008 11:30

В этом случае сессия будет жить только отведенное время. Оно в конфигурации задается (7200 сек). Поэтому примерно так я и использую (только через set_userdata и unset_userdata), но только для того, чтобы сохранить данные куки в сессии, а контролер сам обработает и перенесет их в обычную куку, а из сессии удалит.

10Денис24-01-2016 06:12

Вот простое решение, чтобы работало из любой директории

setcookie("cookie", $cookiedata, time() + 3600 * 24 * 30, '/', $_SERVER["HTTP_HOST"]);
Оставьте свой комментарий!

Комментарий будет опубликован после проверки

Вы можете войти под своим логином или зарегистрироваться на сайте.

(обязательно)

О проекте

MaxSite CMS предназначена для создания сайтов любой сложности. Система отлично подходит обычным пользователям, вебмастерам, фрилансерам и вебстудиям.