【问题标题】:Pulling BLOB image data from MySQL in PHP在 PHP 中从 MySQL 中提取 BLOB 图像数据
【发布时间】:2012-03-27 14:41:13
【问题描述】:

我正在阅读一些关于如何将我的图像作为二进制文件上传到数据库而不是将它们放在服务器本身上的教程,我让它像这样工作:

PHP:

$image = chunk_split(base64_encode(file_get_contents($tmpfile)));
    mysql_query("INSERT INTO images (`img_location`, `caption`, `user`, `genre`, `when`) VALUES ('$image', '$caption', '$id', '$genre', '$when')");

我的问题是你现在如何从数据库中提取它,我已经阅读了几种方法,尝试了所有方法,无法弄清楚,我没有收到 MySQL 错误,这就是我的方法我试试看:

$get_pics = mysql_query("SELECT * FROM images WHERE user='$id' ");
while($get_pics2 = mysql_fetch_array($get_pics))
{
$sixfour_enc = base64_decode($get_pics2['img_location']);

$new .= "<img src=\"".$sixfour_enc."\" >";
}

这行得通……有点,正在发生的事情是它在 IMG 标记中打印出原始二进制文件。

如何让它再次编译为可读图像?另外,将图像存储在数据库中是否愚蠢?我应该做我通常做的事情并将它们存储在服务器上吗?

谢谢 -麦克

【问题讨论】:

    标签: php mysql binary blob


    【解决方案1】:

    如果您愿意,您可以将图像存储在您的数据库中(尽管将它们存储为文件也没有错,选择适合您情况的任何内容),但将原始二进制数据存储在 BLOB 中(即不要用base64编码)。您可以将您从file_get_contents 获得的二进制数据直接嵌入到您的查询中,前提是您首先使用正确的转义函数(在您的情况下为mysql_real_escape_string)。

    至于图像的输出,您可以按照您现在的方式进行,但您必须使用 base64 编码并使用 data URI 方案来输出它,如下所示:

    echo '<img alt="embedded image" src="data:image/png;base64,' . chunk_split(base64_encode($get_pics2['img_location'])) . '">';
    

    请注意,嵌入图像数据有一些优点和缺点。需要注意的一些重要缺点是 base64 编码的严重开销(比原始编码大 33% 左右)和潜在的缓存问题。

    【讨论】:

    • 这完全有道理,我在回顾了性能影响后恢复了旧的做事方式,但我只是抛出这个是为了看看它是否有效,它做得非常好!谢谢楼主!
    【解决方案2】:

    如果您没有任何特殊原因将图像数据存储在数据库中,那么我强烈建议您以正常方式进行。

    这是因为,您的数据库引擎的性能将受到重大影响,因为您将获取和放置比必要更多的数据。

    此外,MySQL 表上的 BLOB 字段在大小方面明显大于其他表,并且在大多数情况下执行速度较慢。

    只要想象一下实现此功能后服务器上的开销就会让我不寒而栗。 ;)

    我想这一切都归结为可扩展性。一旦你的数据库填满,你的服务器就会变得不那么响应,最终会变成一个真正的猪。您的下一个选择是增加服务器 RAM 或修改您的代码以适应更大的负载。

    只是我的 2 美分,希望这会有所帮助!

    祝你好运!

    【讨论】:

    • 是的,我将按照常规方式进行操作。我正在尝试一些新的东西来看看它是如何工作的,但后来我意识到我的数据库会有多沉重。我在想这样做是否会更安全,也许更容易,但正如你所说,它很可能会对性能造成巨大影响。谢谢!
    • 不用担心,只是来帮忙! :)
    【解决方案3】:

    实际上,最好的方法是使用 PHP 脚本来输出带有适当标题的图像的二进制文件(例如 getimage.php),用于生成 HTML 的脚本将具有如下代码:

    $get_pics = mysql_query("SELECT id FROM images WHERE user='$userid' ");
    while($imglist = mysql_fetch_array($get_pics))
    {
        $new .= '<img src="getimage.php?id='.$imglist['id'].'" title="'.$imglist['caption'].'" />';
    }
    

    所以 HTML 看起来像:

    <img src="getimage.php?id=12345" title="the caption of" />
    

    您必须在表images 上有一个主键(为什么还没有?),比如说id

    getimage.php”脚本将提取二进制文件并输出内容(假设字段img_location 包含图像的实际内容:

    <?php
    // this will output the RAW content of an image with proper headers
    $id=(int)$_GET['id'];
    
    $get_img = @mysql_fetch_assoc(@mysql_query("SELECT img_location FROM images WHERE id='$id' "));
    
    $image = imagecreatefromstring(base64_decode($get_img['img_location']));
    if ($image){
        //you may apply here any transformations on the $image resource
        header("Content-Type: image/jpeg"); //OR gif, png, whatever
        imagejpeg($image,null,75);          //OR imagegif, imagepng, whatever, see PHP doc.
        imagedestroy($image);               //dump the resource from memory
    }
    exit();
    @mysql_close();
    ?>
    

    这种方法将为您提供灵活性。 但是,您可能需要检查和清理变量并选择另一种连接 MySQL 的方法,如 MYSQLi 或 PDO。 另一个好主意是使用准备好的语句来防止 SQL 注入。

    【讨论】:

      猜你喜欢
      • 2010-10-23
      • 2012-07-16
      • 2011-07-28
      • 2015-01-23
      • 2020-01-14
      • 2014-08-20
      • 2015-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多