【问题标题】:Insert Multiple Image Paths Into Multiple Columns将多个图像路径插入多列
【发布时间】:2020-08-17 10:49:00
【问题描述】:

在一个 Intranet 站点上,我将很多图像从文件系统移动到 MySQL,并编写了一个小函数来提供帮助。没有错误,但也没有插入图像,所以我需要帮助弄清楚如何在没有 LOAD_FILE() 的情况下执行此操作,因为它需要更改文件夹和文件权限,而我无法做到。

请注意,有必要查询专辑表,以便可以将专辑表中的主键与图像一起插入,以便显示专辑的程序知道要加载哪个图像。

function uploadFolder($path,$thumbpath) {
    // Use form to submit path (keeps process from running automatically when loaded)
    if (isset($_POST['create']) && isset($path)) :
        global $siteDB;

        // Fetch image names from existing albums
        $sqlAlbum = "SELECT ID, ImageName FROM albums ORDER BY ImageName";
        $sqlRow = DBConnect($sqlAlbum, "Multiple", $siteDB, "assoc");

        // Build queries to insert all images to table
        foreach ($sqlRow as $row) :
            $filename = basename($row['ImageName']);
            $albumID = $row['ID'];
            $pathname = $path.$filename; 
            $sqlUpload = "INSERT INTO images (`ImageName`,`AlbumID`,`ImageFull`) VALUES ('$filename', $albumID, LOAD_FILE('$pathname'))";
            // Run the query for each file
            DBConnect($sqlUpload,"Run", $siteDB);
        endforeach;

        // FOR TEST PURPOSES ONLY
        $_SESSION['testSQL'] = $sqlUpload;
    endif;
}

它被调用:

if (isset($_POST)) :
    $path = (isset($_POST['path'])) ? $_POST['path'] : "";
    uploadFolder($path,"thumbnails");
endif;

图片表不多,仅供参考:

CREATE TABLE IF NOT EXISTS `images` (
  `ID` int unsigned NOT NULL AUTO_INCREMENT,
  `ImageName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  `AlbumID` int unsigned DEFAULT NULL,
  `ImageFull` blob,
  `ImageThumb` blob,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=228 DEFAULT CHARSET=utf8;

除了 LOAD_FILE() 问题之外,我有两种方法可以做到这一点。一种是读取所有文件,如果它们存在于专辑表中,则通过查询将它们插入。另一个如上所示是通过查询从相册表中获取文件列表,然后从文件系统中查找并插入这些图像。执行后者(理论上)可以防止它插入不应该在相册中的杂散照片。

虽然我没有在这里展示它是因为我在发布问题后才意识到这一点,但这样做也可以让我从相册表中获取描述列,这样我就可以分辨出哪张图片是哪张。

【问题讨论】:

  • 你的表结构是什么样的?
  • 您正在查询专辑表?为什么?
  • 了解 sql 注入以及准备好的和绑定的查询的重要性 - 我很欣赏它是一个 Intranet 站点,但事实仍然是代码被从一个地方复制和粘贴到另一个地方,真的没有任何借口编写不安全的代码
  • 图像表中是否已经存在包含图像的非缩略图版本的行,或者这应该只加载缩略图?

标签: php mysql mysqli blob


【解决方案1】:

很难确定,因为您正在使用某种带有一些奇怪参数约定的数据库包装器。通常,您不会使用 LOAD_FILE,而是使用 php 将文件读取到变量中并使用 mysql 客户端 api 保存每一行。

LOAD_FILE 可以工作,但它必须是文件的确切路径,并且有效的网络服务器用户(运行网络服务器的用户)必须对您尝试读取的目录具有权限。

假设这是真的,这样的事情应该可以工作:

    foreach ($sqlRow as $row) :
        $filename = basename($row['ImageName']);
        $albumID = $row['ID'];
        $pathname = $path.$filename;
        $thumbPathname = $path . $thumbpath . DIRECTORY_SEPARATOR . $filename
        $sqlUpload = "INSERT INTO images (`ImageName`,`AlbumID`,`ImageFull`,`ImageThumb`) VALUES ('$filename', $albumID, LOAD_FILE('$pathname'), LOAD_FILE('$thumbPathname'));\n";
        // Run the query for each file
        DBConnect($sqlUpload,"Run", $siteDB);
    endforeach;

此代码假定 thumbNail 目录是路径目录的子目录。路径目录需要以斜杠结尾。

潜在问题:

  1. SQL 语句有一个分号和一个换行符。我从未见过包含这些的数据库客户端调用。 MySQL 客户端库不使用这些,所以我不确定为什么它们会成为 DB 包装器的一部分。
  2. 这里没有错误检查代码。如果DBConnect() 函数出现问题,您怎么知道?
  3. 路径变量必须完整且必须有一个结束分隔符。

好的

/somepath/to/directory/

不会工作

/somepath/to/directory

【讨论】:

  • 我根据您的 cmets 调整了代码。错误检查需要来自数据库包装代码。如果有来自 MySQL 的错误,您需要知道这些错误是什么,否则您将无法确定是否是问题所在。
  • 这有很多可能的原因。浏览this question中的答案
  • 该功能运行良好。它周围有安全控制,因此人们不能将其用作漏洞利用。只要您了解权限和 mysql 配置,它就可以正常工作。顺便说一句,您甚至从未确定您正在使用什么操作系统。
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多