Php mysql只返回带有数值的结果

Php mysql只返回带有数值的结果,php,mysql,Php,Mysql,我正在为公共访问类别创建一个随机字母数字,该类别只能通过在url链接中使用此字母数字帖子id找到。奇怪的是,我只在使用数值时从查询中得到结果 $sql = "SELECT * FROM $a WHERE access_key = $category_id 我得到一个“unknown column”错误,其中包含alphnumeric数据作为列,我觉得有点奇怪。我想这可能是需要做的一些简单的事情,比如逃跑,但我不是很确定 任何建议都将被采纳。提前感谢。正如tadman所说的,不要在SQL

我正在为公共访问类别创建一个随机字母数字,该类别只能通过在url链接中使用此字母数字帖子id找到。奇怪的是,我只在使用数值时从查询中得到结果

 $sql = "SELECT *
 FROM $a
 WHERE access_key = $category_id
我得到一个“unknown column”错误,其中包含alphnumeric数据作为列,我觉得有点奇怪。我想这可能是需要做的一些简单的事情,比如逃跑,但我不是很确定


任何建议都将被采纳。提前感谢。

正如tadman所说的,不要在SQL中使用直接的$\u GET或$\u POST值。用这样的东西保护它:

Function protectSQL($val, $type=‘text’) {
$val = get_magic_quotes_gpc() ? stripslashes($val) : $val;
switch ($type) {
    case "text":
         $val = ($val != "") ? "'" . $val . "'" : "NULL";
         break;
    case "long":
    case "int":
         $val = ($val != "") ? intval($val) : "NULL";
         break;
      }
return $val;
}
$sql = sprintf("SELECT * FROM %s WHERE access_key = %s", $a, protectSQL($val)); // $val is passed in the functions above, and $a has to be guaranteed...
由于您没有在撇号中包装您的值,MySQL认为它是一个列。所以,写下如下内容:

Function protectSQL($val, $type=‘text’) {
$val = get_magic_quotes_gpc() ? stripslashes($val) : $val;
switch ($type) {
    case "text":
         $val = ($val != "") ? "'" . $val . "'" : "NULL";
         break;
    case "long":
    case "int":
         $val = ($val != "") ? intval($val) : "NULL";
         break;
      }
return $val;
}
$sql = sprintf("SELECT * FROM %s WHERE access_key = %s", $a, protectSQL($val)); // $val is passed in the functions above, and $a has to be guaranteed...
你会得到一些干净的东西,比如:

echo $sql; // SELECT * FROM table WHERE access_key = 'abc123'

请记住,假定$a来自您的代码,因此没有添加任何保护。如果它来自客户端,一个简单的in_array命令可以确保它是一个有效的表。

这是正确的方法,也可以修复您看到的错误

MYSQLI:

// assuming $a is already safe
$stmt = $mysqli->prepare('SELECT * FROM '. $a .' WHERE access_key = ?');
$stmt->bind_param('s', $category_id);
$stmt->execute();
PDO:

至于白名单。。。这是一个基本示例(在执行任何sql操作之前执行):

啊。。。。如果您只是想快速修复当前的sql代码行(但请务必在将来准备好):


警告:这有一些严重问题,因为用户数据在查询中使用。尽可能使用事先准备好的陈述。在任何用户提供的数据都指定有
:name
指示符的情况下,这些操作非常简单,稍后将根据您使用的是哪个指示符,使用
绑定参数或
执行
填充指示符。永远不要将
$\u POST
$\u GET
或任何用户数据直接放在查询中。您只需要在“$category\u id”周围加引号即可。但是请阅读关于sqli.fair关于注入的评论,感谢您的提醒,因为这是一个url请求,但这是beta dev,在我有工作代码之前,我将避免准备语句的问题。除了为$category_id值准备之外,请确保将$a将拥有的内容也列入白名单。由于您无法准备表名(或字段名)。@Randall这是通过wordpress前缀设置进行的,因此$a已经生成。我需要在这方面做更多的工作吗?天哪,这是我以前没有考虑过的保护措施。感谢您对列/变量问题的澄清。查询如何解释没有引号的变量?它与带有量化标记的变量有何不同?这不会保护您免受任何类型的SQLi的攻击!有趣的工具。不过,我看不到查询的“保护”/“安全性”结果。出于兴趣,感谢您,白名单是如何添加保护的?例如:它如何防止攻击将此标记为正确答案,因为它对原始代码以及附加信息进行了最简单的更正。虽然使用“$category\u id”而不是“$category\u id”可以简单一点,但我为您调整了答案:)您忘记了在返回、退出和死亡之后抛出异常;-)
$sql = "SELECT *
        FROM $a
        WHERE access_key = '$category_id'";