2016-02-25 187 views
0

我認爲這是Cakephp 3中的一個錯誤,但我想首先仔細檢查。Cakephp 3 - 圖片上傳 - mimeType - 無法驗證缺少文件的MIME類型

CakePHP的3.2.3 - Windows 7的使用XAMPP 3.2.2

查看:file.ctp

<div> 
<?= $this->Form->create($client, ['type' => 'file']) ?> 
<?= $this->Form->input('logo', ['type' => 'file']); ?> 
<?= $this->Form->button(__('Submit')) ?> 
<?= $this->Form->end() ?> 
</div> 

控制器: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腳本,我在過去的幾天嘗試過。 如果文件大小高於上傳邊界,則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 
     ) 
) 

這種情況總是拋出異常,如果mime類型檢查中驗證變量。

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檢查只能在文件成功上傳時完成。

該案件應該如何處理?

回答

1

這是預期的行爲,無論前一次失敗,所有驗證規則都會運行。所以在你的情況下,上傳錯誤將被識別,但是驗證仍然會繼續到下一個規則,然後會失敗,因爲沒有文件上傳。

此行爲可以通過使用last選項禁用。將規則標記爲last將導致該字段的驗證在規則失敗的情況下停止。

'uploadError' => [ 
    'rule' => 'uploadError', 
    'message' => __d('clients', 'The logo upload failed.'), 
    'last' => true 
], 

// ... 

又見Cookbook > Validation > Marking Rules as the Last to Run

+0

工程,解決了這個問題。感謝您及時的回覆。 –