【问题标题】:Inserting image path, into database将图像路径插入数据库
【发布时间】:2018-03-09 08:42:25
【问题描述】:

我一直在为一个 uni 项目创建一个网站,我的代码被指出易受 SQL 注入攻击,因为我没有使用准备好的语句。我正在纠正这个问题,我遇到了一堵墙,上传了图片。当我只是使用标准 MYSQLi 查询时,我了解它分配给变量的方式,现在因为我使用占位符和绑定参数,我有点迷茫。最初我无法将图像放入目录,尽管我现在已经通过阅读论坛解决了这个问题。现在我的图像路径没有存储在数据库中,我尝试了很多方法来让它工作并在论坛上广泛阅读。我只是无法使用准备语句在 MYSQLi 中获取图像上传的示例。希望有人能指出我正确的方向,让我更好地理解。

if(isset($_POST['add_product'])) {

    $destination = "C:/Ampps/www/Adaptive_Dev/images/".$_FILES['image']['name'];

    move_uploaded_file($_FILES['image']['tmp_name'], $destination);

    print_r($_FILES);

    $stmt = $connection->prepare("INSERT INTO products
                                (productBrand,
                                productModel,
                                productModelNo,
                                productPrice,
                                productDesc,
                                productSpec,
                                productInTheBox,
                                productGuarantee,
                                productImage)
                                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
    $stmt->bind_param("sssdsssis",
        $_POST['productBrand'],
        $_POST['productModel'],
        $_POST['productModelNo'],
        $_POST['productPrice'],
        $_POST['productDesc'],
        $_POST['productSpec'],
        $_POST['productInTheBox'],
        $_POST['productGuarantee'],
        $_FILES['ProductImage'] );
    $stmt->execute();

我暂时将列设置为接受空值,因此数据会传递到数据库。我试图在图像的占位符位置放置一个变量,这会引发各种错误。我只是不知道如何将它传递给绑定参数。

Array ( [image] => Array ( [name] => b&oM5Banner.jpg [type] => image/jpeg [tmp_name] => C:\Ampps\tmp\phpB39.tmp [error] => 0 [size] => 269481 ) )

我把我的 print_r 结果放在这里,我真的不知道我还能提供什么其他信息,我显然做错了什么,我不知道是什么。提前谢谢。

【问题讨论】:

  • 为什么Ive temporarily set the column to accept nulls,
  • $_FILES['ProductImage'] 不存在
  • 尝试改用$destination

标签: php mysqli prepared-statement


【解决方案1】:

您的错误相当明显,与准备好的语句无关。

你这么说

我已暂时将列设置为接受空值,

您为什么要这样做,因为它会告诉您哪里出了问题。您提供的路径为空。听取您收到的警告和错误通常是一个好主意,因为它们会告诉您在哪里查看。

此外,如果您打开了错误报告,那么您应该已经收到使用未定义索引的警告。你可以这样打开它:

<?php
    error_reporting(-1);
    ini_set('display_errors', 1);

但回到手头的问题,让我们看看您为图像路径输入的内容:

   $_FILES['ProductImage']

在最好的情况下,这是一个数组,而不是路径(字符串)。 $_FILES 数组是 PHP 中的一个超级全局变量,它有一个特殊的用途。也就是说,该数组包含有关通过 HTTP 上传的文件的信息。您应该知道这一点,因为您使用它将文件从“temp”文件夹移动到永久主页。

因此,鉴于解决方案确实非常简单。只需使用$destination 变量,这是您放置文件的路径。您可以在此处查看代码中使用的内容:

  move_uploaded_file($_FILES['image']['tmp_name'], $destination);

为了详细说明,$_FILES 超级全局数组的内容示例如下所示:

 $_FILES = [
      'image' => [
            'name' => 'b&oM5Banner.jpg',
            'type' => 'image/jpeg',
            'tmp_name' => 'C:\Ampps\tmp\phpB39.tmp',
            'error' => 0, 
            'size' => 269481
       ],
 ];
  //I know this because you output it with print_r

所以当您尝试使用$_FILES['ProductImage'] 时,难怪它不起作用?

希望这有助于解释发生了什么以及如何排除故障。

干杯。

【讨论】:

  • 现在你已经指出了它是完全有道理的。我将图像列设置为接受空值,因为我想确保其余数据正常通过。由于我一直在使用标准查询,因此我并不完全了解在何处使用该变量。那是我唯一没有放的地方。我错误地认为 FILES productImage 是必要的,所以我从未省略它。感谢您指出,我很感激。
  • 正确,但这样做会使调试变得更加困难。这就是我想说的。很难在文本中传达上下文,希望它听起来不“苛刻”。祝你好运,编码愉快。
  • 不,当然不是。您不厌其烦地回答并帮助我解决了我的问题,并与其他人一起给了我一些很好的指导,我一定会使用的。我认为这听起来并不刺耳,感谢您的帮助。
  • 当然,很高兴我能帮上忙。
【解决方案2】:

$_FILES['ProductImage'] 似乎不存在,但您确实使用路径创建了一个名为 $destination 的变量,所以我假设您应该使用它。

if(isset($_POST['add_product'])) {

    $destination = "C:/Ampps/www/Adaptive_Dev/images/".$_FILES['image']['name'];

    move_uploaded_file($_FILES['image']['tmp_name'], $destination);

    print_r($_FILES);

    $stmt = $connection->prepare("INSERT INTO products
                                (productBrand,
                                productModel,
                                productModelNo,
                                productPrice,
                                productDesc,
                                productSpec,
                                productInTheBox,
                                productGuarantee,
                                productImage)
                                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
    $stmt->bind_param("sssdsssis",
        $_POST['productBrand'],
        $_POST['productModel'],
        $_POST['productModelNo'],
        $_POST['productPrice'],
        $_POST['productDesc'],
        $_POST['productSpec'],
        $_POST['productInTheBox'],
        $_POST['productGuarantee'],
        //$_FILES['ProductImage'] );
        $destination );
    $stmt->execute();

以后在测试时将这些行添加到脚本的顶部,即使您在关闭错误显示的情况下进行开发(例如托管站点),也会在浏览器上显示错误。

ini_set('display_errors', 1); 
ini_set('log_errors',1); 
error_reporting(E_ALL); 
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

【讨论】:

  • @ArtisticPhoenix 哦,是的,我也是,如果你看看我的评论
  • 我永远不会对答案投反对票。所以不是我。如果你愿意,我可以投票。
  • @ArtisticPhoenix 好的,很酷,一定是一个合格的语法检查员,它注意到我在$destination ) 后面忘记了一个分号:)
  • @ezw 实际上我的答案是在另一个答案之后 1 分钟,但我对相同效果的评论是在另一个答案之前 1 分钟。但你的意思是什么?
  • 感谢您的回复并指出我的错误。我很感激,所以谢谢
猜你喜欢
  • 2019-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-28
相关资源
最近更新 更多