你怎么逃避教义?
我制作了这段代码
$query = $em->createQuery(
"SELECT a FROM AcmeTopBundle:ArtData a WHERE
a.name = '". mysql_escape_string($name) ."'");
但是$ name是A'z
它返回错误
[Doctrine\ORM\Query\QueryException]
SELECT a FROM AcmeTopBundle:ArtData a WHERE
a.name = 'A\'s'
我认为在使用原始sql时我被mysql_escape_string
转义。
如何在学说上避免这个错误?
答案 0 :(得分:12)
我通常使用的方法是使用参数和querybuilder(https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/query-builder.html)...
$qb = $em->createQueryBuilder(
"SELECT a FROM AcmeTopBundle:ArtData a WHERE
a.name = :name")
->setParameter('name',$name);
$result = $qb->getQuery()->execute();
答案 1 :(得分:4)
基于https://stackoverflow.com/a/13377430/829533
来自文档:
$date = new \DateTime("2011-03-05 14:00:21");
$stmt = $conn->prepare("SELECT * FROM articles WHERE publish_date > ?");
$stmt->bindValue(1, $date, "datetime");
$stmt->execute();
答案 2 :(得分:2)
这不能解答您的问题,但会解释您的代码出了什么问题。它不符合评论。
您不能也不应该使用mysql_escape_string()
mysql_real_escape_string()
。阅读the documentation听起来并不像,但为了正确逃避,您必须知道正在使用哪种字符编码。在西方编码方案中,如ASCII,ISO-8859-x甚至UTF-8,它可能没有什么区别,但是有一些奇特的中文编码,绝对需要知道"
字节是否属于另一个字节或者是自己的。所以最后有很多理由说明为什么只是使用任何逃避声音就像是在做这项工作一样是错误的。
正确的方法是使用您正在使用的数据库层的转义。如果您使用Doctrine,则使用它进行转义。或者更好,避免转义,使用预准备语句或查询构建器,让Doctrine处理剩下的事情。
答案 3 :(得分:1)
好吧,即使已经接受了答案,也没有疑问,因为它的标题如此。 @Sven的答案接近,但没有提及:
要在这些情况下避免用户输入,请使用Connection#quote()方法。
我对“情景”感到不满,或者更多地是人们在推动准备好的陈述,例如一些圣杯。好吧,它们在理论上很不错,至少在PHP中它们实际上很笨拙,因为它们无法执行简单的操作,例如IN (<list>)
或使用VALUES (<bla bla>), (<more stuff>)
进行多次插入,这是一笔巨大的交易,如果没有最后,它很普遍地诉诸于不太理想的SQL(简而言之)(如果一个人至少在宗教上坚持使用准备好的语句,那就好了。)
答案 4 :(得分:0)
这将显示如何将数据插入到通常必须使用real_escape_string的数据库中。
Doctrine和Symfony 3使用编写的非QueryBuilder:
// get the post value
$value = $request->request->get('value');
$sql = "INSERT INTO `table_name`
(`column_name1`,`column_name2`)
VALUES
('Static Data',?)
";
$em = $this->getDoctrine()->getManager();
$result = $em->getConnection()->prepare($sql);
$result->bindValue(1, $value);
$result->execute();
如果您使用自动增量记录,现在获得成功/失败的奖励:
$id = $em->getConnection()->lastInsertId();
如果$ id有值,则执行插入。如果没有插入失败。