代码之家  ›  专栏  ›  技术社区  ›  Alex

patchEntity()为什么会剪切图像信息?(CakePHP3)

  •  1
  • Alex  · 技术社区  · 8 年前

    使用POST方法 $data = $this->request->getData(); ,我获得存档:

    [
            'category_id' => '62',
            'title' => 'Name-1',
            'body' => '<p>Text</p>
        ',
            'price' => '30',
            'is_new' => '1',
            'img' => [
                'tmp_name' => 'D:\Web\OpenServer\userdata\temp\php70D9.tmp',
                'error' => (int) 0,
                'name' => 'IronMan.jpg',
                'type' => 'image/jpeg',
                'size' => (int) 131830
            ]
    ]
    

    通过为数据库中的记录准备这些数据:

    $product = $this->Products->patchEntity($product, $data);
    

    但是patchEntity()方法会删除有关图像的所有信息。 我得到:

    object(App\Model\Entity\Product) {
    
        'category_id' => (int) 62,
        'title' => 'Name-1',
        'body' => '<p>Text</p>
    ',
        'price' => (float) 30,
        'is_new' => (int) 1,
        'img' => '', // <--- empty :(
        '[new]' => true,
        '[accessible]' => [
            'category_id' => true,
            'title' => true,
            'body' => true,
            'price' => true,
            'img' => true,
            'is_new' => true,
            'created' => true,
            'modified' => true,
            'category' => true
        ],
        '[dirty]' => [
            'category_id' => true,
            'title' => true,
            'body' => true,
            'price' => true,
            'is_new' => true,
            'img' => true
        ],
        '[original]' => [],
        '[virtual]' => [],
        '[errors]' => [],
        '[invalid]' => [],
        '[repository]' => 'Products'
    
    }
    

    可以修复吗?至少告诉我。非常感谢。

    2 回复  |  直到 8 年前
        1
  •  1
  •   ndm    8 年前

    在修补/创建实体时,数据将根据相应的列数据类型进行编组,如您可以看到的其他属性,如 price ,它从字符串转换为浮点。

    你的 img 列可能是字符串类型,导致封送拆收器相应地转换数据(请参见 \Cake\Database\Type\StringType::marshal() ).

    有多种方法可以避免这种情况,例如使用不映射到现有列的不同属性名,如 img_upload ,然后在移动上载后,手动将生成的文件系统路径设置为 img公司 属性并保存该属性。

    这也可以在 beforeMarshal 您的 ProductsTable 类,以便视图模板可以继续使用 img公司 属性:

    public function beforeMarshal(
        \Cake\Event\Event $event,
        \ArrayObject $data,
        \ArrayObject $options
    ) {
        if (isset($data['img'])) {
            $data['img_upload'] = $data['img'];
            unset($data['img']);
        }
    }
    

    您还可以为 img公司 列,它不会将数据封送到字符串,而只是将其传递:

    namespace App\Database\Type;
    
    use Cake\Database\Type;
    
    class FileType extends Type
    {
        public function marshal($value)
        {
            return $value;
        }
    }
    

    无论如何,您都必须分配文件系统路径,基本上只需避免使用单独的/临时属性即可。

    另请参见

        2
  •  0
  •   Alex    8 年前

    我不知道这在多大程度上是正确的,但最终我做到了以下几点,一切都按照我的需要进行:

    产品内控制器 :

     public function add()
    {
        $product = $this->Products->newEntity();
    
        if ($this->request->is('post')) {
            $data = $this->request->getData();
    
            $product = $this->Products->patchEntity($product, $data);
    
            // If there is a picture that we checked (by the method of validationDefault, when calling patchEntity) and have already uploaded to the server in a temporary folder, then
            if($product->img_upload['name']){
                // We call the user method of processing the downloaded image
                $product = $this->_customUploadImg($product);
                // Leave only the name of the new file, adding it to the new property, with the name corresponding to the name of the table in the database
                $product->img = $product->img_upload['name'];
            }
            // Delete an unnecessary property
            unset($product->img_upload);
    
            if ($this->Products->save($product)) {
                // ...
            }
        // ...
    }
    

    在产品中。php:

        class Product extends Entity{
        protected $_accessible = [
            'category_id' => true,
            'title' => true,
            'body' => true,
            'price' => true,
            'is_new' => true,
            'created' => true,
            'modified' => true,
            'category' => true,
    
            // 'img' => true,
            // Here we specify not 'img' as in the database table, but 'img_upload', in order for ProductsController not to delete our data file about the uploaded file when patchEntity was called.
            'img_upload' => true,
        ];
    }
    

    在ProductsTable中。php :

    public function validationDefault(Validator $validator)
    {
        //...
    
         $validator
            ->allowEmpty('img_upload', 'create')
            ->add('img_upload', [
                'uploadError' => [
                    'rule' => 'uploadError',
                    'message' => 'Error loading picture'
                ],
                'mimeType' => [
                    'rule' => ['mimeType', ['image/jpeg', 'image/jpg', 'image/png', 'image/gif']],
                    'message' => 'Only image files are allowed to be uploaded: JPG, PNG и GIF'
                ],
                'fileSize' => [
                    'rule' => ['fileSize', '<=', '2MB'],
                    'message' => 'The maximum file size should be no more than 2 MB'
                ]
            ]);
    
        //...
    }
    

    添加中。ctp公司 :

    echo $this->Form->create($product, ['type' => 'file']) ?>
    // ...
    echo $this->Form->control('img_upload', ['type' => 'file', 'label'=>'Product photo']);
    //...
    

    感谢“ndm”和“mark”!