Webtech Walker

sfFormで画像アップロード

最近やっとsfFormはソース読まないとダメだということがわかってきました。だってドキュメント全部できてないんだもん。5章で説明します、って書いてあるのに5章がまだないってどういうことだよ。頼むよファビアン・・・。

まあそんなことを愚痴ってもしょうがないので、最近実装してる画像のアップロードについてわかってきたことをメモ程度に。

postValidatorで画像保存するのがよさげ

$form->getValues()はバリデーションが全てのフィールドで通らないと値を返さないので、画像以外のバリデーションが失敗したときも画像は保存したいときに、bindした後$form->getValues()から画像のデータを取得して保存というのはできないっぽい。

なのでpostValidatorのcallbackで画像を保存することにしました。$valuesとは別のところに保存した画像の情報をもっておきたいので$form->savedNameに保存したファイル名を持たせてます。

public function configure() {
    ...
    $this->getValidatorSchema()->setPostValidator(new sfValidatorCallback(
        array('callback' => array($this, 'postValidator'))
    ));
}

public function postValidator($validator, $values) {
    // 画像保存
    $file      = $values['image_file'];
    $filename  = 'uploaded_'.sha1($file->getOriginalName());
    $extension = $file->getExtension($file->getOriginalExtension());
    $file->save(sfConfig::get('sf_upload_dir').'/'.$filename.$extension);

    // 保存した画像名を保存
    $this->savedName = $file->getSavedName();

    // もとの値はセッションにつっこむとエラーになるので削除しておく
    unset($values['image_file']);

    return $values;
}

sfValidatorFileでcleanされたデータはsfValidatedFileのインスタンスで$valuesに格納されるんですが、値のもち回しにセッションを使っている場合、sfValidatedFileをセッションに保存するとunserializeするときにautoloadで失敗してエラーがでたので、どうせ使わないしunsetしました。

sfValidatedFileのメソッド

save($file = null, $fileMode = 0666, $create = true, $dirMode = 0777)

ファイルを保存する。$fileには保存するパスを渡す。$fileがなければgenerateFilename()でファイル名つくる(その場合はバリデータのオプションでpathを設定しておく必要あり)。

generateFilename()

ハッシュ化したランダムなファイル名を返す。

getPath()

保存するパスを返す。

getExtension($default = ”)

ファイルの拡張子を返す。連想配列にmime typeと拡張子のリストがあるのでそこから。リストになければdefaultを返す。

getOriginalExtension($default = ”)

ファイルの拡張子をファイル名の文字列切って抽出

isSaved()

保存されたか。$savedNameがあるかどうかを見てる。

getSavedName()

保存されたファイル名(フルパス)。

getOriginalName()

元ファイル名。

getTempName()

tempファイルのパス。

getType()

mime type。

getSize()

ファイルサイズ。

このエントリーをはてなブックマークに追加