読者です 読者をやめる 読者になる 読者になる

ファイルアップロード

PHP Piece

 だいぶ前に実装していて、すっかり忘れていました。


継続ベースのファイルアップロード機能
http://trac.piece-framework.com/piece-unity/ticket/47


 この件、あとはテストコードを完全なものにするだけなので、当てにしていてください!サンプル・アプリケーションも用意してあります。


 いろいろ懸案点、要望があるのですが、ちょっと詳しく書いている時間がないので、とりあえず事務連絡程度に。時間を作ってGoogleグループやTracにもフィードバックします。


 こんな感じでどうでしょうか?
コンストラクタか初期状態で、ファイル管理を行うオブジェクト(Piece_Unity_File_Container)を生成し、アップロード受付時にそのContainerを与えてvalidateする。Containerが、Piece_Rightの返した結果から、Piece_Unity_Fileオブジェクトを作る。ユーザはPiece_Unity_Fileを通して、アップロードされたファイルにアクセスする。」


 ユーザ側のコード例。

require_once 'Piece/Flow/Action.php';
require_once 'Piece/Unity/File/Container.php';

<?php
class PhotoAction extends Piece_Flow_Action {
    function PhotoAction()
    {
        // Piece_Unity_File_Containerはフローが継続している間
        // アップロードされたファイルを管理するオブジェクト
        $this->_container = &new Piece_Unity_File_Container();
    }

    function validate()
    {
        // ValidationはPiece_Rightの
        // Validator_File, Validator_Imageを使って行う。
        $validation = &$this->_payload->getValidation();
        
        if ($validation->validate('Photo', $this->_container)) {
            return 'goDisplayConfirmationFromProcessConfirmForm';
        } else {
            return 'goDisplayFormFromProcessConfirmForm';
        }
    }

    function register()
    {
        // Piece_Unity_File_ContainerからPiece_Unity_File
        // オブジェクトを取得
        $photo = &$this->_container->getFile('photo');

        // ファイル実体を指定の場所に移動
        $file->move('some/dir/filename.jpg');

        // あるいはコピー
        // $file->copy('another/dir/filename.jpg');
    }

    // ... privates methods
}
?>


 実際に使ってみての感想なのですが、

  • フローが正常終了すれば、$file->move()を使っているため、テンポラリにファイルがたまることがないので、ガーベジコレクションを行う必要はそれほど感じない。cronで消せば十分。
  • フロー属性に保存したファイルにアクセスできるような仕組みが必要。例えば、画像アップロードの確認画面で、Pieceの管理下にある画像ファイルを表示するような場合。逆にいうと、そういう仕組みがないと、「継続」ということにあまりメリットを感じない。
  • テンポラリファイルの置き場をどうやって設定するか判断できないでいます。Piece_Unity0.12以降だとConfigurator_Envとかに設定を行うことになるのでしょうか?