投稿

jQuery:Uploadify

jquery

PHPで複数ファイルのアップロードをなるべくスマートにやる方法はないかなぁと探し回ってたどり着いたのが、コレ。
自分的にはベストな解答です、たぶん。
 
詳しい使い方は「Ajax風にファイルをアップロードするjQueryプラグイン「Uploadify」の使い方」が超詳しいので、こちらを参照のこと。
 
以下は自分的にポイントとなったところ。

  1. 既存のPHPシステム(例えば、EC-CUBEなど)とはできるだけ独立した形にしたかったので、少し工夫した。
  2. 呼出し部分は小さいので、display:none で本体のHTMLに組み込む。例えば、こんな感じ。
    [code]

    $(document).ready(function() {
    $(“#uploadify”).uploadify({
    ‘uploader’ : ‘js/uploadify/uploadify.swf’,
    ‘script’ : ‘js/uploadify/uploadify.php?rand_no=‘,
    ‘cancelImg’ : ‘js/uploadify/cancel.png’,
    ‘folder’ : ‘‘,
    ‘queueID’ : ‘fileQueue’,
    ‘auto’ : false,
    ‘buttonText’ : ‘Select Files…’,
    ‘multi’ : true
    });
    });

    画像ファイルを選択して、Uploadしてください。

    Upload Files Cancel All Uploads

    [/code]
    ちょっと見慣れない細工コードが入っているのは無視無視。たったこれだけでアップローダ定義完了。

  3. 特殊なことをしている点は、複数の人が同時にこのアップローダを使った場合、同じテンポラリ・フォルダを使うことになるので、ファイル管理用のランダム文字列を持たせたこと。(ほんとは rand()だとかぶる危険性もあるんだけど、今回は管理画面からのアップロードということで、せいぜい10人未満の同時使用しかないだろうから、そこには目を瞑った)
  4. それと、#uploadブロックは通常非表示で、Thickboxのモーダル・ウィンドウで上がってくるようにしている。
    [code]
    Uploadify
    [/code]
    こうすると本体のHTMLを汚さなくて済むからいいよね。で、Close Windowのとき、fnModeSubmit()といういままでアップロードボタンに割りつけていた関数を呼んでフックをかけると。
  5. サーバ側もいたってシンプル。
    [code]
    if (!empty($_FILES)) {
    $tempFile = $_FILES[‘Filedata’][‘tmp_name’];
    $targetPath = str_replace(‘//’,’/’, $_SERVER[‘DOCUMENT_ROOT’] . $_REQUEST[‘folder’] . ‘/’);
    $targetFile = $targetPath . $_FILES[‘Filedata’][‘name’];
    move_uploaded_file($tempFile,$targetFile);

    $_FILES[‘Filedata’][‘tmp_name’] = $targetFile;
    $fp = fopen($targetPath.$_REQUEST[‘rand_no’], “a”);
    fputs($fp, serialize($_FILES[‘Filedata’]).”\n”);
    fclose($fp);
    echo “1”;
    }
    [/code]
    複数ファイルをまとめてアップロードすると、この PHPが回数分呼ばれることになる。
    やってることは、渡されたファイルをフォルダに移して、なんのファイルを移したかファイルに記録しておくだけ。
    このときのファイル名に例のランダム文字列を使ってる。

  6. あとは、この $_FILES がシリアライズされたファイルを読んで、あたかも $_FILESで入ってきたように振舞ってやれば OK。
    [code]
    $no = 0;
    $buf = @file(IMAGE_TEMP_DIR . $this->rndNo);
    if ($buf) {
    foreach ($buf as $e) {
    $no++;
    $key = “sub_image”.$no;
    $_FILES[$key] = unserialize($e);
    $this->arrErr[$key] = $this->objUpFile->makeTempFile($key, IMAGE_RENAME);
    }
    @unlink(IMAGE_TEMP_DIR . $this->rndNo);
    unset($_POST[‘rand_no’]);
    unset($this->rndNo);
    }
    [/code]
    EC-CUBEのコードにがっつり入り込んでいるのでわかりにくいけど、シリアライズされたファイルを読んで、アンシリアライズしたものを $_FILESにセットして、処理を継続しているだけ。終わったら、後始末しておく。

こんな感じで活用させていただいてます。ありがとう、Uploadify