APC と jQuery を利用してファイルアップロードの進行状況を表示する
2008-04-13-2: [PHP][jQuery][JavaScript]
ネタ的には特別新しいものではないですが、気になっていたので試してみました。
PHP 5.2.0 以降、APC 3.0.13 が必要です。
1. APC の設定
普通に APC をインストールして、以下のように apc.rfc1867 を有効にするだけです。
apc.rfc1867 = On
2. アップロードフォームの準備
普通のアップロードフォームです。
ただし、"APC_UPLOAD_PROGRESS" という name 属性を持った hidden フィールドを用意します。値は、何でもいいのですが、ここでは "progress_key" という風にしています (本当はランダムにするほうがいいと思います)。
<form id="upload" action="upload.php" method="post" enctype="multipart/form-data">
<p>
<input type="hidden" name="APC_UPLOAD_PROGRESS" value="progress_key" />
<input type="file" name="file" />
<input id="submit_button" type="submit" value="アップロード" />
</p>
</form>
3. アップロードファイルの処理
上記アップロードフォームの upload.php ですが、これは通常のファイルアップロード時の処理を書いてください。
今回はテストなので何もしませ
<?php
// 通常のファイルアップロードの処理
?>
4. アップロードの進行状況を返す処理
次のファイルを progress.php とします。
<?php
// progress.php
header('Content-type: application/json; charset=UTF-8');
$status = apc_fetch('upload_progress_key');
echo json_encode($status);
exit;
?>
2 で指定した "APC_UPLOAD_PROGRESS" の値の先頭に upload_ をつけたものを apc_fetch() の引数に指定します。upload_ は設定で変更することが出来ます (apc.rfc1867_prefix)。
apc_fetch() で取得できる値は次のようになります。
total | アップロードされるファイルのサイズ | |
current | 現時点までに受信したファイルのサイズ | |
rate | アップロード速度 (byte/second) | アップロード完了時のみ |
filename | ファイル名 | |
name | <input type="file" /> の name 属性 | |
temp_filename | 一時ファイル名 | アップロード完了時のみ |
cancel_upload | アップロードがキャンセルされたかどうか | アップロード完了時のみ |
done | アップロードが完了したかどうか | |
start_time | アップロード開始日時の UNIX TIME |
- cancel_upload: 0 = キャンセルされていない、1 = キャンセルされた
- done: 0 = 未完了、1 = 完了
これらの値を JSON で出力しています。
5. jQuery を使って進行状況を取得する
jQuery Form Plugin を使って、フォームを POST し、1 秒毎に getJSON で進行状況を取得します。
また、getJSON でリクエストに現在日時を渡しているのは、ブラウザのキャッシュを利用しないようにするためです。
var timer = null;
var progress = function() {
// progress.php を呼び出して進行状況を取得する
$.getJSON('progress.php', { 'd': new Date().getTime() }, function(json) {
// 進行状況を % で表示する
$('#status').html(parseInt(json.current / json.total * 100) + '%');
});
};
$(function() {
$('#upload').submit(function() {
timer = setInterval('progress()', 1000);
// フォームを POST する
$(this).ajaxSubmit(function() {
clearInterval(timer);
progress();
});
return false;
});
});
6. デモ
本当は、デモを用意したかったのですが、ここのレンタルサーバでは APC が使えないようでしたのでアップロード状況をキャプッチャしました。
基本的には、上記の処理を行なっているだけですが、進行状況の表示の部分は Progress Bar Plugin を利用して、プログレスバーで表示しています。
このデモで使用したファイル一式を以下に置いておきます。
参考
- PHP V5.2 の新機能、第 5 回: ファイル・アップロードの進行状況を追跡する方法
http://www.ibm.com/developerworks/jp/opensource/library/os-php-v525/
- upload meter for PHP with APC and Json
http://progphp.com/progress.phps
- PHP: APC 関数 - Manual
http://php.net/apc
- jQuery Form Plugin
http://malsup.com/jquery/form/
- Progress Bar Plugin
http://digitalbush.com/projects/progress-bar-plugin