PHPのフレームワーク「Phalcon」で画像のバリデーションをしようとしたところエラーが発生したのでメモ。
エラーメッセージ
FastCGI sent in stderr: "PHP message: PHP Warning: strtr(): The second argument is not an array in {filepath}
環境
- PHP 7.1.33
- Phalcon 3.2.2
原因
Phalconのバグのようです。
2017年9月頃に修正が終わっているようなので、それ以降の3.2.x系のphalconだと大丈夫みたいです。
https://github.com/phalcon/cphalcon/issues/12947
今回は2017年9月以前のPhalcon3.2.2を使用していたため、エラーが発生。
コードは以下のようにしていました。
Formクラス
・・・ use Phalcon\Forms\Form; use Phalcon\Forms\Element\File; use Phalcon\Validation\Validator\File as FileValidator; class xxxx extends Form { $imageFile = new File('image_file'); $imageFile->setLabel('画像'); $imageFile->addValidators(array( new FileValidator(array( 'allowEmpty' => true, 'maxSize' => '2M', 'messageSize' => ':field exceeds the max filesize (:max)', 'allowedTypes' => array('image/jpeg', 'image/png'), 'messageType' => 'Allowed file types are :types', 'maxResolution' => '800x600', 'messageMaxResolution' => 'Max resolution of :field is :max' )) )); $this->add($imageFile); }
allowEmpty=trueで空を許可したので、画像を入力しなかった場合はエラーになりません。
画像を入力したときのみエラーになります。
allowEmpty=falseの場合は、画像未入力でもエラーになります。
対応策
Phalcon\Validation\Validator\File は使えないので、カスタムバリデーション等で対応。
いったん、バージョンアップするまでこんな感じでカスタムバリデーションを作成して暫定対応しました。
複数画像対応とか制約とか足りない部分もありますが、ベースとしてはこんな感じ。
カスタムバリデーション
namespace App\xxx\Validation\Validator; use Phalcon\Validation; use Phalcon\Validation\Message; use Phalcon\Validation\Validator; /** * Fileのバリデーション * * Phalcon\Validation\Validator\Fileがバグでうまく動作しないのでカスタムで作成(バグ:phalcon3.2.xの最新で改善するよう) */ class File extends Validator { /** * バリデーションの実行 * * use App\xxx\Validation\Validator\File as FileValidator; * * new FileValidator( * [ * "maxSize" => 3072, // キロバイトで指定 * "messageSize" => "field exceeds the max filesize ", * "allowedTypes" => [ * "image/jpeg", * "image/png", * ], * "messageType" => "Allowed file types are types", * ] * ) * * @param Validation $validator * @param string $attribute * @return boolean */ public function validate(Validation $validator, $attribute) { $request = $validator->getDI()->get('request'); if (!$request->hasFiles(true)) return true; $file = $this->getTargetFile($attribute, $request->getUploadedFiles(true)); if (!$file) return true; $maxSize = $this->getOption('maxSize'); if (!is_null($maxSize)) { if ($file->getSize() > $maxSize * 1024) { $message = new Message($this->getOption('messageSize'), $attribute, 'maxSizeFile'); $validator->appendMessage($message); return false; } } $allowedTypes = $this->getOption('allowedTypes'); if (!is_null($allowedTypes)) { if (!in_array($file->getRealType(), $allowedTypes)) { $message = new Message($this->getOption('messageType'), $attribute, 'allowedTypesFile'); $validator->appendMessage($message); return false; } } return true; } /** * リクエストからバリデーション対象ファイルを取得 * * @param array $attribute key * @param array $files $request->getUploadedFiles() * @return Phalcon\Http\Request\File | null */ public function getTargetFile($attribute, $files) { foreach ($files as $file) { if ($attribute === $file->getKey()) { return $file; } } return null; } }