PHP 从 MySQL 下载批量图片 Table

PHP Bulk Image Download from MySQL Table

我正在尝试下载存储为 MySQL table.

中的所有图像文件(.jpg 格式)

以下 PHP 代码可以毫无问题地单独显示和保存各个图像。

blob2img.php

<td>
<form method="post" action="download_img.php">
<input type='submit' name='submit' <?php $imgCode = $row['IMAGEID']; echo "value='View imgId: " . $imgId . "'"; ?> />
<input type='hidden' name='imgId' <?php echo "value='" . $imgId . "'"; ?> />
</form>
</td>

download_img.php

<?php
    $img_id = $_REQUEST['imgId'];
    require_once "db3.php";
    if(isset($img_id)) {
        $myCode = $img_id;
        $sql = "select * from images where IMAGEID='" . $myCode . "'";

        if (!$result=mysqli_query($con, $sql)){
        echo mysqli_error($con);
        } else {
            $row = mysqli_fetch_array($result);
        header('Cache-Control: no-cache');
        header('Accept-Ranges: bytes');
        header('Content-Type: image/jpeg');
                header('Content-Transfer-Encoding: binary');
        header('Content-Disposition: attachment; filename="'. basename($row["IMAGEID"]) . '_' . basename($row["LOCATION"]) . '"');
            echo $row["IMAGEDATA"];
        }
    }
?>

问题是 table 中存储了数千张图片,如果能够一次下载全部图片会更好。 当 download_img.php 文件被免除并且上面的 ... blob2img.php 文件中的块被替换为以下代码:

<?php
    require_once 'db3.php';
    $result = mysqli_query($con,"SELECT IMAGEID, LOCATION FROM images");
    if (mysqli_num_rows($result) > 0) {
?>
<table class='table table-bordered table-striped'>
    <tr>
        <td>ImageId</td>
        <td>Location</td>
        <td>ImageData</td>
    </tr>
    <?php
        $i=0;
        while($row = mysqli_fetch_array($result)) {
    ?>
    <tr>
        <td><?php echo $row["IMAGEID"]; ?></td>
        <td><?php echo $row["LOCATION"]; ?></td>
        <td>
            <?php
                header('Content-Type: text/html; charset=utf-8');
                if (!file_exists($file)) {
                    $basedir = '/home/user/Documents/retrieved-images/';
                    $id = $row["IMAGEID"];
                    $loc = $row["LOCATION"];
                    $data = $row["IMAGEDATA"];
                    $file = $basedir . $id . "_" . $loc;
                    $fp=fopen($file,"wb");
                        echo "Opening File: $file<br>";
                        fwrite($fp,$data);
                        echo "Writing File: $file<br>";
                        fclose($fp);
                        echo "Closing File: $file<br>";
                        sleep(1);
                } else {
                        echo "Skipping File: $file<br>";
                }
            ?>
        </td>
    </tr>
    <?php
        $i++;
        }
    ?>
</table>

... table 逐行加载,文件下载似乎已处理,因为所有打开文件、写入文件和关闭文件消息都按预期返回,但是 none的图像文件被写入目标目录。这不可能是权限问题,因为用户对 $basedir 指定的目标目录具有完全 read/write 权限。

如果下面一行代码:

    $result = mysqli_query($con,"SELECT IMAGEID, LOCATION FROM images");

替换为:

    $result = mysqli_query($con,"SELECT IMAGEID, LOCATION, IMAGEDATA FROM images");

只返回页面标题。出于某种原因,如果 IMAGEDATA 在那个阶段包含在 select 进程中,它会阻止 table 被加载。

如果如下代码行:

                    $id = $row["IMAGEID"];
                    $loc = $row["LOCATION"];
                    $data = $row["IMAGEDATA"];

被替换为:

                    $sql = "select * from images where IMAGEID='" . $row["IMAGEID"] . "'";
                    $id = $sql["IMAGEID"];
                    $loc = $sql["LOCATION"];
                    $data = $sql["IMAGEDATA"];

数据以随机顺序返回,$sql["LOCATION"] returns 实际图像文件名,但同样不会将任何图像文件保存到目标目录.

根据 siride 和 Robert 的初步反馈,我尝试替换以下代码行:

                if (!file_exists($file)) {
                    $basedir = '/home/user/Documents/retrieved-images/';
                    $id = $row["IMAGEID"];
                    $loc = $row["LOCATION"];
                    $data = $row["IMAGEDATA"];
                    $file = $basedir . $id . "_" . $loc;

与:

                    $basedir = '/tmp/retrieved-images/';
                    $id = $row["IMAGEID"];
                    $loc = $row["LOCATION"];
                    $data = "select IMAGEDATA from images where IMAGEID='" . $id . "'";
                    $file = $basedir . $id . "_" . $loc;
                    if (!file_exists($file)) {

...但该更改也没有任何区别。

$basedir = '/tmp/'; 到 /tmp/ 实际上会导致“跳过文件:...”消息,而 $basedir = '/tmp/retrieved-images/'; 不会。

如有任何帮助,我们将不胜感激。

正如 Robert 和 Rick James 所指出的,该问题是内存限制问题。罗伯特对 mysqli_use_result 和 link 的引用为我指明了解决问题的正确方向。

下面是一次性从数据库中下载所有图片的代码:

<table class='table table-bordered table-striped'>
    <tr>
        <td>ImageId</td>
        <td>Location</td>
        <td>ImageData</td>
    </tr>
    <?php
        require_once 'db3.php';
        mysqli_real_query($con, 'SELECT * FROM images');
        $result = mysqli_use_result($con);
        header('Content-Type: text/html; charset=utf-8');
        while ($row = mysqli_fetch_row($result)) {
    ?>
    <tr>
        <td><?php echo $row[0]; ?></td> 
        <td><?php echo $row[5]; ?></td>
        <td>
            <?php
                if (!file_exists($file)) {
                    $basedir = '/tmp/';
                    $id = $row[0];          // 0 here and above refers to the location where the IMAGEID data is stored in the returned row array.
                    $loc = $row[5];         // 5 here and above refers to the location where the LOCATION data is stored in the returned row array.
                    $data = $row[9];        // 9 refers to the location where the IMAGEDATA data is stored in the returned row array.
                    $file = $basedir . $id . "_" . $loc;
                    $fp=fopen($file,"wb");
                        echo "Opening File: $file<br>";
                        fwrite($fp,$data);
                        echo "Writing File: $file<br>";
                        fclose($fp);
                        echo "Closing File: $file<br>";
                        sleep(1);
                } else {
                        echo "Skipping File: $file<br>";
                }
            ?>
        </td>
    </tr>
    <?php
        }
        mysqli_free_result($result);
    ?>
</table>

再次感谢大家的意见。