【问题标题】:Can't retrieve images from DB无法从数据库中检索图像
【发布时间】:2014-07-20 11:17:43
【问题描述】:

我构建了一个简单的表单,用于将图像连同描述一起上传到数据库中。图像和描述存储在数据库中,但我很难检索/渲染(?)图像。我认为数据库连接没问题,因为我实际上可以上传东西。我将在下面留下代码和一些打印屏幕:

表格:

上传.php

<form action="imageUpload.php" method="post" enctype="multipart/form-data">
  <label for="userFile">Upload your file: </label>
  <input type="file" size="40" name="userFile" id="userFile"/><br />
  <br />
  <label for="altText">Description of image</label>
  <textarea class="ckeditor" name="altText" id="altText"/></textarea><br />
  <br />
  <input type="submit" class="pdf" value="Save!" />
</form>

imageUpload.php

<?php
                if ( !isset($_FILES['userFile']['type']) ) {
                   die('<p><strong>Du har inte laddat upp någon bild!</strong></p></body></html>');
                }
            ?>
                Your image:<br /><br />
                Temporary name: <?php echo $_FILES['userFile']['tmp_name'] ?><br />
                Original name: <?php echo $_FILES['userFile']['name'] ?><br />
                Size: <?php echo $_FILES['userFile']['size'] ?> bytes<br />
                Type: <?php echo $_FILES['userFile']['type'] ?></p>

            <?php
                require '../scripts/common.php';
                // Validate uploaded image file
                if ( !preg_match( '/gif|png|x-png|jpeg/', $_FILES['userFile']['type']) ) {
                   die('<p>Bara gif, png eller jpg/jpeg filer är accepterade!</p></body></html>');
                } else if ( strlen($_POST['altText']) < 9 ) {
                   die('<p>Please write more then 9 characters!</p></body></html>');
                } else if ( $_FILES['userFile']['size'] > 5000000 ) {
                   die('<p>Your image is too big!</p></body></html>');
                // Connect to database
                } else if ( !($link=mysql_connect($host, $username, $password)) ) {
                   die('<p>Could not connect to DB</p></body></html>');
                } else if ( !(mysql_select_db($dbname)) ) {
                   die('<p>Error when connecting to DB</p></body></html>');
                // Copy image file into a variable
                } else if ( !($handle = fopen ($_FILES['userFile']['tmp_name'], "r")) ) {
                   die('<p>Could not open temp file!!</p></body></html>');
                } else if ( !($image = fread ($handle, filesize($_FILES['userFile']['tmp_name']))) ) {
                   die('<p>Error when reading the temp file!</p></body></html>');
                } else {
                   fclose ($handle);
                   // Commit image to the database
                   $image = mysql_real_escape_string($image);
                   $alt = htmlentities($_POST['altText']);
                   $query = 'INSERT INTO image (type,name,alt,img) VALUES ("' . $_FILES['userFile']['type'] . '","' . $_FILES['userFile']['name']  . '","' . $alt  . '","' . $image . '")';
                   if ( !(mysql_query($query,$link)) ) {
                      die('<p>Could not save info on the DB!</p></body></html>');
                   } else {
                      die('<p>Your info has been saved!</p></body></html>');
                   }
                }
            ?>

getImage.php

<?php
    require '../scripts/common.php';
    $link = mysql_connect($host, $username, $password);
    mysql_select_db($dbname);
    $query = 'SELECT type,img FROM image WHERE id="' . $_GET['id'] . '"';
    $result = mysql_query($query,$link);
    $row = mysql_fetch_assoc($result);
    header('Content-Type: ' . $row['type']);
    echo html_entity_decode($row['img']);
?>

showimage.php

<?php
                require '../scripts/common.php';
                if ( !($link=mysql_connect($host, $username, $password)) ) {
                   die('<p>Kunde inte koppla med databasen!</p></body></html>');
                } else if ( !(mysql_select_db($dbname)) ) {
                   die('<p>Fel att läsa databasen!</p></body></html>');
                } else {
                   $query = "SELECT id,name,alt FROM image";
                   if ( !($result = mysql_query($query,$link)) ) {
                      die('<p>Kunde inte läsa databasen!</p></body></html>');
                   } else {
                      for ( $i = 0 ; $i < mysql_num_rows($result) ; $i++ ) {
                        $row = mysql_fetch_assoc($result);
                        echo '<article class="span12 post"> 
                                <div class="mask3 span3"> 
                                    <img src="getImage.php?id=' . $row['id'] . '" alt="' . $row['alt'] . '" title="' . $row['name']  .'"/>    
                                </div>
                                <div class="inside">
                                  <div class="span8 entry-content">
                                    <div class="span12">
                                        ' . $row['alt'] . '
                                    </div>
                                  </div>
                                </div>
                              </article>';
                      }
                   }
                }
            ?>

