PHPのフレームワーク「Phalcon」で画像のバリデーションをしようとしたところエラーが発生したのでメモ。
エラーメッセージ
FastCGI sent in stderr: "PHP message: PHP Warning: strtr(): The second argument is not an array in {filepath}
環境
原因
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;
}
}