Работа с cookies

Вторник, 19 августа 2008 г.
Рубрика: PHP
Просмотров: 4215
Подписаться на комментарии по RSS

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

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

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

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

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

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

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

twitter.com facebook.com mail.ru friendfeed.com livejournal.ru memori.ru google.com yandex.ru

Комментариев: 9

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

  2. Ну «каталог»-то не меняется wink

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

  4. ... которые работают только «вниз»...

  5. Жду еще лекций

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

    Дело в том, что при корректной обработке кук в браузере и проблем–то никаких нет. Действительно, если при установке куки параметр 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. Тут два момента. Указание «/» ни к чему не приводит. Правда я тестировал на localhost и может это связано именно с этим, но даже если это так, то уже вариант не подходит.

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

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

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

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

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

Оставьте свой комментарий!

grin LOL cheese smile wink smirk rolleyes confused surprised big surprise tongue laugh tongue rolleye tongue wink raspberry blank stare long face ohh grrr gulp oh oh downer red face sick shut eye hmmm mad angry zipper kiss shock cool smile cool smirk cool grin cool hmm cool mad cool cheese vampire snake excaim question

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

(войти без комментирования)

Имя и сайт используются только при регистрации

Авторизация: Loginza.

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