【问题标题】:Weird $_GET behaviour奇怪的 $_GET 行为
【发布时间】:2013-08-11 17:11:16
【问题描述】:

您好,我正在尝试用我的脚本修复一个错误。问题是我的 get 查询仍然适用于额外的字母。

所以,edit.php?id=1 有效,edit.php?id=1hello 也有效(显然它不应该)。发生了什么事?

$idtoedit = mysql_real_escape_string($_GET["id"]);

//Check if ID exists
$doesidexist = mysql_query("SELECT `id` FROM Data WHERE `id` = \"$idtoedit\"");
if (mysql_num_rows($doesidexist) == 0) {
    die("<div class=\"alert alert-error\"><h4 class=\"alert-heading\">Error</h4><p>ID does not exist.</p><p><a class=\"btn btn-danger\" href=\"javascript:history.go(-1)\">Go Back</a></p></div></div></body></html>");
 }

【问题讨论】:

  • obviously it wouldn't - 为什么不呢?
  • 我记得最近读过一些东西,ID 不应该以数字开头,也不推荐。至于“为什么”,我不知道。我只记得读过一些有这种影响的东西,答案来自一个 38k 会员。
  • 只有字符串需要转义(因此是“mysql_real_escape_string”而不是“mysql_real_escape_anything”)。对于数值,您最好使用$idtoedit = intval($_GET['id']);,这也有助于理解您所询问的行为。
  • 你应该使用 mysqli_* 函数。 mysql_* 已弃用。
  • 如果有帮助,您应该接受其中一个答案。

标签: php mysql get


【解决方案1】:

这是因为 MySQL 在将字符串转换为数字时对输入的“任何事情”处理。

您构建的 SQL 查询将输入作为字符串(它周围的 "s)传递,因此如果 = 左侧的列具有数字类型(您的示例中的 id 列)。

查看this section of the manual了解更多信息。

【讨论】:

  • +1 很好的解释 :) 我总是使用类型转换,所以这对我来说是新的! :)
【解决方案2】:

mysql_real_escape_string 仅“清理”变量,因此在查询中使用它是安全的,但它不会将其转换为整数,也不应该这样做。您可以使用PDO 和参数化查询来执行此操作,否则您必须自己手动转换,即

$idtoedit = (int) mysql_real_escape_string($_GET["id"]);

PDO 示例:

$sth = $pdoObject->prepare('SELECT `id` FROM Data WHERE `id` = ?');
$sth->bindParam(1, $_GET["id"], PDO::PARAM_INT);
$sth->execute();

编辑: 还没有真正回答你的问题,所以澄清一下: 正如 complex857 所说,MySQL 会尝试根据列类型进行转换,因此转换1hello 会导致整数值为 1。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 2015-07-20
    相关资源
    最近更新 更多