如何在 cakephp3.7 中检索通过带有 blob 列的表单上传到 mysql 数据库中的图像字符串名称?

How to retrieve in cakephp3.7 the name as string of an image uploaded trough a form with blob column into a mysql database?

我正在用 cakephp3.7 构建一个电子商务网站,卖家 post 他们需要上传要销售的文章图片,并通过带有 Blob 的表单柱子。从视图中可以很好地上传图像,但是在数据库中没有显示图像的真实名称,相反,在那个地方显示的所有图像的名称是所有文章的 'Blob'。现在的问题是,当我试图从数据库中检索文章的图片(只能通过它的名字知道)到控制器以便将它发送到网站的前端时,它找不到图片,我严重卡住了!!!

但是当我到达 webroot/img 文件夹时,我找到了上传的图像,当我在前端视图中手动 copy/paste 名称时,图像出现在前端,其他属性为文章。

这是应该从数据库中查找文章及其图像的控制器代码,地址 table 是 table 'annonces',并且table 将图像存储在 'piece_jointe':

public function articles()
        {
            $this->viewBuilder()->layout('react2019');
            $annonces = $this->Annonces->find()
            ->where(['Annonces.subcategorie_id'=>1])
            ->contain(['Comptes', 'Subcategories'])
            ->all();


            $this->set(compact('annonces'));
        }

这是posted文章转发到前端时的文章视图,我现在无法检索的字段是'piece_jointe':

<?php foreach ($annonces as $annonce): ?> 
  <div class="col-lg-4 col-md-6 mb-4">
            <div class="card h-100">
              <a href="#"><?= $this->Html->image($annonce->piece_jointe, array('height'=>90, 'width'=>90)); ?></a>

              <div class="card-body">
                <h4 class="card-title">
                  <a href="#"><?= h($annonce->annonce_titre) ?></a>
                </h4>
                <h5><?= h($annonce->prix_produit) ?></h5>
                <p class="card-text"><?= h($annonce->annonce_description) ?></p>
              </div>
              <div class="card-footer">
                <small class="text-muted">&#9733; &#9733; &#9733; &#9733; &#9734;</small>
              </div>
            </div>
          </div>
<?php endforeach; ?>

我想知道如何从 mysql 数据库中检索 Blob 类型 'piece_jointe' 的名称并在 cakephp 语法中使用它:

<?= $this->Html->image($annonce->piece_jointe, array('height'=>90, ' 
        width'=>90)); ?>

因为当我将 $annonce->piece_jointe 变量替换为它的真实名称 'macbook' 时效果很好,例如:

<?= $this->Html->image('macbook', array('height'=>90, 'width'=>90)); ?>

到目前为止一切顺利!我深入研究了 cakephp 关于处理 图像、视频、pdf、文档等文件的惯例。 并且我了解了更多东西。首先,我认为我应该将图像作为 BLOB 存储在数据库中,以尊重 MVC 概念。但我终于弄清楚 cakephp 通常如何处理图像和文件,因为图像和文件是敏感信息,会在应用程序中打开漏洞,cakephp 建议不要将图像直接存储在数据库中以防止攻击,例如 SQL注射。很多人问过关于cakephp如何处理图片的问题,但是给出的答案并不都是完全适用的。所以我想分 4 个步骤给出要点: 1-当我们上传文件时,就像我对 'piece_jointe' 列所做的那样,我将其类型从 'BLOB' 更改为 'VARCHAR' ,cakephp 为该图像提供参数,您可以在此处从我的 debug($this->request->data) 的渲染中看到:

[
    'title' => 'computer',
    'category_id' => '1',
    'subcategory_id' => '3',
    'announce_description' => 'smart price',
    'prix_produit' => '500000',
    'photo'=> '',
    'compte_id' => '1',
    'piece_jointe' => [
        'tmp_name' => '/private/var/folders/kl/lgxkfn5x4r1fjht2wckngjzr0000gn/T/phpodWgh1',
        'error' => (int) 0,
        'name' => 'macbook.jpg',
        'type' => 'image/jpeg',
        'size' => (int) 37780
    ]
]

可以观察到'piece_jointe'有'temp_name','error','name','type',[=48等字段=] 由cakephp创建,供我们自定义图片和文件上传。 但是在这一堆信息中我们确实需要的是'name'。所以我们要在数据库中的 table 声明中添加另一个 varchar 列,这就是为什么我添加了 varchar 类型的列 'photo' ,您可以在上面的调试结果中看到。目的是给 'photo' 图像的路径 $uploadPath = WWW_ROOT.'img/products/' 及其名称 $fileName = $this->request->data['piece_jointe'][ 'name'] 在我们的控制器 add() 方法中 所以 cakephp 可能会遵循该路径并从相关文件夹中获取图像,在我的案例中,products 文件夹位于 webroot/img 内。整体操作如下所示:

    if (!empty ($this->request->data['piece_jointe']['tmp_name']))
                            {
                                  $fileName = $this->request->data['piece_jointe']['name'];
                                  $uploadPath = WWW_ROOT.'img/products/';
                                  $uploadFile = $uploadPath.$fileName;
                                  if (move_uploaded_File($this->request->data['piece_jointe']['tmp_name'], $uploadFile))
                                    {  
                                        $annonce->photo = 'products/'.$fileName;                

                                    }

                             }

2- 然后在 Model/Table 中不要忘记将此添加到 public 函数初始化(数组 $config)方法中:

$this->addBehavior('Timestamp');

另一件事也不要忘记在 add() 视图中提及上传 'piece_jointe' 属于 'type'=>'file' 的图像的位置。 你可能会这样:

       <?php
            echo $this->Form->input('piece_jointe', [ 'type' => 'file']); 
        ?>
</Div>

3- 最后列 'photo' 在数据库 /products/macbook.jpg 而不是 'BLOB' 中收到这个值,而我正在发疯。 4- 要检索图像,我们只需将其添加到视图中:

<?= $this->Html->image($annonce->photo, array('height'=>90, 'width'=>90)); ?>

总之,这些是在 cakephp 中处理图像和文件上传的可靠步骤。将图像存储到 BLOB 类型的数据库中,并期望它在前端显示在原始 MVC 概念中,这太疯狂了。 还要感谢@ndm 让我知道我错过了这个概念。