Обработка сеанса PHP, когда один и тот же клиент запрашивает один и тот же скрипт несколько раз одновременно

Итак, вот моя тестовая установка:

session_start();
if(!isset($_SESSION['bahhhh']))
    $_SESSION['bahhhh'] = 0;
$_SESSION['bahhhh']++;
sleep(5);
die('a'.$_SESSION['bahhhh']);

Я ожидаю, что каждый раз, когда я нажимаю на страницу, она возвращает другое число.

Но если я использую несколько вкладок и обновляю их каждую в течение 5 секунд после первой, все они возвращают одно и то же число. (Это не кэширование на стороне клиента, так как 5-секундная задержка все еще очевидна.)

Почему это происходит и как это исправить?

Похоже, у него такая же странная проблема с кэшированием файлов и данных базы данных, и это мешает мне создать работающий мьютекс, чтобы предотвратить запуск одного и того же кода более одного раза за раз.

Вот еще один, более простой пример:

echo microtime();
sleep(10);

Запустите это 3 раза, каждые 2 секунды, и все три вернут одну и ту же микросекунду. ВТФ?


person VexedPanda    schedule 01.03.2010    source источник


Ответы (3)


Данные сеанса по умолчанию не сохраняются до завершения запроса. Таким образом, ваш прирост не сохраняется во время сна. Если вы хотите досрочно сохранить сеанс, проверьте session_write_close().

person Mike B    schedule 01.03.2010
comment
Как я уже сказал, для этого подхода я также использовал серверные части файлов и баз данных. Вот еще один тестовый скрипт, который не работает должным образом: echo microtime(); сон (10); Если вы откроете это на нескольких вкладках, а затем обновите каждую в течение 10 секунд друг от друга, любая вкладка будет утверждать, что она была вызвана в одну и ту же микросекунду (явная невозможность). - person VexedPanda; 02.03.2010
comment
Я не понимаю, какой носитель информации делать с вашей проблемой. Я протестировал ваш скрипт на 5 вкладках, обновляя каждую в течение 10 секунд друг от друга и каждый раз получая разные результаты. Протестировано с последней версией 5.2.x на Ubuntu 9.10. - person Mike B; 02.03.2010

Я бы попросил сам скрипт добавить что-то в файл журнала, чтобы убедиться, что скрипт действительно выполняется столько раз, сколько вы думаете. Возможно, у вас есть какое-то программное обеспечение, которое перехватывает запрос и возвращает кешированный ответ.

Если бы не ваш комментарий, что это также происходит с microtime(), я бы дал объяснение, как php управляет параллелизмом с сессиями, а когда это может быть не так.

person goat    schedule 02.03.2010
comment
Сложность записи в файл заключается в том, что, поскольку такие вещи, как microtime(), возвращают один и тот же результат для всех экземпляров, я не смог бы различить все три записи в файл (поскольку в конечном итоге это будет одно и то же имя файла) , или только один. Тем не менее, ошибка, с которой мы сталкиваемся в производственной среде, заключается в том, что сценарий обслуживания запускается более одного раза и сталкивается с условиями гонки с самим собой, поэтому я уверен, что все три копии действительно выполняются. Вот почему мы пытаемся построить мьютекс. - person VexedPanda; 02.03.2010

Видимо это какая-то ошибка в самом браузере. Opera ведет себя так, а Internet Explorer — нет. Я провел первоначальное тестирование в IE с теми же результатами, но с более сложным кодом. По-видимому, в этом сложном коде была ошибка, вызвавшая неправильное поведение в IE, а в этом упрощенном коде — нет. Извините, что беспокою всех.

person VexedPanda    schedule 02.03.2010