Intereting Posts
PHP Получить возвращаемое значение из конструктора Отображение ошибки разбиения на страницы с использованием mysqli Реляционный API: where () не может определить столбец, используя классы с именами Каков наилучший способ определить, на каком сервере работает скрипт, и, следовательно, на PHP? Загрузите Joomla 3.x Framework и модули во внешний файл PHP Миграции доктрины: в пространстве имен "" отсутствуют команды php: Сохранить изображение в Mysql blob, хорошо или плохо? Множественный узел клиента Php Jquery ajax, данные с src изображения jquery добавляет поле ввода и сообщение jQuery ajax call возвращает пустую ошибку в браузерах Mac Safari и Chrome Проблемы с контактной формой Ajax – не отправляется электронное письмо Как я могу исключить определенные поля формы при отправке формы без отключения поля отправлять данные при нажатии кнопки из javascript в базу данных Определите, запрашиваются ли HTTP-запросы из приложения Android или нет? и затем отреагировать соответствующим образом

Почему PHP не сохраняет переменные сеанса для определенных пользователей в Internet Explorer?

У меня проблема с сайтом, где PHP не сохраняет переменные сеанса для определенных пользователей в Internet Explorer. Но для некоторых других пользователей с Internet Explorer проблем нет, и у пользователей с другими браузерами тоже нет никаких проблем.

Я создал следующие три небольших сценария, чтобы убедиться, что на сайте не было другого кода:

test.php:

<?php session_start(); function logMsg($text) { $filename = dirname(__FILE__) . "/test.log"; $fh = fopen($filename, "a") or die("Could not open log file."); fwrite($fh, date("dmY, H:i")." - $text\n") or die("Could not write file!"); fclose($fh); } ob_start(); var_dump(session_id(), $_SESSION, $_SERVER, $_REQUEST); $content = ob_get_clean(); logMsg("test.php"); logMsg($content); $_SESSION['test'] = array('test' => 'lalala'); $_SESSION['count'] = 1; ?> <a href="test2.php">Next</a> 

test2.php:

 <?php session_start(); function logMsg($text) { $filename = dirname(__FILE__) . "/test.log"; $fh = fopen($filename, "a") or die("Could not open log file."); fwrite($fh, date("dmY, H:i")." - $text\n") or die("Could not write file!"); fclose($fh); } ob_start(); var_dump(session_id(), $_SESSION, $_SERVER, $_REQUEST); $content = ob_get_clean(); logMsg("test2.php"); logMsg($content); $_SESSION['count']++; ?> <a href="test3.php">Next</a> 

test3.php:

 <?php session_start(); function logMsg($text) { $filename = dirname(__FILE__) . "/test.log"; $fh = fopen($filename, "a") or die("Could not open log file."); fwrite($fh, date("dmY, H:i")." - $text\n") or die("Could not write file!"); fclose($fh); } ob_start(); var_dump(session_id(), $_SESSION, $_SERVER, $_REQUEST); $content = ob_get_clean(); logMsg("test3.php"); logMsg($content); 

Ожидаемый результат для var_dump($_SESSION) будет примерно таким:

 array(0) { } array(2) { ["test"] => array(1) { ["test"] => string(6) "lalala" }, ["count"] => int(1) } array(2) { ["test"] => array(1) { ["test"] => string(6) "lalala" }, ["count"] => int(2) } 

Однако выход для пользователей с проблемой заключается в следующем:

 array(0) { } array(0) { } array(1) { ["count"] => int(1) } 

Это означает, что переменные сеанса не сохраняются для этих пользователей. Однако идентификатор сеанса для пользователей с проблемами одинаковый для всех трех тестовых страниц.

Кто-нибудь знает, что это может быть? Насколько я знаю, проблемный код проработал несколько лет, и проблемы начали проявляться за последний месяц или около того.

редактировать