showimage.php 的最终结果:

那么,关于如何使图像显示的任何建议?

【问题讨论】:

  • 作为一般提示,您应该避免使用 mysql_* 样式函数并使用 mysqli 或 pdo_mysql,因为它们已被弃用。它们有助于避免您的脚本当前可能受到影响的 SQL 注入攻击。至少你应该在任何输入上使用 mysql_real_escape_string() 在查询中使用它之前
  • 您可能还考虑是否需要将图像存储在数据库中(而不是对它们的引用); stackoverflow.com/questions/527801/…有一些有趣的地方

标签: php mysql database upload image-uploading


【解决方案1】:

我怀疑图像的“上传”存在问题。对mysql_real_escape_string 的调用正在扫描需要转义的“字符”,并在任何“不安全”字符之前插入一个反斜杠字符。

如果$image 是二进制数据(我没有看到任何base64 或十六进制编码/解码),我怀疑您并不想更改二进制数据。

鉴于您已经获得的信息,将二进制数据转换为十六进制格式可能适用于 INSERT(只要 SQL 文本的长度不超过 max_allowed_packet)。

... , img ) VALUES ( ... , x'FFD8FFE00004A464946000102' )

另一个选项是使用 MySQL LOAD_FILE 函数,读取位于 MySQL 服务器主机上的文件的内容。同样,max_allowed_packet 限制了可以通过这种方式加载的文件的大小。

... , img ) VALUES ( ... , LOAD_FILE('/tmp/img.jpg') )

【讨论】:

  • 如果你删除了 mysql_real_escape_string(),你需要对文件类型进行适当的检查,而不是依赖 $_FILES 信息,因为它可以被伪造并用于 SQL 注入。
  • @Kalitz:我不确定“正确检查文件类型”如何防止 SQL 注入。但是,我确信在二进制内容上运行 mysql_real_escape_string 有可能改变二进制内容,并且二进制内容不应包含在 SQL 文本中。为了使二进制内容“安全”包含在 SQL 语句中,我在回答中概述的两个选项是合适的。
  • OP在输出二进制文件时也需要避免使用html_entity_decode()
【解决方案2】:

如果在 getImage.php 内回显 row['img'] 而不是 html_entity_decode($row['img']); 我相信它会起作用。

【讨论】:

    【解决方案3】:

    这里是疯狂的猜测。试图弄清楚并提供可能有助于解决问题的信息。 我从未将二进制文件放入 MySQL(所以我不知道使用 BLOB 转义要求,如果有的话??????)

    (确保它不是 CSS 的东西。:-))

    <?php
        require '../scripts/common.php';
        $link = mysql_connect($host, $username, $password);
        mysql_select_db($dbname);
        $query = 'SELECT type,img FROM image WHERE id="' . $_GET['id'] . '"';
        $result = mysql_query($query,$link);
        $row = mysql_fetch_assoc($result);
        header('Content-Type: ' . $row['type']);
        echo html_entity_decode($row['img']);   //Is enough being echoed here?
    ?>
    
     // html_entity_decode() on a BLOB? [PHP Manual: html_entity_decode()][1]
    
    <div class="mask3 span3"> 
        <img src="getImage.php?id=' . $row['id'] . '" alt="' . $row['alt'] . '" title="' . $row['name']  .'"/>    
    </div>
    

    如果在 getImage.php 的最后一行回显了足够多的内容。文件名是必需的吗? 如果您使用的是&lt;base&gt; HTML 标记,则可能不必指定完整的 url。

    【讨论】:

      【解决方案4】:

      如果图像是 blob 或纯二进制数据,请使用数据 URIS-https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs

      【讨论】:

      • 那个链接好像坏了
      • 很奇怪。必须完整粘贴链接。
      猜你喜欢
      • 1970-01-01
      • 2012-10-07
      • 1970-01-01
      • 1970-01-01
      • 2013-11-09
      • 2021-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多