Я использую CURL для загрузки большого файла с внешнего URL-адреса и сохранения его на моем сервере. Это может занять до нескольких минут. Во время загрузки я использую curl_setopt ($ ch, CURLOPT_PROGRESSFUNCTION, .. для запуска анонимной функции, которая периодически обновляет переменную $ _SESSION ['download_progress'] с текущей информацией о загрузке.
Теперь все это происходит в файле upload.php, и пока пользователь ждет загрузки файла, я использую javascript для запроса страницы progress.php, которая содержит следующий простой код:
session_start(); echo $_SESSION['download_progress'];
Это позволяет моему javascript-коду отображать информацию о ходе загрузки.
Кроме того, что он не работает.
Страница «progress.php» не будет загружаться до завершения загрузки «upload.php» (другими словами, обе страницы загружаются только после завершения загрузки файла), и это не хорошо. Session_start () каким-то образом блокирует загрузку страницы «progress.php». Я использую свой собственный сервер (apache + php 5.4), поэтому у меня есть все права администратора.
Как я могу решить эту проблему? Я мог бы использовать некоторое уродливое обходное решение, например, записывать информацию загрузки в файл txt вместо переменной сеанса, а затем использовать javascript для прямого чтения этого txt-файла, но я бы этого не хотел.
благодаря
У вас есть классическая проблема с сессиями, поддерживаемыми файловой системой. Ваш сценарий загрузки блокирует файл поддержки сеанса в течение его продолжительности, поэтому невозможно получить доступ к информации о сеансе до тех пор, пока он не освободит блокировку.
Здесь есть несколько возможных решений, но самым простым было бы для вашего сценария загрузки периодически выпускать сеанс и снова блокировать его; это оставило бы возможность для вашего скрипта прогресса читать сеанс тем временем.
Чтобы освободить блокировку сеанса, вызовите session_write_close
в любой момент из сценария загрузки. Это оставляет вас без доступа к переменным сеанса, пока вы снова не вызове session_start
. Вы можете повторить этот цикл столько, сколько хотите.
Существуют и другие, более эффективные решения. Например, вы можете перенести информацию о ходе работы в какой-либо механизм хранения, который не остается заблокированным в течение всего срока действия скрипта; вы можете идентифицировать информацию каждого пользователя на основе своего идентификатора сеанса (вам не нужно начинать сеанс, чтобы получить его идентификатор, если он существует).