我有一个可以添加帖子的博客,所以假设我创建了一个标签asd'qwe
然后我创建一个帖子,通过搜索添加一个标签,输入asd'
,当涉及到报价'
时,我在网络中得到一个错误
SQLSTATE[42000]: Syntax error or access violation: 1064 SQL语法错误;检查与您的MySQL服务器版本对应的手册,以便在第一行使用"asd",
name
)'附近使用正确的语法。正在执行的SQL是:SELECTid
,name
FROMblog_tag
WHEREname
LIKE '%asd'%' ORDER BY LOCATE('asd ",name
)
这都是因为这里的引号,这是我为post添加标签的函数
public function actionGetTags($query = '')
{
Yii::$app->response->format = Response::FORMAT_JSON;
if (!is_string($query) || !$query) {
return '';
}
$tags = BlogTag::find()
->select(['id', 'name'])
->where(['like', 'name', $query])
->orderBy(["LOCATE('$query', `name`)" => SORT_ASC])
->asArray()->all();
return $tags;
}
我听说在yii2中有转义方法来修复类似的错误,但我还没有弄清楚在哪里以及如何使用它
如有任何帮助或提示,我将不胜感激。如果您这样调用orderBy
,则在将$query的值传递给orderBy
函数之前将其插入字符串。orderBy
函数将数组键视为列名,并且不会转义它们。
这是一个相当大的问题,因为除了你正在经历的错误,它可以被滥用SQL注入攻击。
如果你想在SQL查询的order by
子句中使用更复杂的表达式,你应该使用yiidbExpression
。这将允许您将$query
作为绑定参数传递,而不是直接包含它。
在你的例子中,orderBy()
可以像这样:
->orderBy(new yiidbExpression(
'LOCATE(:query, `name`) ASC',
[':query' => $query]
))
你不必担心where()
调用。对于像['like', 'name', $query]
这样的简单条件,查询生成器将自动使用绑定参数。