Cakephp 3图片上传 - 验证无效

时间:2016-02-25 10:29:41

标签: php validation cakephp file-upload

Cakephp 3 - 图像上传处理目前过于复杂。

我正在使用XAMPPv3.2.2进行WIN7系统

我有这个测试视图 - 用于测试上传的Clients \ file.ctp

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

我通过此控制器将名为logo(成功)的图像上传到服务器 - ClientsController.php

<?php

namespace App\Controller;

use App\Controller\AppController;
use Cake\Event\Event;
use Cake\Filesystem\Folder;

class ClientsController extends AppController
{
public function file() {
    $client = $this->Clients->newEntity();

    if ($this->request->is('post')) {

        $this->log($client, 'debug');
        $this->log($this->request->data, 'debug');

        $client = $this->Clients->patchEntity($client, $this->request->data);
        // Here my first error was included - I have setup the model including LOGO as a varchar(250) field. 
        // This is transferred into a text field but the upload needs to be an array
        // How do we have to define an image field within the Database?
        if (!empty($this->request->data) && !empty($this->request->data['logo']) && !empty($this->request->data['logo']['name']))
            $client->logo = $this->request->data['logo'];

        // Assigning test  to see if something is saved within the DB
        $client->name = 'TEST';              

        if ($this->Clients->save($client)) {
            $this->log($client, 'debug');
            $this->log($this->request->data, 'debug');

            $this->Flash->success(__('The client has been saved.'));
            return $this->redirect(['action' => 'file']);
        } else {
            //debug($client->errors());
            $this->Flash->error(__('The client could not be saved. Please, try again.'));
        }
    }

    $this->set(compact('client'));
    $this->set('_serialize', ['client']);
}

问题1: 我不得不将自己上传的数组分配给它工作的模型变量并上传。数据库模型应该如何通过BAKE生成图像上传?我找不到这个记录。

我已在ClientsTable.php之后设置以验证此数据

 <?php

 namespace App\Model\Table;

 use Cake\ORM\RulesChecker;
 use Cake\ORM\Table;
 use Cake\Validation\Validator;

 class ClientsTable extends Table
 {
public function initialize(array $config)
{
    parent::initialize($config);

    $this->table('clients');
    $this->displayField('name');
    $this->primaryKey('id');

    $this->addBehavior('Timestamp');

    // I handle the upload of the image within this Behavior.
    // This is working well! This validator is triggered with beforeSave event
    $this->addBehavior('Upload', [
        'field' => 'logo',
        'uploadPath' => 'logos',
        'setUniqueGuidName' => true
    ]);
}

public function validationDefault(Validator $validator)
{
    $validator
        ->uuid('id')
        ->allowEmpty('id', 'create');

    $validator
        ->allowEmpty('title');

    $validator
        ->add('logo', [
            'uploadError' => [
                'rule' => 'uploadError',
                'message' => 'The cover image upload failed.',
                'allowEmpty' => TRUE,
            ],

            'mimeType' => [
                'rule' => array('mimeType', array('image/gif', 'image/png', 'image/jpg', 'image/jpeg')),
                'message' => 'Please only upload images (gif, png, jpg).',
                'allowEmpty' => TRUE,
            ],
            'fileSize' => [
                'rule' => array('fileSize', '<=', '1MB'),
                'message' => 'Cover image must be less than 1MB.',
                'allowEmpty' => TRUE,
            ],
        ])
        ->allowEmpty('logo');
    }
}

问题2:为什么未触发验证?我可以上传PDF文件以及大于1MB的文件,并始终获得成功的消息。我也可以在目录中找到上传的文件!对于大于1MB的文件,我会得到一个有趣的例外

2016-02-25 03:17:07 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}

以下是控制器的两个日志条目的输出

 2016-02-25 03:36:36 Debug: {
"logo": "C:\\Users\\D052192\\OneDrive\\xampp\\htdocs\\pam\\webroot\\img\\logos\\56ce76c3edb88.pdf",
"name": "TEST",
"created": "2016-02-25T03:36:35+0000",
"modified": "2016-02-25T03:36:35+0000",
"id": "6d84cf0c-a1b9-4c1b-8e61-98dce6b9a659"
 }

2016-02-25 03:36:36 Debug: Array
(
[logo] => Array
    (
        [name] => TK.pdf
        [type] => application/pdf
        [tmp_name] => C:\Users\D052192\OneDrive\xampp\tmp\php57F0.tmp
        [error] => 0
        [size] => 6437
    )
)

我通过谷歌搜索了很多内容,但也在文档中搜索过,但无法确定我是否在设置验证调用时遇到问题,或者使用徽标变量的分配。

我在CakeCore中记录了流程 - Validation.php。

首先,如果我上传PDF文件,我会调用uploadErrors,而不会出现错误响应。 第二个是mimeType Check,它获得以下值

public static function mimeType($check, $mimeTypes = [])
$check = Array
        (
            [name] => TK.pdf
            [type] => application/pdf
            [tmp_name] => C:\Users\D052192\OneDrive\xampp\tmp\phpB7C.tmp
            [error] => 0
            [size] => 6437
        )

$mimeTypes = Array
        (
            [0] => image/gif
            [1] => image/png
            [2] => image/jpg
            [3] => image/jpeg
        )

与这些值一起,此函数返回FALSE。 所以问题是,为什么这个错误没有被处理? 我应该在哪里看下一个?

2 个答案:

答案 0 :(得分:0)

@ndm 非常感谢你的所有提示! 你是对的!通过这个电话

$client = $this->Clients->patchEntity($client, $this->request->data);

数据经过验证,只有在验证结果为肯定的情况下才会设置。 将$logo设置为请求中的值,清除了验证状态,因此屏幕上未显示。我已经评论了这个

if (!empty($this->request->data) && !empty($this->request->data['logo']) && !empty($this->request->data['logo']['name'])) $client->logo = $this->request->data['logo'];

但在这种情况下,如果我传输有效图像,$client->logo = ""为空。如果我传输的图像无效,则根本不会设置$client->logo

所以我通过扩展if语句解决了我的问题,如下所示

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'];

仅在验证被接受并设置之前,我才设置$logo 最后一个问题是,如果传输了有效图片并且必须手动分配,$client->logo = ""为空的原因。

答案 1 :(得分:0)

我看到数据库中存储图像路径的列名称也称为徽标。因此,尝试将输入名称从徽标更改为视图中的其他内容,然后在控制器表以及。