Programmer's Reference Guide

Zend_File

Zend_File_Transfer

Zend_File_Transfer を使用すると、 ファイルのアップロードやダウンロードを管理することができます。 組み込みのバリデータを使ってファイルを検証したり、 フィルタによってファイルを変更したりという機能があります。 Zend_File_Transfer はアダプタ形式を採用しており、 HTTP や FTP、WEBDAV などのさまざまな転送プロトコルを同じ API で使用することができます。

注意: 制限
現在の Zend_File_Transfer の実装では、HTTP Post によるアップロードにしか対応していません。 ファイルのダウンロードやその他のアダプタについては次のリリースで追加される予定です。 実装されていないメソッドを実行すると例外をスローします。 したがって、実際のところは Zend_File_Transfer_Adapter_Http のインスタンスを直接操作することになります。 これは、将来複数のアダプタが使用可能になった段階で変更される予定です。

注意: フォーム
Zend_Form を使う場合は Zend_Form の API を使うようにし、Zend_File_Transfer を直接使わないようにしましょう。Zend_Form のファイル転送機能は Zend_File_Transfer で実装されているので、この章の説明は Zend_Form のユーザにも有用です。

Zend_File_Transfer の使い方はきわめて単純です。 ふたつの部分から成り立っており、 アップロードを行う HTTP フォームとアップロードされたファイルを Zend_File_Transfer で処理するコードを作成します。 次の例を参照ください。

例1 シンプルなファイルアップロードフォーム

これは、基本的なファイルアップロード処理の例です。 まずはファイルアップロードフォームから。 今回の例では。アップロードしたいファイルはひとつです。

<form enctype="multipart/form-data" action="/file/upload" method="POST">
    <input type="hidden" name="MAX_FILE_SIZE" value="100000" />
        アップロードするファイルを選択: <input name="uploadedfile" type="file" />
    <br />
    <input type="submit" value="アップロード" />
</form>

HTML を直接作成するのではなく、利便性を考慮して Zend_Form_Element_File を使っていることに注意しましょう。

次はアップロードしたファイルを受け取る側です。 今回の例では、受け取る側は /file/upload となります。そこで、file コントローラにアクション upload を作成します。

$adapter = new Zend_File_Transfer_Adapter_Http();

$adapter->setDestination('C:\temp');

if (!$adapter->receive()) {
    $messages = $adapter->getMessages();
    echo implode("\n", $messages);
}

        

このコードは Zend_File_Transfer のもっともシンプルな使用法を示すものです。 ローカルの保存先を setDestination メソッドで指定して receive() メソッドをコールします。 アップロード時に何らかのエラーが発生した場合は、 返された例外の中でその情報を取得することができます。

注意: 注意
この例は、Zend_File_Transfer の基本的な API を説明するためだけのものです。 これをそのまま実際の環境で使用しては いけません。 深刻なセキュリティ問題を引き起こしてしまいます。 常にバリデータを使用してセキュリティを向上させるようにしなければなりません。

Zend_File_Transfer がサポートするアダプタ

Zend_File_Transfer は、 さまざまなアダプタと転送方向をサポートするように作られています。 ファイルのアップロードやダウンロードだけでなく、転送 (あるアダプタでのアップロードと別のアダプタでのダウンロードを同時に行う) にも対応できるように設計されています。 しかし、Zend Framework 1.6 の時点で存在するアダプタは Http アダプタひとつだけです。

Zend_File_Transfer のオプション

Zend_File_Transfer やそのアダプタはさまざまなオプションをサポートしています。 オプションはコンストラクタで指定することもできますし、 setOptions($options) で指定することもできます。 getOptions() は、実際に設定されているオプションを返します。 サポートするオプションは次のとおりです。

  • ignoreNoFile: このオプションを true にすると、 ファイルがフォームからアップロードされなかったときにバリデータは何も行いません。 このオプションのデフォルトは false で、 この場合はファイルがアップロードされなければエラーとなります。

ファイルのチェック

Zend_File_Transfer のメソッドの中には、さまざまな前提条件をチェックするためのものもあります。 これらは、アップロードされたファイルを処理する際に便利です。

  • isValid($files = null): このメソッドは、 ファイルにアタッチされたバリデータを用いてそのファイルが妥当なものかどうかを検証します。 ファイル名を省略した場合はすべてのファイルをチェックします。 isValid()receive() の前にコールすることもできます。 この場合、receive() がファイルを受信する際に内部的に isValid をコールすることはありません。

  • isUploaded($files = null): このメソッドは、 指定したファイルがユーザによってアップロードされたものなのかどうかを調べます。 これは、複数のファイルを任意でアップロードできるようにする場合などに便利です。 ファイル名を省略した場合はすべてのファイルをチェックします。

  • isReceived($files = null): このメソッドは、 指定したファイルがすでに受信済みであるかどうかを調べます。 ファイル名を省略した場合はすべてのファイルをチェックします。

例2 ファイルのチェック

$upload = new Zend_File_Transfer();

// すべての既知の内部ファイル情報を返します
$files = $upload->getFileInfo();

foreach ($files as $file => $info) {
    // アップロードされたファイルか ?
    if (!$upload->isUploaded($file)) {
        print "ファイルをアップロードしてください";
        continue;
    }

    // バリデータを通過したか ?
    if (!$upload->isValid($file)) {
        print "$file は不適切です";
        continue;
    }
}

$upload->receive();

            

さらなるファイル情報

