Сегодня столкнулся с одной «особенностью» 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 17:46
Возможно, если бы были определены конечные страницы как *.html то такой броблемы не возникло бы.
2Максим19-08-2008 17:49
Ну «каталог»-то не меняется ;)
3Sam20-08-2008 08:53
У setcookie есть в параметрах и путь и домен…
4Максим20-08-2008 10:49
... которые работают только «вниз»...
5Роман21-08-2008 14:35
Жду еще лекций
6Владимир22-08-2008 09: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 10:28
Тут два момента. Указание «/» ни к чему не приводит. Правда я тестировал на localhost и может это связано именно с этим, но даже если это так, то уже вариант не подходит.
А по сессии тут немного по-другому. Я использую сессию CodeIgniter - а это и есть кука, только для всего сайта. Поэтому ваш пример это обычная php-сессия, а CodeIgniter-сессии это чуть другое. Мне кажется, что мой алгоритм всё-таки более универсальный. Ну или как минимум браузеронезависим.
8Аноним23-08-2008 01:07
А чем в этом случае не подходит использование этого
Я тут смотрел исходники Linkster так там для передачи сообщений между методами именно этот способ использован.
9Максим23-08-2008 09:30
В этом случае сессия будет жить только отведенное время. Оно в конфигурации задается (7200 сек). Поэтому примерно так я и использую (только через set_userdata и unset_userdata), но только для того, чтобы сохранить данные куки в сессии, а контролер сам обработает и перенесет их в обычную куку, а из сессии удалит.
10Денис24-01-2016 04:12
Вот простое решение, чтобы работало из любой директории