Что делает session_write_close при вызове его перед запросом?

#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 .