如何在 MYSQLi 中求解参数


How to solve parameters in MYSQLi?

我在名为 JO-dashboard.php 的 php 文件中遇到了问题。它显示代码下方显示的错误。

这是我的代码:

<?php
$link = connectToDB();
$strXML = "<chart caption='Factory Output report' subCaption='By Quantity'   pieSliceDepth='30' showBorder='1' formatNumberScale='0' numberSuffix=' Units'>";   
$strQuery = "select DISTINCT profile from vgprofile";
$result = mysqli_query($link, $strQuery) or die(mysqli_error());
if($result) {
    while ($ors = mysqli_fetch_array($result)) {
        $strQuery = "select sum(MT) as totalLM from tbljocreator where PROFILE =" .    $ors['profile'];
        $result2 = mysqli_query($link, $strQuery) or die(mysqli_error());
        $getresult2 = mysqli_fetch_array($result2); 
        $strXML .= "<set label='" . $ors['profile'] . "' value ='" . $getresult2['totalLM'] . "'  />";
        mysqli_free_result($result2);
    }
}
mysqli_close($link);
$strXML .= "</chart>";
echo renderChart("FusionCharts/Column3D.swf", "", $strXML, "JoCreator", 450, 300, false, true);
?>

错误出在:

$result2 = mysqli_query($link, $strQuery) or die(mysqli_error());

在浏览器中,它显示:

Warning: mysqli_error() expects exactly 1 parameter, 0 given in C:'xampp'htdocs'LearningFusionCharts'MyFirstChart'JO-dashboard.php on line 29

mysqli_error函数需要一个参数。 http://us3.php.net/mysqli_error

P.S清理你的代码并使用选项卡:)


最初的问题

你必须将连接对象传递给函数mysqli_error,如下所示:

$result = mysqli_query($link, $strQuery) or die(mysqli_error($link));

而这...

$result2 = mysqli_query($link, $strQuery) or die(mysqli_error($link));

注意:您的代码必须有另一个问题,在您执行此操作后将揭示该问题。如果查询中没有错误或与之相关的内容,PHP 将不会执行mysqli_error的部分。


隐藏的问题

事实上,我有理由认为*问题是$ors['profile']是字符串,因此它应该在查询字符串中的引号之间:

$strQuery = 'select sum(MT) as totalLM from tbljocreator where PROFILE = "' . $ors['profile'] . '"';

*:这在评论中得到了证实。错误是:

您的 SQL 语法有误;请查看手册 对应于您的MySQL服务器版本,以便使用正确的语法 靠近1号线的"铆钉"

在这种情况下,RIVETS$ors['profile']的值,显然它是一个字符串,因此它必须在引号之间......但这并不意味着它是安全的。


SQL 注入

我们可以说你的代码是正确的,相同的代码可能会工作是数据不同的地方。但是,由于您在查询字符串中输入的值可能并不完全安全(即使数据来自数据库),因此您将不得不转义危险字符。

这是由您得到的错误证明的:

您的 SQL 语法有误;请查看手册 对应于您的MySQL服务器版本,以便使用正确的语法 靠近第 1 行的"切割盘 4"附近

在这种情况下,变量$ors['profile']得到字符串CUTTING DISC 4"。此值来自数据库,会导致问题。它包含4"意思是四英寸,但Mysql看到引号(")并认为这是字符串的结尾,并试图将引号后面的任何内容解释为SQL。

如果此输入不是来自数据库,而是来自用户...这将是最糟糕的...恶意用户可能会利用它来执行数据库中的任意命令。这种攻击的潜力是压倒性的。

我推荐视频 使用SQL注入的黑客网站 - 计算机爱好者,对于那些初学者来说,这是对SQL注入的一个非常好的介绍 网络安全,数据库安全或一般信息安全。要了解有关此类攻击可能执行的操作的更多信息,请阅读Trenton Ivey的SQL注入演练(DVWA)。


防止 SQL 注入 - 旧方法

解决这个问题的旧方法是转义字符。SQL允许通过使用反斜杠字符(')来做到这一点。因此,在此示例中,您必须传递4'"而不是4"。但这只是冰山一角,它有很多安全问题。

为了便于迁移,您可以做的是声明一个函数来清理您发送到数据库的数据,这个想法是转义任何可能的处理字符......事实上,在PHP中有一个函数(mysql_real_escape_string):

$strQuery = 'select sum(MT) as totalLM from tbljocreator where PROFILE = "' . mysql_real_escape_string($ors['profile']) . '"';

旧方式的问题

但是mysql_real_escape_string已被弃用,不应该在新开发中使用(你会注意到它不是 mysqli... ),这个函数本身也有一些怪癖......例如,没有办法告诉该函数你正在使用什么字符编码(它使用数据库正在使用的任何字符编码),并且有报道称在使用多字节字符时它有问题。这是解决这个问题的旧方法。

这是另一个建议:每个软件开发人员绝对,肯定必须了解的关于Unicode和字符集的绝对最低限度 作者:Joel Spolsky。我明白如果你不想读...获取另一个视频: 字符,符号和Unicode奇迹 - 计算机爱好者


防止SQL注入 - 新的和改进的方法

话虽如此,正确的解决方案是迁移到预准备语句,它们对于 mysqli 来说并不是那么难,它会是这样的:

$strQuery = 'select sum(MT) as totalLM from tbljocreator where PROFILE = ?';
if($stmt = $link->prepare($strQuery))
{
    //s for string
    //i for integer
    //d for double (or float)
    $stmt->bind_param('s', $ors['profile']);
    if (!$stmt->execute())
    {
    die mysqli_error($link);
    }
}
else
{
    die mysqli_error($link);
}

在 PHP.net 阅读更多关于准备好的声明。

只需更改

mysqli_error() 

mysqli_error($link)

在它发生的每个地方。

即第四行:

$result = mysqli_query($link, $strQuery) or die(mysqli_error($link));

和第八行:

$result2 = mysqli_query($link, $strQuery) or die(mysqli_error($link));

替换

mysqli_error()

mysqli_error($link)

顺便说一句,如果错误消息很清楚,则无需在此处询问。只需阅读手册。