Подтвердить что ты не робот

Как сделать работу PHP upload_progress SESSION?

Я пытаюсь сделать сеанс upload_progress после нескольких изменений в php.ini, например:

session.upload_progress.enabled = On

;session.upload_progress.cleanup = On

session.upload_progress.prefix = "upload_progress_"

session.upload_progress.name = "123"

session.upload_progress.freq =  "1%"

session.upload_progress.min_freq = "1"

и созданная и html-страница с формой для отправки файлов:

<form action="upload_progress.php" method="POST" enctype="multipart/form-data">
  <input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="123" />
  <input type="file" name="file1" />
  <input type="file" name="file2" />
  <input type="submit" />
</form>

а затем на стороне сервера script, которая правильно загружает файлы:

session_start();
move_uploaded_file($_FILES['file1']['tmp_name'], './uploads/'.$_FILES['file1']['name']);
move_uploaded_file($_FILES['file2']['tmp_name'], './uploads/'.$_FILES['file2']['name']);
print_r($_SESSION);

В глобальных таблицах $_SESSION имеется пустой массив, хотя загрузка файлов завершена правильно. В чем проблема с настройками сеанса?

Я использую PHP 5.4.5

Notice: Undefined index: upload_progress_123 in C:\apache\localhost\www\upload_progress.php on line 13

4b9b3361

Ответ 1

Загрузка через сеанс в PHP довольно сложная, и не весь контекст и обстоятельства хорошо документированы. Номер аналогичный questions указывает it вызывает проблемы. Я лично потерял больше одного дня, так что вот мой совет, чтобы помочь вам.

  • Очевидное существенное требование: PHP версия >= 5.4.0 и PHP не работает как FastCGI. (Как узнать.)
  • Для лучшей отладки отключите немедленную очистку сеанса сеанса в php.ini
    session.upload_progress.cleanup = Off
    Таким образом вы можете проверить содержимое сеанса после. Загрузка выполнена.
  • Узнайте, где хранится сеанс (переменная session.save_path в php.ini, типичное значение на машинах Linux - /var/lib/php/sessions) и проверяйте их, ищите индекс с именем upload_progress_xxxxxxxxxxx после начала загрузки.

  • Чтобы активировать определенное отслеживание хода загрузки, обычно используется элемент скрытой HTML-формы. Он должен быть отправлен до файла. Если вы думаете об этом, то логично: когда PHP обрабатывает запрос, он должен сначала столкнуться с сигналом, чтобы начать отслеживать ход загрузки файла и после этого распознать сам файл. С другой стороны, это не сработает.

    <form action="upload_progress.php" method="POST" enctype="multipart/form-data">
        <input type="hidden" 
            name="<?php echo ini_get("session.upload_progress.name"); ?>" value="123" />
        <input type="file" name="myfile1" />
        <input type="submit" />
    </form>
    
  • Осторожно с отправкой AJAX. Хотя это маловероятно, некоторые JS-библиотеки могут изменять порядок элементов в HTTP-запросе. Вы должны проверить фактическую связь HTTP с помощью инструментов разработчика в своем браузере и убедиться, что порядок отправленных элементов соответствует предыдущей точке.

  • Имя сеанса. Хотя вы можете использовать любое возможное имя сеанса в своем коде, PHP не знает его и записывает ход выполнения всегда на сеанс по умолчанию, обычно PHPSESSID (обратитесь к свойству php.ini session.name, чтобы проверьте фактическое значение.) Это поведение не является ошибкой.
    Если вы возражаете, что создаются две сессии, вы должны либо изменить свой код на использование значения по умолчанию, либо изменить значение по умолчанию session.name, которое не всегда возможно (например, общий хостинг). Обратите внимание, что значение также можно изменить с помощью .htaccess.

  • Некоторые фреймворки PHP (Zend, Cake PHP) имеют собственную структуру содержимого сеанса, а механизм PHP повреждает сеанс при написании процесса загрузки в сеансе. Причинение потери хранимой информации и, таким образом, эффекты, такие как выходы, повреждения для отслеживания и т.д. Issue, issue, issue. Я пришел к выводу, что в этом случае необходимо использовать 2 разных сеанса.

Мое окончательное решение

