Web アプリケーションでは、多くの場合、ファイル アップロード機能を提供する必要があります。一般的なシナリオには、ユーザー アバターのアップロード、アルバム写真のアップロードなどが含まれます。アップロードするファイルが比較的大きい場合は、アップロードの進行状況を示すプログレスバーを提供する必要があります。
PHP 5.4 より前では、このような進行状況バーを実装するのは簡単ではありませんでした。主に 3 つの方法がありました:
Flash、Java、ActiveX
## を使用する2 番目の方法の欠点は、PHP の APC 拡張ライブラリのインストールが必要であり、ユーザーがサーバー側の構成を制御する必要があることです。さらに、アップロードの進行状況バーを実装するためだけに APC がインストールされている場合、それは明らかにやりすぎです。
3 番目の方法は、サーバー側のサポートを必要とせず、ブラウザ側の Javascript のみを使用する最も理想的な方法です。しかし、HTML5の標準規格がまだ確立されておらず、ブラウザメーカーごとにサポート状況が異なるため、この方法はまだ普及が難しいです。
PHP 5.4 で導入されたセッションベースのアップロード進行状況監視関数 (session.upload_progress) は、サーバー側のアップロード進行状況監視ソリューションを提供します。 PHP 5.4 にアップグレードした後は、APC 拡張機能をインストールする必要はなく、ネイティブ PHP とフロントエンド Javascript のみを使用してアップロード進行状況バーを実装できます。
PHP 5.4 の session.upload_progress 新機能を詳しく紹介しましょう。
原理の紹介ブラウザがファイルをサーバーにアップロードすると、PHP はファイルの詳細情報 (アップロード時間、アップロードの進行状況など) をアップロードします。 ) はセッションに保存されます。その後、アップロードが進行するにつれて、セッション内の情報が定期的に更新されます。このようにして、ブラウザは Ajax を使用してサーバー側のスクリプトを定期的にリクエストし、スクリプトはセッションの進行状況情報を返します。ブラウザ側の Javascript はこの情報に基づいて進行状況バーを表示/更新できます。 それでは、ファイルのアップロード情報はどのように保存されるのでしょうか?どうやってアクセスするのでしょうか?以下で詳しく説明しましょう。
PHP 5.4 では、いくつかの設定項目 (php.ini で設定) が導入されました。
コードは次のとおりです。
session.upload_progress.enabled = "1" session.upload_progress.cleanup = "1" session.upload_progress.prefix = "upload_progress_" session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS" session.upload_progress.freq = "1%" session.upload_progress.min_freq = "1"
enabled は、upload_progress 関数をオンにするかどうかを制御します。デフォルトの「有効」。クリーンアップは、ファイルのアップロード要求が送信された後にセッション関連の情報をクリアするかどうかを設定します。これはデフォルトで有効になっています。
プレフィックスと名前は、セッションに保存される進行状況情報の変数名/キー名を設定するために使用されます。これら 2 つのアイテムの詳細な使用方法については、以下を参照してください。
freq と min_freq は、サーバー側で進捗情報を更新する頻度を設定するために使用されます。これら 2 つの項目を適切に設定すると、サーバーの負荷を軽減できます。
ファイルをアップロードするためのフォームでは、このアップロードの識別子を設定し、この識別子を使用して後続のプロセスで進行状況情報を参照する必要があります。具体的には、アップロード フォームに非表示の入力が必要で、その name 属性は php.ini の session.upload_progress.name の値であり、その値は自分で定義した識別子です。次のように:
コードは次のとおりです:
<input type="hidden" name="<?php echo ini_get('session.upload_progress.name'); ?>" value="test" />
ファイル アップロード フォームを受信した後、PHP は $_SESSION 変数に新しいキーを作成します。キー名はセッションの値です。 Upload_progress.prefix と上記 カスタム識別子を連結した後に得られる文字列は次のように取得できます:
コードは次のとおりです:
$name = ini_get('session.upload_progress.name'); $key = ini_get('session.upload_progress.prefix') . $_POST[$name]; $_SESSION[$key]; // 这里就是此次文件上传的进度信息了
この変数の構造は次のようになります:
コードは次のとおりです:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">$_SESSION["upload_progress_test"] = array(
"start_time" => 1234567890, // 开始时间
"content_length" => 57343257, // POST请求的总数据长度
"bytes_processed" => 453489, // 已收到的数据长度
"done" => false, // 请求是否完成 true表示完成,false未完成
// 单个文件的信息
"files" => array(
0 => array( ... ),
// 同一请求中可包含多个文件
1 => array( ... ),
)
);</pre><div class="contentsignin">ログイン後にコピー</div></div>
このようにして、content_length と bytes_processed の 2 つの項目を使用して、進行状況のパーセンテージを取得できます。
原則を紹介したので、PHP と Javascript に基づいてファイル アップロードの進行状況バーを完全に実装してみましょう。
アップロード フォームまず、アップロード フォーム ページのindex.phpを作成します。コードは次のとおりです。
コードは次のとおりです。次のとおりです:<form id="upload-form" action="upload.php" method="POST" enctype="multipart/form-data" style="margin:15px 0" target="hidden_iframe"> <input type="hidden" name="" value="test" /> <p><input type="file" name="file1" /></p> <p><input type="submit" value="Upload" /></p> </form> <iframe id="hidden_iframe" name="hidden_iframe" src="about:blank" style="display:none;"></iframe> <p id="progress" class="progress" style="margin-bottom:15px;display:none;"> <p class="bar" style="width:0%;"></p> <p class="label">0%</p> </p>
フォームの target 属性に特別な注意を払う必要があります。ここでの設定は、現在のページの iframe を指しています。これは重要で、target 属性を設定することで、フォーム送信後のページが iframe 内に表示され、現在のページへのジャンプを回避できます。現在のページに進行状況バーを表示する必要があるためです。
#progressこの p は、進行状況バーを表示するために使用されます。
注: session_start() をindex.php の先頭に追加することを忘れないでください。
フォームのアクションは、upload.php をポイントしており、upload.php でアップロードされたファイルを処理し、現在のディレクトリに転送します。ここでは通常のアップロード処理と変わりません。
代码如下:
if(is_uploaded_file($_FILES['file1']['tmp_name'])){ move_uploaded_file($_FILES['file1']['tmp_name'], "./{$_FILES['file1']['name']}"); } ?>
Ajax获取进度信息
这一步是关键,我们需要建立一个 progress.php 文件,用来读取session中的进度信息; 然后我们在 index.php 中增加Javascript代码,向 progress.php 发起Ajax请求,然后根据获得的进度信息更新进度条。
progress.php 的代码如下:
代码如下:
session_start(); $i = ini_get('session.upload_progress.name'); $key = ini_get("session.upload_progress.prefix") . $_GET[$i]; if (!empty($_SESSION[$key])) { $current = $_SESSION[$key]["bytes_processed"]; $total = $_SESSION[$key]["content_length"]; echo $current < $total ? ceil($current / $total * 100) : 100; }else{ echo 100; } ?>
在这里我们获得$_SESSION变量中的进度信息,然后输出一个进度百分比。
在 index.php 中,我们将如下代码添加到页面底部 (为简便,这里使用jQuery):
代码如下:
function fetch_progress(){ $.get('progress.php',{ '' : 'test'}, function(data){ var progress = parseInt(data); $('#progress .label').html(progress + '%'); $('#progress .bar').css('width', progress + '%'); if(progress < 100){ setTimeout('fetch_progress()', 100); }else{ $('#progress .label').html('完成!'); } }, 'html'); } $('#upload-form').submit(function(){ $('#progress').show(); setTimeout('fetch_progress()', 100); });
当#upload-form被提交时,我们把进度条显示出来,然后反复调用 fetch_progress() 获得进度信息,并更新进度条,直到文件上传完毕,显示'完成!'。
注意事项
input标签的位置
name为session.upload_progress.name的input标签一定要放在文件input 的前面。
取消上传
通过设置 $_SESSION[$key]['cancel_upload'] = true 可取消当次上传。但仅能取消正在上传的文件和尚未开始的文件。已经上传成功的文件不会被删除。
setTimeout vs. setInterval
应该通过 setTimeout() 来调用 fetch_progress(),这样可以确保一次请求返回之后才开始下一次请求。如果使用 setInterval() 则不能保证这一点,有可能导致进度条出现'不进反退'。
以上がセッションと Javascript を使用して、PHP でファイル アップロードの進行状況バー機能を実装する方法を学びます。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。