我在名为 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)
顺便说一句,如果错误消息很清楚,则无需在此处询问。只需阅读手册。