你如何逃脱教义?



你如何逃脱教条?

我做了这个代码

$query = $em->createQuery(
                "SELECT a FROM AcmeTopBundle:ArtData a WHERE
                a.name = '". mysql_escape_string($name) ."'");

但是当$name是A'z 时

它返回错误

[DoctrineORMQueryQueryException]          
SELECT a FROM AcmeTopBundle:ArtData a WHERE  
                a.name = 'A's'  

我想在使用原始sql的情况下,我通过mysql_escape_string进行了转义。

我怎样才能避免这种学说上的错误呢?

我通常处理此问题的方法是使用参数和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();

好吧,即使有公认的答案,它也不是标题中的问题。@Sven的回答很接近,但没有提到:

条令文件

要在这些场景中转义用户输入,请使用Connection#quote()方法。

我对"场景"有点不满,或者更抱怨人们像圣杯一样推销事先准备好的声明。好吧,它们在理论上很好,在实践中——至少在PHP中——它们很糟糕,因为它们无法用VALUES (<bla bla>), (<more stuff>)做简单的事情,比如IN (<list>)或多插入,这是一笔巨大的交易,因为如果没有它,人们通常会求助于非常次优的SQL(说得轻一点)(好吧,如果人们虔诚地坚持至少准备好的语句)。

这并不能回答您的问题,但可以解释您的代码有什么问题。这不适合发表评论。

您不能也不应该使用mysql_escape_string()

  • 这是错误的转义函数,正确的转义函数曾经是mysql_real_escape_string()。阅读文档听起来不太像,但要正确地转义,您必须知道使用了哪个字符编码。在ASCII、ISO-8859-x甚至UTF-8等西方编码方案中,这可能没有什么区别,但有一些奇特的中文编码,绝对需要知道"字节是属于另一个字节,还是独立的
  • 使用mysql_real_eescape_string()时,需要使用mysql_connect()创建一个已打开的DB连接。如果不这样做,PHP会尝试使用PHP.ini文件中定义的默认用户和密码打开一个新连接。这通常会导致错误,因为如果没有密码,数据库将不允许您执行任何操作。此外,如果你成功了,那么这种连接的编码设置很可能不是Doctrine使用的
  • 使用任何mysql_*函数都是错误的,因为这些函数已被弃用。正确的方法是使用mysqli_*函数
  • Doctrine可以使用三种数据库连接方法中的任何一种:mysql、mysqli或PDO。如果要手动调用正确的转义函数,则必须选择真正使用的函数。当连接已经创建时。不知何故,您需要获取该连接资源,以允许您正在调用的函数检测所使用的编码

因此,最终有很多原因可以解释为什么仅仅使用听起来像是在完成任务的转义是错误的。

正确的方法是使用正在使用的数据库层的转义。如果你使用条令,那就用来逃跑。或者更好的方法是,避免转义,使用准备好的语句或查询生成器,让Doctrine处理其余部分。

基于https://stackoverflow.com/a/13377430/829533

你可以使用事先准备好的语句http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#using-准备好的报表

来自文档:

$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();

这将展示如何将数据插入到通常必须使用real_escape_string的数据库中。

条令和Symfony 3使用prepared not 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有一个值,那么它执行插入。如果没有,则插入失败。

相关内容

  • 没有找到相关文章

最新更新