Cakephp 3 - 图片上传处理目前过于复杂。
我正在使用带有XAMPPv3.2.2的WIN7系统
我有这个测试视图 - 客户端''文件.ctp 用于测试上传
<div>
<?= $this->Form->create($client, ['type' => 'file']) ?>
<?= $this->Form->input('logo', ['type' => 'file']); ?>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
我通过此控制器(客户端控制器)将名为徽标的图像(成功)上传到服务器.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 生成的图像上传?我找不到这个记录。
我已经按照客户表进行了设置.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 - 验证.php中记录了流程。
首先,如果我上传PDF文件,则调用uploadErrors,则执行时没有错误响应。第二个是mime类型检查,它得到以下值
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。所以问题是,为什么这个假不处理?我下一步应该看哪里?
@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 = ""
为空。
我看到数据库中存储图像路径的列名也命名为徽标。因此,请尝试将输入名称从徽标更改为视图中的其他名称,然后在控制器和表中进行更改。