Почему этот PHP скрипт (вызываемый AJAX) случайным образом не загружает SESSION правильно?
Ahoy StackOverflow,
Я столкнулся с этой проблемой в своем проекте: короче, из того, что я собрал, является то, что PHP script, вызываемый через AJAX, неправильно регистрирует переменные SESSION, которые были установлены в верхней части index.php
стр. Сначала я предположил, что это произошло из-за блокировки сеанса, поэтому я пошел дальше и добавил session_write_close()
, однако это не устранило проблему.
Эта проблема возникает только около 25% времени после начала нового пользовательского сеанса (т.е. когда пользователь входит в систему).
Я пошел вперед и удалил 90% кода, чтобы получить ошибку до минимального минимального кодирования, необходимого для воспроизведения.
Плохой результат Firebug через ajax.php
![image]()
Ожидаемый результат Firebug через ajax.php
![image2]()
Примечание. Оба результата показывают возврат индекса print_r($_SESSION)
как Array ( [userid] => 3724 [trialstatus] => 1 [trialtcompletions] => 0 [userlevel] => 5 )
, который позволяет мне знать, что проблема не связана с тем, что сеанс установлен на индексной странице.
Кто-нибудь знает исправление (возможно, даже не кодовое, а может быть, и настройку сервера), которое правильно разрешит script через AJAX правильно обращаться к переменной сеанса?
Сценарий тестирования для воспроизведения
- Удалить все файлы cookie для домена
- Загрузите страницу (макс. 2 раза). Проблема не возникает после двух перезагрузок.
- Если плохой результат не отображается, повторите шаги.
index.php
<?php
if (session_status() === PHP_SESSION_NONE) session_start();
if (!isset($_SESSION['userid']))
{
$_SESSION['userid'] = 3724; //$login['AccountID'];
}
$_SESSION['trialstatus'] = "12";
$_SESSION['trialtcompletions'] = "12";
$_SESSION['userlevel'] = "12";
session_write_close();
print_r($_SESSION);
?>
<!DOCTYPE html><html><head><script src="./js/jquery.min.js"></script>
<script>
function loadStage(step,input,callback){
$.ajax({
type: "POST",
url: "./ajax.php",
data: { step: step, input: input },
dataType: "JSON",
timeout: 5000,
success: function(data){
if(data !== false){
callback(data);
}
}
});
}
$(document).ready(function(){
startLoadingSequence();
});
function startLoadingSequence(skipped){
loadStage(1,skipped,function(data){});
}
</script>
</head></html>
ajax.php
<?php
if (session_status() === PHP_SESSION_NONE) session_start();
print_r($_SESSION);
if (!isset($_SESSION['userid']))
{
die(json_encode(array(
"error",
"You must be logged in to view report data."
)));
}
?>
По запросу:
![phpinfo]()
Читать комментарии для дополнительной информации
Ответы
Ответ 1
Это может вызвать две вещи.
- У вас недостаточно места в пути сохранения сеанса (df -h), или у вас нет разрешения на его сохранение.
- Ваш сервер находится за балансировщиком нагрузки, и вы должны сохранять сеансы в постоянном бэкэнд, например memcache или redis.
Ответ 2
Если вы используете балансировщик нагрузки, вы должны убедиться, что ваши серверы используют общую точку для данных. По умолчанию PHP хранит сеансы в локальной файловой системе. Это становится проблемой, если ваш балансировщик нагрузки отправляет вас с сервера A на сервер B, где этот файл не существует. Вы можете настроить сетевой ресурс и убедиться, что все веб-серверы используют этот ресурс. Таким образом, вы можете создать общий ресурс NFS, а затем добавить session_save_path или установить его в php.ini
session_save_path('/your/nfs/share/here');
Другим вариантом является написать собственный обработчик сеанса, который помещает сеансы в вашу базу данных. Затем вы можете использовать что-то вроде memcached для хранения сеансов таким образом, чтобы вы не ударяли свою БД каждый раз, когда вы читаете данные сеанса.
Ответ 3
Снимок экрана, который я приложил, для почти всех 25-30 запусков, которые я выполнил. [1]: http://i.stack.imgur.com/MgLpS.jpg Проверьте размер данных сеанса, возможно, он превышает размер кеша. или некоторые другие данные сеанса хранятся, исчерпывая кеш-память. Увеличьте размер кеша, возможно, он поможет в вашем сценарии.