Я использую Zend Framework, и я закончил с двумя отдельными сеансами. Я использую следующий простой PHP script, чтобы сообщить о ходе загрузки определенного файла. script полностью изолирован от Zend Framework и использует пространство имен PHPSESSID по умолчанию.

session_start();

if(!isset($_GET['id']))
  die("unsupported");

$id = $_GET['id'];

if(!preg_match('/^[a-zA-Z0-9]{1,32}$/', $id))
  die("unsupported");

$sessionKey = ini_get('session.upload_progress.prefix') . $id;
$uploadInfo = (isset($_SESSION[$sessionKey])) ? $_SESSION[$sessionKey] : null;

$status  = [
    'total'    => 0,
    'current'  => 0,
    'rate'     => 0,
    'message'  => '',
    'done'     => false,
];

if($uploadInfo === null)
{
  header('Content-Type: application/json');
  echo json_encode($status);
  return;
}

$status = $uploadInfo + $status;
$status['total']   = $status['content_length'];
$status['current'] = $status['bytes_processed'];

$time = time() - $status['start_time'];
$status['rate'] = ($time > 0) ? $status['bytes_processed'] / $time : 0;

if (!empty($status['cancel_upload'])) {
    $status['done'] = true;
    $status['message'] = 'The upload has been canceled';
}

header('Content-Type: application/json');
echo json_encode($status);

Приложение, созданное поверх Zend Framework, устанавливает его собственное пространство имен сеанса в методе Module.php onBootstrap():

$sessionManager = new \Zend\Session\SessionManager();
$sessionManager->setName('myFancyNamespace');
$sessionManager->start();

Ответ 2

Прогресс загрузки можно увидеть в $_SESSION Array, поэтому можно проверить прогресс в другом запросе php.

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

как в этом примере

check_progress.php

<?php 
if(isset($_SESSION['upload_progress_123']))){
   print_r($_SESSION['upload_progress_123']);
}
?>

Пример массива

<?php
$_SESSION["upload_progress_123"] = array(
 "start_time" => 1234567890,   // The request time
 "content_length" => 57343257, // POST content length
 "bytes_processed" => 453489,  // Amount of bytes received and processed
 "done" => false,              // true when the POST handler has finished, successfully or not
 "files" => array(
  0 => array(
   "field_name" => "file1",       // Name of the <input/> field
   // The following 3 elements equals those in $_FILES
   "name" => "foo.avi",
   "tmp_name" => "/tmp/phpxxxxxx",
   "error" => 0,
   "done" => true,                // True when the POST handler has finished handling this file
   "start_time" => 1234567890,    // When this file has started to be processed
   "bytes_processed" => 57343250, // Number of bytes received and processed for this file
  ),
  // An other file, not finished uploading, in the same request
  1 => array(
   "field_name" => "file2",
   "name" => "bar.avi",
   "tmp_name" => NULL,
   "error" => 0,
   "done" => false,
   "start_time" => 1234567899,
   "bytes_processed" => 54554,
  ),
 )
);

Полное руководство можно найти здесь, как сказал pilif

http://www.sitepoint.com/tracking-upload-progress-with-php-and-javascript/

http://oliversmith.io/technology/2011/12/04/php-5-4-file-upload-progress-and.html5-progress-bars/

см. также этот ответ. Выполнение PhP Upload в PhP 5.4 не работает. Параметры сеанса не установлены

Ответ 3

В тот момент, когда ваш script вызывает move_uploaded_file() и последовательный print_r(), загрузка уже завершена.

Если вы хотите получить доступ к прогрессу загрузки, вы должны

  • отправить загруженную форму в другое окно браузера (так что JS на текущей странице может продолжаться) или фрейм (используйте атрибут target в форме)
  • используйте вызов ajax, чтобы повторно опросить сервер, чтобы запросить ход текущей загрузки сеанса.

Объяснение http://php.net/manual/en/session.upload-progress.php относится к различным запросам к одному и тому же сеансу, а не к данным внутри одного и того же запроса.

Немного Googling появилось http://www.sitepoint.com/tracking-upload-progress-with-php-and-javascript/, в котором содержится более подробная информация и приведены примеры копирования и примеры.