CakePHP 3:上传多个文件并将文件名保存在关联模型中?

Posted

技术标签:

【中文标题】CakePHP 3:上传多个文件并将文件名保存在关联模型中?【英文标题】:CakePHP 3: Upload multiple files and save file names in associated model? 【发布时间】:2015-10-06 22:40:34 【问题描述】:

我需要创建上传过程,用户可以使用带有 html5 多个属性的文件字段一次上传多个文件。文件名必须保存在关联模型中。

我可以成功运行上传一个文件并将文件名保存在照片表中,跨字段:

echo $this->Form->file('photos.name');

但如果我想启用上传更多照片

echo $this->Form->input('title'); // post title
echo $this->Form->input('maintext'); // post main text,
... etc
echo $this->Form->file('photos[].name',['multiple'=>true]);

我进入问题,并试图了解我在哪里犯了错误,但没有成功。

PostsController:

public function add()

    $post = $this->Posts->newEntity();
    if ($this->request->is('post')) 
        $post = $this->Posts->patchEntity($post, $this->request->data);

        if ($this->Posts->save($post)) 
            $this->Flash->success(__('The post has been saved.'));
            return $this->redirect(['action' => 'index']);
         else 
            $this->Flash->error(__('The post could not be saved. Please, try again.'));
        
    
    $this->set(compact('post'));
    $this->set('_serialize', ['post']);

PostsTable:

$this->addBehavior('Upload');

$this->hasMany('Photos', [
    'foreignKey' => 'post_id'
]);

上传行为

我目前执行调试 $data / $entity 的所有标准回调,但仅在 beforeMarshal 我使用:

$data = Hash::get($data,'name');
debug($data);
// debug output
[
'name' => 'HPIM3869.JPG',
'type' => 'image/jpeg',
'tmp_name' => 'C:\xampp\tmp\phpF02D.tmp',
'error' => (int) 0,
'size' => (int) 1295448
],
...

在 beforeSave 和 afterSave 中

我的表单没问题,数据在 Marshal 方法之前正确进入,如果我上传 3 个文件,我也会看到相同数量的调试输出,但在 beforSave 和 afterSave 调试中只显示第一个文件,如下所示:

debug($entity);

object(App\Model\Entity\Photos) 

    'name' => [
        'name' => 'HPIM3435.JPG',
        'type' => 'image/jpeg',
        'tmp_name' => 'C:\xampp\tmp\php5839.tmp',
        'error' => (int) 0,
        'size' => (int) 1517410
    ],
    'post_id' => (int) 469,
    'created' => object(Cake\I18n\Time) 

        'time' => '2015-10-07T09:22:44+0200',
        'timezone' => 'Europe/Berlin',
        'fixedNowTime' => false

    ,
    'modified' => object(Cake\I18n\Time) 

        'time' => '2015-10-07T09:22:44+0200',
        'timezone' => 'Europe/Berlin',
        'fixedNowTime' => false

    ,
    '[new]' => true,
    '[accessible]' => [
        '*' => true
    ],
    '[dirty]' => [
        'name' => true,
        'post_id' => true,
        'created' => true,
        'modified' => true
    ],
    '[original]' => [],
    '[virtual]' => [],
    '[errors]' => [],
    '[repository]' => 'Photos'


编辑:

出于测试的目的,我创建了这样一个表格:

echo $this->Form->input('name',['value'=>'zzz']);
echo $this->Form->input('photos.0.name',['value'=>'zzz']);
echo $this->Form->input('photos.1.name',['value'=>'hhh']);
echo $this->Form->input('photos.2.name',['value'=>'fff']);

也只保存第一个结果。

我需要帮助来了解如何保存多个表单数据。我哪里错了?

【问题讨论】:

您没有展示任何实际的上传过程,也没有真正提及任何具体的技术问题。人们很难回答你的问题。 我添加了一些新的细节。当我只想保存多个名称时也会发生同样的情况,请查看表单的最后一个示例。文件的上传和处理不是问题的主题,此时尝试保存关系表中的唯一名称。 上传/处理可能不受这个问题的影响,但了解这种未知的上传行为的作用可能很重要。如果甚至您的新示例(不涉及任何上传)都没有正确保存,那么该行为可能会涉及其中。也许您应该从您的问题中删除所有这些噪音,并说明重要的事情,即 1.) 您究竟需要如何构建已发布的数据(all 数据)以成功保存? 2.) 当前发布的数据(all 数据)究竟以什么结构到达?鉴于完全有可能成功保存。 你是对的。我分离了“未知”的上传行为,现在可以将多个数据保存到关系表中(从表单的最后一个示例发送)。我将不得不创建一个新问题,即行为如何处理多个数据。谢谢。 谢谢您的回复,我的错,我放了afterSave退出方法,并停止存储多条数据。我习惯在调试功能后放置 die 或 exit。我不知道存储多个数据时重复使用的模型和行为。 【参考方案1】:

我觉得你的领域应该是这样的

echo $this->Form->file('photos.name.',['multiple'=>true]); //note dot notation at end of name. It will generate input name as array

【讨论】:

不,该方法适用于 CakePHP 2 版本。

以上是关于CakePHP 3:上传多个文件并将文件名保存在关联模型中?的主要内容,如果未能解决你的问题,请参考以下文章

CakePHP 3 编辑上传

CakePHP - 如何在保存时将关联记录添加到模型中?

在 CakePHP 3 中保存多个 belongsToMany 关联

CakePHP 3.7 - 测试用例文件上传

CakePHP 3.7 - 测试用例文件上传

使用 CakePHP 1.3 将图像上传到服务器