Подтвердить что ты не робот

Почему этот 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

Читать комментарии для дополнительной информации

4b9b3361

Ответ 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 Проверьте размер данных сеанса, возможно, он превышает размер кеша. или некоторые другие данные сеанса хранятся, исчерпывая кеш-память. Увеличьте размер кеша, возможно, он поможет в вашем сценарии.