#php #sql
#php #sql
Вопрос:
Мне было интересно, что session_write_close()
делает. Я нахожу руководство немного расплывчатым. У меня есть несколько довольно больших SELECT
запросов. Перед этими SELECT
запросами, которые я вызываю session_write_close()
, и после запросов, которые я вызываю session_start()
снова.
Вы можете задаться вопросом, почему я это делаю, если я этого не делаю, а пользователь выполняет один из этих SELECT
запросов и прерывает их (например, пытается открыть другую страницу), пользователь не может открыть новую страницу (или должен ждать довольно долго). Я думаю, потому что скрипт ждет, пока не будет выполнен большой запрос.
Итак, мой вопрос (ы):
Что именно session_write_close()
делает при вызове его перед запросом?
Почему пользователю не нужно ждать ( session_write_close()
перед запросом) при открытии новой страницы, при прерывании запроса?
Заранее спасибо
Комментарии:
1.
session_write_close()
в основном записывает и закрывает сеанс.2. @Jack Я прочитал это, влияет ли это на сеанс пользователя при
session_start
повторном вызове? И влияет ли это на запрос?3. Ваши пользователи не прерывают запрос. Если они закроют браузер или перейдут куда-нибудь еще, или просто нажмут клавишу escape, это повлияет только на клиента. Сервер ничего об этом не знает. Как только серверный код завершает выполнение, он возвращает html клиенту, который его запросил. Клиент может больше не ждать этого html, но на самом деле ничего не ломается.
4. @DanBracuk На самом деле сервер может определить, не может ли он написать ответ любого типа. php.net/connection_aborted
Ответ №1:
Хранилище сеансов PHP по умолчанию — это просто файл на жестком диске. Т.Е. Содержимое $_SESSION
просто сбрасывается в файл на диске. При вызове session_start
этот файл считывается и $_SESSION
заполняется, когда скрипт завершается, $_SESSION
записывается обратно на диск.
Здесь легко попасть в классическое состояние гонки. Если два запроса поступают параллельно, и два независимых скрипта считывают из файла, а затем через некоторое время два скрипта записывают обратно в файл… какой из них выигрывает? Каким будет содержимое файла, и, возможно, какие-то данные были перезаписаны?
Решением этой проблемы является блокировка файлов. PHP получает блокировку файла сеанса, не позволяя никому другому читать или записывать в него, пока блокировка не будет снята. Если два параллельных скрипта одновременно пытаются получить блокировку, одному из них приходится ждать, пока другой не завершит работу. Это то, что вы видите.
session_write_close
явно записывает $_SESSION
содержимое на диск и снимает блокировку.
Комментарии:
1. Спасибо, дал вам преимущество. Джек был немного раньше с четким объяснением.
2. Могу ли я, однако, получить доступ к переменным сеанса после вызова session_write_close?
3. Я не уверен,
$_SESSION
очищается или нет при вызове функции, в руководстве об этом ничего не говорится. Попробуйте. Вы должны быть очень осторожны, чтобы читать только из него, а не записывать в него, пока сеанс закрыт. В противном случае вы можете потерять записанные данные.
Ответ №2:
Я надеюсь, что приведенный ниже график помогает понять, что происходит; мы говорим о сеансе для одного и того же пользователя (т. Е. С тем же идентификатором сеанса):
script a | lock | script b
--------------------- ------ -----------------
start
open session <- | yes | start
do stuff
close session -> | yes | -> open session
do heavy queries | | do stuff
open session <- | yes | <- script ended
script ended -> | no |
Закрытие сеанса, когда вы не собираетесь его использовать, будь то на некоторое время или до завершения скрипта, делает его доступным для другого скрипта.
Обратите внимание, что после запуска другого скрипта данные сеанса могли быть изменены.
Комментарии:
1. Могу ли я, однако, получить доступ к переменным сеанса после вызова session_write_close?
2.Обновленные переменные сеанса становятся доступными только после
session_start
.