为什么mysqli QUERY工作,但返回SQL语法错误的PREPARED语句版本相同?

时间:2017-07-13 06:03:00

标签: php mysql mysqli

好的,所以我现在已经四处走动了2个小时,无法弄清楚所谓的SQL语法错误在哪里。我最终将准备好的语句重新编写为标准查询 - 它工作正常,语法完全相同。

准备好的声明代码:(不工作)

if ($account_info = $mysqli->prepare("SELECT users.specid, users.username ?
    FROM users ? WHERE users.id = ?")) {
     //A SWITCH to determine bind_param and bind_result
} else {
     //Error output
}

以上导致以下MYSQL错误:

  

您的SQL语法有错误;检查手册   对应于您的MySQL服务器版本,以便使用正确的语法   靠近'?来自用户? WHERE users.id =?'在第1行

现在,如果我真的改变了'?'到$ variables并将准备好的语句转换为普通查询,如:

if ($account_info = $mysqli->query("SELECT users.specid, users.username $param1 
    FROM users $param2 WHERE users.id = $param3")) {
     //Fetch array and set variables to results
} else {
     //Error output
}

上面的代码按预期运行,没有错误。

对于那些好奇的特定开关案例中的$变量我测试:

$param1 = ', tenants.paper';
$param2 = ', tenants';
$param3 = $_SESSION['user_id'].' AND tenants.id = users.specid';

那么为什么一个有效但有另外一个有相同的语法?它甚至没有到达bind_param部分!?我更喜欢使用准备好的陈述方法。

3 个答案:

答案 0 :(得分:2)

您不能将对象nane(tablename或columnname)作为参数传递。

因为您尝试使用的users.username ?users ?是错误的。

传递param不是字符串替换..

这种行为是由param绑定不允许的 你应该避免这种情况..但如果你真的需要那么尝试使用字符串连接

答案 1 :(得分:0)

您只绑定参数绑定的值。不是SQL的一部分。 ::bind_param

您尝试使用$param1 = ', tenants.paper';进行的操作已经是SQL注入。构建预备语句是为了防止这种情况发生。

您应该为每个查询而不是通用查询创建一个方法。

答案 2 :(得分:0)

您无法在查询中绑定复杂的查询部分和列。我也不明白为什么你需要参数化你在代码中明确设置的字符串。

请改为:

$param = $_SESSION['user_id'];
if ($account_info = $mysqli->prepare("SELECT users.specid, users.username, tenants.paper
    FROM users JOIN tenants ON tenants.id=users.specid WHERE users.id = ?")) {
     //A SWITCH to determine bind_param and bind_result
} else {
     //Error output
}

如果您(在将来的任何时候)需要从用户输入中转义列名称(尽管您不应该允许用户开始这样的权力),请执行以下操作:

 $columnNameFromUserInput = $_GET["column"];
 $columnNameFromUserInput = "`".str_replace("`","",$columnNameFromUserInput)."`";

这应该足够了。

不要将包含需要转义的部分的查询段放在变量中。将需要转义的部分放在各自独立的变量中,这样就可以绑定它们了。这就是整个想法。

示例:

$param1 = ', tenants.paper'; //Bad has a comma in it, should be `tenants`.`paper` and the comma should go in the query itself
$param2 = ', tenants'; //Bad, though you have to use JOIN in any SQL language after 1992 
//The next part is very very bad.
// You have something that needs escaping mixed with things that compose a query. Split them. 
$param3 = $_SESSION['user_id'].' AND tenants.id = users.specid';