第19章 Zend_File

目次

19.1. Zend_File_Transfer
19.1.1. Zend_File_Transfer がサポートするアダプタ
19.1.2. Zend_File_Transfer のオプション
19.1.3. ファイルのチェック
19.1.4. さらなるファイル情報
19.2. Zend_File_Transfer 用のバリデータ
19.2.1. Zend_File_Transfer でのバリデータの使用法
19.2.2. Count バリデータ
19.2.3. ExcludeExtension バリデータ
19.2.4. ExcludeMimeType バリデータ
19.2.5. Exists バリデータ
19.2.6. Extension バリデータ
19.2.7. FilesSize バリデータ
19.2.8. ImageSize バリデータ
19.2.9. IsCompressed バリデータ
19.2.10. IsImage バリデータ
19.2.11. MimeType バリデータ
19.2.12. NotExists バリデータ
19.2.13. Size バリデータ
19.3. Filters for Zend_File_Transfer
19.3.1. Using filters with Zend_File_Transfer
19.3.2. LowerCase filter
19.3.3. Rename filter
19.3.4. UpperCase filter
19.4. 以前のバージョンからの移行
19.4.1. 1.6.1 から 1.6.2 以降への移行
19.4.1.1. バリデータを使う際の変更点

19.1. Zend_File_Transfer

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

[注意] 制限

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

[注意] フォーム

Zend_Form を使う場合は、 Zend_Form の章の説明を読んでそこにある例を使うようにしましょう。 Zend_File_Transfer を手動で使用してはいけません。 しかし、たとえ直接使うことがないにしても本章で得られる情報は有用です。 すべての前提、説明、解決法は、Zend_Form から Zend_File_Transfer を使う場合でも同じです。

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

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

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

<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);
}

        

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


[注意] 注意

これは最もシンプルな例であることを忘れないようにしましょう。 これをそのまま実際の環境で使用しては いけません。 深刻なセキュリティ問題を引き起こしてしまいます。 常にバリデータを使用してセキュリティを向上させるようにしなければなりません。

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

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

現時点ではひとつだけしかアダプタが存在しないので、 基底クラスはまだ使えるようになっていません。 Zend_File_Transfer を使いたい場合は、 アダプタを直接使用する必要があります。

19.1.2. Zend_File_Transfer のオプション

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

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

19.1.3. ファイルのチェック

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

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

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

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

例 19.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();

            

19.1.4. さらなるファイル情報

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

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

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

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

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

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

例 19.3. ファイル名の取得

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

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

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

            

[注意] 注意

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

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

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

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

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

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

            

[注意] 注意

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