Zend_File_Transfer は、ファイルについてのさらなる情報を返すことができます。 次のメソッドが使用可能です。

  • getFileName($file = null, $path = true): このメソッドは、転送されたファイルの実際のファイル名を返します。

  • getFileInfo($file = null): このメソッドは、転送されたファイルのすべての内部情報を返します。

  • getFileSize($file = null): このメソッドは、指定したaifるの実際のファイルサイズを返します。

  • getHash($hash = 'crc32', $files = null): このメソッドは、転送されたファイルの内容のハッシュを返します。

  • getMimeType($files = null): このメソッドは、転送されたファイルの mimetype を返します。

getFileName() の最初のパラメータには、 要素の名前を渡すことができます。名前を省略した場合は、 すべてのファイル名を配列で返します。 multifile 形式であった場合も結果は配列となります。 ファイルがひとつだけだった場合は結果を文字列で返します。

デフォルトでは、ファイル名はフルパス形式で返されます。 パス抜きのファイル名だけがほしい場合は、2 番目のパラメータ $path を設定します。これを false にするとパスの部分を取り除いた結果を返します。

例3 ファイル名の取得

$upload = new Zend_File_Transfer();
$upload->receive();

// すべてのファイルのファイル名を返します
$names = $upload->getFileName();

// フォームの 'foo' 要素のファイル名を返します。
$names = $upload->getFileName('foo');

            

注意: ファイルを受信する際にファイル名が変わることがあることに注意しましょう。 これは、ファイルを受信した後ですべてのフィルタが適用されるからです。 getFileName() をコールするのは、ファイルを受信してからでなければなりません。

getFileSize() は、デフォルトではファイルサイズを SI 記法で返します。 つまり、たとえば 2048 ではなく 2kB のようになるということです。単にサイズだけが知りたい場合は、オプション useByteString を false に設定してください。

例4 ファイルのサイズの取得

$upload = new Zend_File_Transfer();
$upload->receive();

// 複数のファイルがアップロードされた場合は、すべてのファイルのサイズを配列で返します
$size = $upload->getFileSize();

// SI 記法を無効にし、数値のみを返すようにします
$upload->setOption(array('useByteString' => false));
$size = $upload->getFileSize();

            

getHash() の最初のパラメータには、ハッシュアルゴリズムの名前を指定します。 使用できるアルゴリズムについては » PHP の hash_algos メソッド を参照ください。アルゴリズムを省略した場合は crc32 をデフォルトのアルゴリズムとして使用します。

例5 ファイルのハッシュの取得

$upload = new Zend_File_Transfer();
$upload->receive();

// 複数のファイルがアップロードされた場合は、すべてのファイルのハッシュを配列で返します
$hash = $upload->getHash('md5');

// フォームの 'foo' 要素のハッシュを返します。
$names = $upload->getHash('crc32', 'foo');

            

注意: 複数のファイルを指定した場合は、返される結果が配列となることに注意しましょう。

getMimeType() はファイルの mimetype を返します。 複数のファイルがアップロードされた場合は配列、そうでない場合は文字列を返します。

例6 ファイルの mimetype の取得

$upload = new Zend_File_Transfer();
$upload->receive();

$mime = $upload->getMimeType();

// フォーム要素 'foo' の mimetype を返します
$names = $upload->getMimeType('foo');

            

注意: このメソッドは、fileinfo 拡張モジュールが使用可能な場合はそれを使用することに注意しましょう。 この拡張モジュールがみつからなかった場合は、mimemagic 拡張モジュールを使用します。 それもみつからなかった場合は、ファイルがアップロードされた際にファイルサーバから渡された mimetype を使用します。

ファイルアップロードの進捗

Zend_File_Transfer では、ファイルアップロードの進捗状況を知ることができます。 この機能を使用するには、APC 拡張モジュール (ほとんどの PHP 環境においてデフォルトで提供されています) あるいは uploadprogress 拡張モジュールが必要です。 これらの拡張モジュールがインストールされていれば、自動検出してそれを使用します。 進捗状況を取得するには、いくつかの事前条件があります。

まず、APC あるいは uploadprogress のいずれかを有効にする必要があります。APC の機能は php.ini で無効化できることに注意しましょう。

次に、ファイルを送信するフォームの中に適切な hidden フィールドを追加しなければなりません。Zend_Form_Element_File を使う場合は、この hidden フィールドは Zend_Form が自動的に追加します。

これらふたつの条件さえ満たせば、ファイルアップロードの進捗状況を getProgress メソッドで取得することができます。

例7 ファイルアップロードの実際の進捗の取得

フォームの作成を終えてデータを投稿し、 まさに今ファイルのアップロードが進行中であるとしましょう。

$upload = Zend_File_Transfer_Adapter_Http::getProgress();

$upload = null;
while (empty($upload['message'])) {
    $upload = Zend_File_Transfer_Adapter_Http:getProgress($upload);
    // 返されたデータを使って何らかの処理をします
}

            

使用している拡張モジュールによって、返されるデータの詳細は異なります。 しかし、どちらの拡張モジュールも、以下のキーを持つ配列形式で情報を返します。

  • total: アップロードされたファイル全体のサイズをバイト単位で表した整数値。

  • current: 現在までにアップロードされたファイルサイズをバイト単位で表した整数値。

  • rate: アップロードの平均速度を「バイト/秒」単位で表した整数値。

  • id: そのアップロード自体への参照。複数のユーザがファイルをアップロードした場合、 それぞれのアップロードごとに個別の ID が設定されます。リクエストごとの ID は、getProgress() を最初にコールしたときに返されます。

  • message: 何か問題が発生したときに有用なメッセージ。 「問題」とは、何もアップロード中でない場合や 進捗状況の取得に失敗した場合、あるいはアップロードがキャンセルされた場合を意味します。

それ以外に返されるキーについては各拡張モジュールが直接返すものであり、 チェックしていません。


Zend_File
blog comments powered by Disqus

Select a Version

Languages Available

Components

Search the Manual