Zend_File

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 の API を使うようにし、Zend_File_Transfer を直接使わないようにしましょう。Zend_Form のファイル転送機能は Zend_File_Transfer で実装されているので、この章の説明は Zend_Form のユーザにも有用です。

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

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

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

<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 を説明するためだけのものです。 これをそのまま実際の環境で使用しては いけません。 深刻なセキュリティ問題を引き起こしてしまいます。 常にバリデータを使用してセキュリティを向上させるようにしなければなりません。

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

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

1.2. Zend_File_Transfer のオプション

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

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

1.3. ファイルのチェック

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

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

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

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

例271 ファイルのチェック

$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();

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

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

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

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

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

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

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

例272 ファイル名の取得

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

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

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

[注意] 注意

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

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

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

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

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

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

[注意] 注意

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