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。 所以问题是,为什么这个错误没有被处理? 我应该在哪里看下一个?
答案 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)
我看到数据库中存储图像路径的列名称也称为徽标。因此,尝试将输入名称从徽标更改为视图中的其他内容,然后在控制器和表以及。