【问题标题】:How To in CakePHP 3: Upload multiple images to server and save each image in database using cakephp 3如何在 CakePHP 3 中使用:将多个图像上传到服务器并使用 cakephp 3 将每个图像保存在数据库中
【发布时间】:2018-02-24 08:20:29
【问题描述】:

我正在使用 cakephp 3 上传多个图像文件,其中,我希望将这些图像上传到我的代码目录路径中指定的服务器中,并且每个上传的图像都应该保存在数据库中(我正在使用 MySQL 数据库)。

在我当前的构建中,我可以在表单中选择多个图像,幸运的是,提交表单后,所有图像都成功上传到服务器图像目录路径,正如我所料,事情只有一(1)张图像保存在数据库,因为它应该将所有和每个图像都保存在数据库中。

在此附上我的 ImageUploadController 中的代码副本:

public function add()
{
    $UploadedImage = array();
    $uploadedImage = $this->UploadedImages->newEntity();

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

        $images = array();

        $images = $this->request->data['name'];

        foreach ($images as $key => $image) {

          if(!empty($image[$key].$image['name'])){
            $fileName = $image[$key].$image['name'];
            $uploadPath = WWW_ROOT.'img/press-releases/';
            $uploadFile = $uploadPath.$fileName;


            if(move_uploaded_file($image[$key].$image['tmp_name'],$uploadFile)){

                $uploadedImage->name = $fileName;
                $uploadedImage->image_dir = 'press-releases/';
                $uploadedImage->status = $this->request->data['status'];

                $this->UploadedImages->save($uploadedImage);

            } else {  $this->Flash->error(__('Unable to upload image, please try again.'));  }


           } else { $this->Flash->error(__('Please choose an image to upload.')); } 

        }//EOF FOREACH      

    }

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

这是我的简单形式:add.ctp 文件: simple multiple image upload form

这是我的模型表 UploadImageTable:

class UploadedImagesTable extends Table
{
    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->setTable('uploaded_images');
        $this->setDisplayField('name');
        $this->setPrimaryKey('id');

        $this->addBehavior('Timestamp');
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->allowEmpty('name');

        $validator
            ->allowEmpty('image_dir');

        $validator
            ->boolean('status')
            ->allowEmpty('status');

        return $validator;
    }
}

我是 CakePHP 3 的新手,所以你们所有知道上传多张图片并将每张图片保存在数据库中的人,请帮帮我,或者有什么可以帮助我解决这个问题的,因为我有点卡住了这东西。您的任何帮助将不胜感激。

如需更多详细信息,特此添加我的调试器 SQL 日志的屏幕截图。In the image,I tried to upload 5 images

如果你能看到图片,因为我尝试上传 5 张图片;在第一个查询中,它对我的​​表执行 INSERT,然后下一个其他查询是 UPDATE,它应该是 INSERT。我想知道为什么 DML(Data Manipulation Language) 在此类查询中会突然发生变化。

提前多谢, 玛丽

【问题讨论】:

  • 感谢您的修改建议.. 感激不尽。
  • 你可以使用我的插件或者看看它。它确实在做您正在尝试的事情,但在更高的抽象级别上为您的应用程序中的所有内容提供文件存储,而不仅仅是图像。 github.com/burzum/cakephp-file-storage 阅读文档并随时在 IRC 或 Slack 频道上提问。我必须承认它可能对新手不太友好,因为它使用 CakePHP 事件系统,如果您不熟悉 SoC、DRY 和设计模式,总体上可能不太容易理解。
  • 你好 burzum,我刚刚阅读并尝试了一段时间你的 FileStorage 插件,它真的很棒,但老实说,我认为我真的需要一些时间才能了解它的工作原理,就像你的 SoC 一样,我在 cakephp 中有点新,并且仍在尝试探索它的核心。但我可以肯定地说,我会在其他时间使用你的。我真的很感谢你的帮助。非常感谢。

标签: php mysql image cakephp file-upload


【解决方案1】:

由于您要保存多个图像,因此您还必须创建多个实体以保存在数据库中。使用您当前的控制器,您将创建一个实体并将数据保存到该实体。

在您的 UploadedImagesController 中尝试以下操作:

public function add()
{
    if ($this->request->is('post')) {
        $data = $this->request->getData();

        $images = $data['name'];
        $path = 'img/press-releases/';

        foreach ($images as $image) {
            if(!empty($image['name'])) {
                $fileName = $image['name'];
                $uploadPath = WWW_ROOT . $path;
                $uploadFile = $uploadPath . $fileName;

                if(move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    // Create a new Entity over here for each uploaded image
                    $uploadedImage = $this->UploadedImages->newEntity();
                    $uploadedImage->name = $fileName;
                    $uploadedImage->image_dir = $path;
                    $uploadedImage->status = $data['status'];

                    $this->UploadedImages->save($uploadedImage)
                } else {
                    $this->Flash->error(__('Unable to upload image, please try again.'));
                }
            } else {
                $this->Flash->error(__('Please choose an image to upload.'));
            }
        }
    }

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

您也可以直接通过saving multiple Entities 解决此问题。您可能还希望将您的代码外包给模型或Behavior,以使其可在其他控制器中重用。就像 burzum 提到的那样,使用 file storage plugin 添加文件散列和/或唯一 ID(例如 UUID)等内容可能是明智的。否则你可以上传同名文件...

【讨论】:

  • 我只能说“哇”和“谢谢”你的代码就像一个魅力蜂蜜,我很高兴。我只是复制代码并替换我的整个 ADD 函数,并在(我猜你只是忘记了)“$this->UploadedImages->save($uploadedImage)”之后添加了一些分号,它就可以工作了。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2015-12-30
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多