Ответы на вопросы в комментариях:

  • Я не могу воспроизвести проблему на локальном компьютере.
  • У меня есть сообщения о проблемах пользователей с IE7 и IE9. Но я не могу точно сказать, что с другими версиями проблем нет, потому что может быть, что они просто не сообщаются.
  • В браузере пользователя с этой проблемой не отключены файлы cookie, cookie PHPSESSID отправляется на сервер.
  • В имени машины нет – или _ ( https://stackoverflow.com/a/306601/534109 ).
  • Регенерация идентификатора сеанса с session_regenerate_id () не влияет на результат для пользователей с проблемой.
  • Настройки часового пояса и времени для пользователя с такой же проблемой, как и на сервере.

Изменить 2

Как указано в комментарии @ nl-x, данные сохраняются во втором запросе. Поэтому я адаптировал тестовый сценарий и добавил еще один шаг, чтобы увидеть, работает ли сеанс в последующих запросах. И это так. Данные сеанса, установленные в step2.php и step3.php , сохраняются между запросами.

Итак, теперь возникает вопрос, почему данные сеанса для первого запроса теряются, а не для последующих запросов?

Я понял, что у пользователей, у которых были проблемы, установлен Chrome Frame. Я проверил это, установив Chrome Frame на локальный компьютер, и в этом случае я смог реплицировать проблемы.

Проблемы были вызваны тем, что на нашем сервере установлен Suhosin. Были активированы следующие настройки Suhosin:

 suhosin.session.cryptua suhosin.cookie.cryptua 

Это означает, что строка User Agent также является частью идентификации сеанса пользователя. Обычно это не проблема, но для пользователей с установленным фреймом Chrome строка User Agent отличается от первого запроса и последующих запросов. После отключения этих настроек Suhosin проблем больше не было.

Я полагаю это, вместо того, чтобы ждать кого-то, обладающего особыми знаниями механизма сессии PHP:

Я работаю в основном с ASP.NET, а объект Session использует cookie для хранения данных по запросам. Если PHP работает одинаково, наиболее очевидный вывод состоит в том, что пользователи с проблемами сеанса либо отключили cookies, либо используют программное обеспечение, которое разрешает домены whitelisted устанавливать файлы cookie. Я посмотрю, смогу ли я найти какие-либо факты, чтобы поддержать эту теорию …

Из руководства по PHP ( http://www.php.net/manual/en/intro.session.php ):

Это либо сохраняется в файле cookie на стороне пользователя, либо распространяется в URL-адресе.

Я не могу точно сказать, почему в первый раз, после первого запроса, cookie, кажется, заблудился. (Это то, что, как я думаю, происходит.) И почему второй / второй запрос НЕ пропадает.

Возможно, проблема кеширования. Проверьте инструменты разработчика и посмотрите, что именно происходит на вкладке сети. Первый запрос поступает с 200-OK, и отвечает ли ответ на заголовок файла cookie? Или это действительно кэшировано, как сказал один из комментариев?

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

В основном это означает изменение:

 <a href="test3.php">Next</a> 

в:

 <a href="test3.php?<?php echo htmlspecialchars(SID); ?>">Next</a> 

или:

включение –enable-trans-sid

Теперь, когда PHP-уведомления о сеансах не передаются с помощью файлов cookie, он будет передавать их менее безопасным образом в URL-адресе. Особенно в этом случае вам понадобится session_regenerate_id() .

edit: Ой, да, я хотел упомянуть об этом раньше, но потом подумал, что это не может быть. Но, во-вторых, я все равно буду упоминать об этом! :

По умолчанию файлы cookie являются доменными. Если пользователь перейдет на сайт http://yourdomain.com (без www. ), А второй запрос будет отправлен на http://www.yourdomain.com , cookie не передержит изменение домена! Таким образом, влияет на вашу сессию.

Чтобы исправить это, либо настройте домен cookie сеанса, либо всегда используйте тот же домен (либо с www, либо без него).

Прежде всего, вы должны проверить конфигурацию сеанса php.ini, особенно продолжительность файла cookie. Добавьте раздел к вашему вопросу. Установите Fiddler на клиента, который дает вам сообщение об ошибке и выдает полный откат дат сеанса. Это должно помочь вам легко найти проблему.