18

次のようなphp.iniの一連の変更の後、upload_progressセッションを機能させようとしています:

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>

次に、ファイルを適切にアップロードするサーバー側スクリプト:

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

4

5 に答える 5

5

PHP のセッションを介したアップロードの進行状況はかなりトリッキーであり、すべてのコンテキストと状況が十分に文書化されているわけではありません。似たような質問の は、それが トラブルを引き起こすことを示しています。私は個人的にこれで1日以上を失ったので、ここにあなたを助けるための私のアドバイスがあります.

  1. 明らかな必須要件: PHP バージョン >= 5.4.0、および PHPが FastCGI として実行されていないこと。調べ方
  2. デバッグを改善するには、セッション プロパティの即時クリーニングを無効にしますphp.ini
    session.upload_progress.cleanup = オフ
    このようにして、アップロードが完了したにセッションの内容を確認できます。
  3. セッションが保存されている場所 ( の変数session.save_pathphp.iniLinux マシンでの一般的な値は) を見つけて検査し、アップロードの開始後に/var/lib/php/sessions名前が付けられたインデックスを探します。upload_progress_xxxxxxxxxxx

  4. 特定のアップロード進行状況の追跡を有効にするには、通常、非表示の 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>
    
  5. AJAX 送信は慎重に。可能性は低いですが、一部の JS ライブラリはHTTP リクエスト内の要素の順序を変更する場合があります。ブラウザーで開発者ツールを使用して実際の HTTP 通信を確認し、送信される要素の順序が前のポイントに従っていることを確認する必要があります。

  6. セッション名。コードで任意のセッション名を使用できますが、PHP はそれを認識せず、アップロードの進行状況を常にデフォルトの sessionに書き込みPHPSESSIDます (実際の値を確認するには、php.iniのプロパティを参照してください)。この動作はバグではありません。 2 つのセッションが作成されていることに問題がある場合は、デフォルト値を使用するようにコードを変更するか、常に可能であるとは限らないデフォルト値 (共有ホスティングなど) を変更する必要があります。で値を変更することもできます。session.name
    session.name.htaccess

  7. 一部の PHP フレームワーク (Zend、Cake PHP) には独自のセッション コンテンツの構造があり、PHP エンジンは、アップロードの進行状況をセッションに書き込むときにセッションを破損します。保存された情報の損失を引き起こし、サインアウト、追跡への損害などの影響を与えます。問題問題問題。その場合、2 つの異なるセッションを使用する必要があるという結論に達しました。

私の最終的な解決策

私は Zend Framework を使用していますが、最終的に 2 つの別々のセッションになりました。次の単純な PHP スクリプトを使用して、特定のファイルのアップロードの進行状況を報告します。スクリプトは 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.phponBootstrap()メソッドで独自のセッション名前空間を設定します。

$sessionManager = new \Zend\Session\SessionManager();
$sessionManager->setName('myFancyNamespace');
$sessionManager->start();
于 2016-12-09T11:30:42.373 に答える
1

アップロードの進行状況は $_SESSION 配列で確認できるため、別の php リクエストで進行状況を確認できます。

$_SESSION は、ファイルがアップロードされた後ではなく、ファイルがアップロードされるまで利用可能です。したがって、ファイルを処理すると、それはなくなります。ファイルのアップロード中に別のリクエストでこれを print_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 5.4 での PhP アップロードの進行状況が機能しません。セッション変数が設定されていません

于 2016-02-23T07:37:24.913 に答える
0

スクリプトが呼び出している時点move_uploaded_file()とそれに続くprint_r()で、アップロードは既に完了しています。

アップロードの進行状況にアクセスするには、

  • アップロードされたフォームを別のブラウザー ウィンドウに送信する (現在のページの JS を引き続き実行できるようにする) またはフレーム (targetフォームの属性を使用する)
  • ajax 呼び出しを使用してサーバーを繰り返しポーリングし、現在のセッションのアップロードの進行状況を照会します。

http://php.net/manual/en/session.upload-progress.phpの説明は、同じリクエスト内のデータではなく、同じセッションへの異なるリクエストについて言及しています。

ちょっとしたグーグル検索でhttp://www.sitepoint.com/tracking-upload-progress-with-php-and-javascript/が見つかりました。これはより詳細に説明し、コピー & ペースト可能な例を提供しています。

于 2015-09-10T15:43:18.280 に答える