Идентификатор сеанса PHP изменяется между страницами
У меня проблема, когда я теряю сессию PHP между 2 страницами.
Session_start() включен в файл с именем session-inc.php на каждую страницу, требующую установки сеанса. Это работает для всех страниц сайта, кроме одной конкретной страницы, member-profile.php. Когда эта страница посещается, вместо нее устанавливается и используется новый сеанс с другим идентификатором (то же имя сеанса).
Еще несколько деталей:
- Имя сеанса устанавливается вручную
- Все страницы находятся на одном сервере под одним и тем же доменным именем
- Если я добавлю дополнительный session_start() над include ('session-inc.php') в файле member-profile.php, сеанс будет перенесен правильно
- Я попытался установить session_cookie_domain и session.session_name в .htaccess, это сработало для этого домена, но оно прекратило передачу сеанса вне домена оплаты
- Мы запускаем apache 2.2.6 с php 5.2.5
Включение session_start() над include ('session-inc.php') в файле member-profile.php - это быстрое и грязное исправление для этой проблемы, но мне интересно, знает ли кто-нибудь, почему это происходит.
Приветствия
Воля
Ответы
Ответ 1
Согласно документации PHP, session_start
должен быть вызван до того, как любой вывод будет отправлен обратно в браузер - может ли эта страница иметь rogue CR/LF, знак байта Unicode или аналогичный, который вызывает вывод перед вами include('session-inc.php')
?
Ответ 2
При переносе устаревшего сайта с PHP4 на PHP5 я заметил настройку конфигурации php.ini, которая заставляет php автоматически запускать сеанс при каждом запросе. Это альтернатива размещению session_start()
на каждой странице...
Существует несколько способов включить этот параметр:
Поместите следующую строку в php.ini:
session.auto_start = on
или поместите это в конфигурацию виртуального сайта apache или файл .htaccess:
<IfModule mod_php5.c>
php_flag session.auto_start on
</IfModule>
и он должен сделать изменения $_SESSION доступными для всех страниц
Ответ 3
Я только что столкнулся с этой проблемой. Интересно, что просмотр через http://127.0.0.1
вместо http://localhost
помог мне.
Ответ 4
Обнаружена проблема
В начале основного файла был отмечен знак байтового заказа, включающий файл второго домена. как указано ken, не может иметь какой-либо вывод перед началом сеанса, он не правильно установил сеанс.
Ответ 5
Обнаружено, что проблема заключалась в том, что знак байтового байта (BOM) был выведен в начале файла. Из него избавился, и он разобрал проблему с сеансом.
Ответ 6
РЕШЕНИЕ:
session.auto_start = on
в файле: php.ini
Он решил проблему повторного генерации идентификатора сеанса на странице перезагрузки (страницы обновления/изменения страницы).
Проблема появилась после обновления CPanel (и включила Multi PHP), даже версия php осталась прежней.
В файле PHP.ini не было этой переменной.
Пошел в Cpanel → Редактор INI MultiPHP → Режим редактора (не Basic, в основном у вас нет этой настройки) и добавил строку. Нажмите Сохранить.
СОВЕТЫ/КОГДА ИСПОЛЬЗОВАТЬ ЭТО РЕШЕНИЕ:
Чтобы определить, является ли это проблемой, поместите строку в самом начале и в самом конце вашего файла index.php, чтобы проверить идентификатор сеанса. Функция использования:
идентификатор сессии();
Навигация по страницам/перезагрузка страницы. Если значение session_id изменяется, проблема не в коде, и это решение должно решить вашу проблему (сеанс потерян за пределами вашего кода).
Я также попытался проверить доступность сеанса сохранения на веб-сервере (session.save_path), но даже если это было причиной, это было не так.
Я предполагаю, что это "функция" Cpanel с MULTIPHP UPDATE, которая будет происходить довольно часто.
Ответ 7
У меня была эта проблема, и причина была в том, что PHP игнорировал все куки после первых 100. (Я задал этот вопрос, чтобы попытаться выяснить, почему, но до сих пор никто не понял это). Браузер отправлял PHPSESSID *, но так как это был 110-й файл cookie, PHP игнорировал его.
Чтобы выяснить, влияет ли эта проблема на вас, используйте инструменты разработки вашего браузера, чтобы посмотреть файлы cookie, которые браузер отправляет вместе с запросом, и сравните этот список с массивом $ _COOKIE в PHP. Они должны быть одинаковыми. Но если браузер отправляет PHPSESSID *, а в $ _COOKIE нет PHPSESSID *, то это объясняет, почему сеансы не работают.
Я решил проблему, так как на моем сайте не использовалось так много файлов cookie, что в любом случае является хорошей практикой.
* PHPSESSID - это имя сеанса по умолчанию. Ваш сайт может использовать другое имя.
Ответ 8
Чтобы решить изменение session_id после каждого запроса, вы изменяете параметры session.auto_start и session.cookie_httponly в файл конфигурации php.
найти используемый файл конфигурации php
php -i | grep "php.ini"
затем вы открываете его и пытаетесь найти параметр session.auto_start. Ты устанавливаешь
session.auto_start = 1
session.cookie_httponly = 0
наконец вы перезапускаете службу httpd/apache.
Ответ 9
Нашел проблему
В моем случае это было связано с настройками лака, пожалуйста, проверьте настройки лака. PHPSESSID вы можете исключить куки из настроек лака.
Ответ 10
Я потратил весь день на диагностику этой проблемы в своем проекте Ionic3-to-PHP. TL; DR - убедитесь, что ваш клиент на самом деле отправляет учетные данные сеанса.
В интересах помощи любому, кто совершит эту ошибку, я поделюсь, как я нашел проблему. Я использовал эти инструменты для диагностики сеанса как на клиенте, так и на сервере:
1) Добавьте тестовый файл с phpinfo() на сервер, чтобы просмотреть параметры сеанса PHP.
2) Просмотрите код PHP, чтобы убедиться, что перед строкой session_start() не происходит никакого вывода, преднамеренного или непреднамеренного. Проверьте строку состояния кода Visual Studio и убедитесь, что метка порядка байтов (BOM) отсутствует в файлах PHP.
3) Просмотрите логи PHP сервера (в /var/log/nginx/error.log для меня). Добавьте строки error_log() в файл php, чтобы получить дамп массива session_id() или $ _SESSION.
4) Используйте tcpdump -An 'port 80 or port 443'
для просмотра фактических HTTP-запросов и ответов. (Это где я обнаружил пропавшие куки).
Для поставщика данных Ionic3 правильный синтаксис для клиента:
var obsHttp = this.http.post(url, body,
{ headers: new HttpHeaders({
'Content-Type':'application/x-www-form-urlencoded'
}),withCredentials: true }).timeout(this.timeoutTime);
Обратите внимание на withCrentials:true
Для отправки запроса нужно вызвать подписку на obsHttp().