Единственным долгосрочным решением является правильное использование session_write_close()
.
Как вы, несомненно, понимаете, данные сеанса заблокированы, поэтому только один сценарий в любой момент может записать в постоянное хранилище данных сеанса.Блокировка сеанса предотвращает трудное устранение ошибок параллелизма и является более безопасной.
Не видя вашу реализацию, очень сложно, э-э ... невозможно дать какой-либо точный совет.Вот некоторые вещи, которые следует учитывать, что может помочь разобраться в беспорядке.
Либо выполните ALL или NONE записей сеанса в функциях ответа AJAX.(Под «функцией ответа AJAX» я подразумеваю значение PHP controller/method
URL-адреса AJAX.)
С помощью ALL вызова подхода session_write_close()
в сценарии «main» перед выполнением любогоAJAX просит.Имейте в виду, что $_SESSION
не зависит от session_write_close()
.Все элементы $_SESSION
в сценарии main останутся доступными, чтобы вы могли надежно прочитать значения.Однако изменения , внесенные в $_SESSION
, записываться не будут, поскольку для PHP сессия закрыта.Но это верно только для сценария, который вызывает session_write_close()
.
При использовании подхода NONE вам все равно может понадобиться прочитать данные сеанса.В этом случае было бы целесообразно, чтобы функции ответа AJAX вызывали session_write_close
как можно скорее, чтобы минимизировать время, когда параллельные запросы блокируются.Вызов более важен для функций, которые требуют значительного времени для выполнения.Если время выполнения скрипта короткое, то явный вызов session_write_close()
не нужен.Если это вообще возможно, т. Е. Нет необходимости читать данные сеанса, то отсутствие загрузки класса session
может привести к более чистому коду.Это определенно исключило бы любую возможность одновременной блокировки запросов.
Не пытайтесь протестировать поведение сеанса, используя несколько вкладок в одном приложении в одном браузере.
Подумайте об использовании $config['sess_time_to_update'] = 0;
, а затем явно вызовите $this->sess_regenerate((bool) config_item('sess_regenerate_destroy'));
, когда и где имеет смысл изменить идентификатор сеанса, т.е. сразу после входа в систему;сразу после перенаправления на «чувствительную» страницу;и т. д.
То, что следует далее, предлагается с большим трепетом.Я проверил это с помощью драйвера «files», но не очень.Итак, покупатель остерегается.
Я обнаружил, что можно «перезапустить» сеанс, вызвав функцию PHP session_start()
после использования session_write_close()
.CodeIgniter откроет и прочитает хранилище данных сеанса и перестроит суперглобальный $_SESSION
.Теперь возможно изменить данные сеанса, и они будут записаны, когда выполнение скрипта закончится - или с другим вызовом session_write_close()
.
Это имеет смысл, потому что session_write_close()
ничего не делает для CodeIgniter session
объект.Класс все еще создается и настраивается.Пользовательский код SessionHandlerInterface
CodeIgniter используется для открытия, чтения и записи данных сеанса после вызова session_start()
.
Возможно, эта очевидная функциональность может быть использована для решения ваших проблем.В случае, если я не был ясен ранее - используйте на свой страх и риск!