我认为这是Cakephp 3中的一个错误,但我想先仔细检查。
Cakephp 3.2.3 - 使用XAMPP 3.2.2的Windows 7
查看:file.ctp
<div>
<?= $this->Form->create($client, ['type' => 'file']) ?>
<?= $this->Form->input('logo', ['type' => 'file']); ?>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
Controller:ClientsController.php
public function file() {
$client = $this->Clients->newEntity();
if ($this->request->is('post') ) {
$client = $this->Clients->patchEntity($client, $this->request->data);
if (!is_null($client->logo)
&& !empty($this->request->data)
&& !empty($this->request->data['logo'])
&& !empty($this->request->data['logo']['name']))
$client->logo = $this->request->data['logo'];
$client->name = 'TEST';
if ($this->Clients->save($client)) {
$this->Flash->success(__('The client has been saved.'));
return $this->redirect(['action' => 'file']);
} else {
$this->Flash->error(__('The client could not be saved. Please, try again.'));
}
}
$this->set(compact('client'));
$this->set('_serialize', ['client']);
}
型号:ClientsTable.php
public function validationDefault(Validator $validator)
{
$validator
->add('logo', [
'uploadError' => [
'rule' => 'uploadError',
'message' => __d('clients', 'The logo upload failed.')
],
'mimeType' => [
'rule' => array('mimeType', array('image/gif', 'image/png', 'image/jpg', 'image/jpeg')),
'message' => __d('clients', 'Please upload images only (gif, png, jpg).')
],
'fileSize' => [
'rule' => array('fileSize', '<=', '1MB'),
'message' => __d('clients', 'Logo image must be less than 1MB.')
],
])
->allowEmpty('logo');
}
这是一个简单的ImageUpload-Test脚本,我在过去几天尝试过。 如果filesize高于上载边界,则mimeType验证会导致异常。我不是指fileSize验证金额。我的意思是PHP.ini中提到的值(在我的例子中是upload_max_filesize = 2M)。
如果我上传的文件大于2MB,我会收到此异常
2016-02-25 18:33:56 Error: [RuntimeException] Cannot validate mimetype for a missing file
Request URL: /pam/clients/file
Referer URL: http://localhost/pam/clients/file
Stack Trace:
#0 [internal function]: Cake\Validation\Validation::mimeType(Array, Array)
#1 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\Validation\RulesProvider.php(71): ReflectionMethod->invokeArgs(NULL, Array)
#2 [internal function]: Cake\Validation\RulesProvider->__call('mimeType', Array)
#3 [internal function]: Cake\Validation\RulesProvider->mimeType(Array, Array, Array)
#4 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\Validation\ValidationRule.php(138): call_user_func_array(Array, Array)
#5 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\Validation\Validator.php(1410): Cake\Validation\ValidationRule->process(Array, Array, Array)
#6 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\Validation\Validator.php(137): Cake\Validation\Validator->_processRules('logo', Object(Cake\Validation\ValidationSet), Array, true)
#7 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\ORM\Marshaller.php(193): Cake\Validation\Validator->errors(Array, true)
#8 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\ORM\Marshaller.php(466): Cake\ORM\Marshaller->_validate(Array, Array, true)
#9 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\ORM\Table.php(2073): Cake\ORM\Marshaller->merge(Object(App\Model\Entity\Client), Array, Array)
#10 C:\Users\D052192\OneDrive\xampp\htdocs\pam\src\Controller\ClientsController.php(102): Cake\ORM\Table->patchEntity(Object(App\Model\Entity\Client), Array)
#11 [internal function]: App\Controller\ClientsController->file()
#12 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\friendsofcake\crud\src\Controller\ControllerTrait.php(51): call_user_func_array(Array, Array)
#13 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\Routing\Dispatcher.php(114): App\Controller\AppController->invokeAction()
#14 C:\Users\D052192\OneDrive\xampp\htdocs\pam\vendor\cakephp\cakephp\src\Routing\Dispatcher.php(87): Cake\Routing\Dispatcher->_invoke(Object(App\Controller\ClientsController))
#15 C:\Users\D052192\OneDrive\xampp\htdocs\pam\webroot\index.php(37): Cake\Routing\Dispatcher->dispatch(Object(Cake\Network\Request), Object(Cake\Network\Response))
#16 {main}
$this->request->data
内的值为:
Array
(
[logo] => Array
(
[name] => Image6MB.jpg
[type] =>
[tmp_name] =>
[error] => 1
[size] => 0
)
)
如果mimeType检查在验证变量中,则此情况总是抛出异常。
public static function mimeType($check, $mimeTypes = [])
{
if (is_array($check) && isset($check['tmp_name'])) {
$check = $check['tmp_name'];
}
if (!function_exists('finfo_open')) {
throw new LogicException('ext/fileinfo is required for validating file mime types');
}
if (!is_file($check)) {
throw new RuntimeException('Cannot validate mimetype for a missing file');
}
这应该是蛋糕核心测试中的测试用例。因为apache没有上传数据并将error
设置为1.这应该由代码处理而不是抛出异常。
我有3次验证检查,无论如何最终会出现异常。在引发异常时,甚至无法显示uploadError
。 mimeType检查和fileSize检查只能在文件上传成功后才能完成。
如何处理此案件?
答案 0 :(得分:1)
这是预期的行为,无论前一个验证规则是否失败,都会运行所有验证规则。因此,在您的情况下,将识别上传错误,但验证仍将继续执行下一个规则,然后由于没有上传文件而导致失败。
可以使用last
选项禁用此行为。将规则标记为last
将导致在该规则失败时停止验证该字段。
'uploadError' => [
'rule' => 'uploadError',
'message' => __d('clients', 'The logo upload failed.'),
'last' => true
],
// ...
另请参阅 Cookbook > Validation > Marking Rules as the Last to Run