好的,所以我现在已经四处走动了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部分!?我更喜欢使用准备好的陈述方法。
答案 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';