PDO::ATTR_EMULATE_PREPARES => 假

Posted

技术标签:

【中文标题】PDO::ATTR_EMULATE_PREPARES => 假【英文标题】:PDO::ATTR_EMULATE_PREPARES => false 【发布时间】:2013-11-13 04:34:33 【问题描述】:

我是 php 和 PDO 的新手,所以我阅读了对类似帖子的回复->

PDO真的不使用mysql的prepared statements吗?是的,通过 默认(至少在我测试的版本中)但可以打开本机模式 手动开启。如果不是,是否可以强制这样做? PDO::ATTR_EMULATE_PREPARES 设置,名字很漂亮 不言自明。 $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, 错误的 );你应该这样做吗?这是所有问题中最难的问题。 好吧,我会说 - 是的,你应该。如果您选择 PDO 作为您的数据库驱动程序, 在仿真模式下使用它没有意义。 — Your Common sense

对于 SQL 注入来说,准备好的语句不是安全的,为什么要从 'true'->false 更改?什么是原生模式??

【问题讨论】:

这个问题及其答案也可能有所帮助:***.com/questions/10113562/… 【参考方案1】:

从那以后我改变了主意。

首先,每种模式都同样安全。 使准备好的语句安全的不是本机绑定,而是参数化语句的一般原则,它完成格式化,从而产生无懈可击的查询。

所以,我宁愿保持模拟模式开启,因为它对一般的网络使用更有意义,并且允许一些次要的便利,例如更明智的错误消息(在查询中实际替换数据)或多个具有相同名称的占位符。

从模拟更改为本机模式的唯一原因是准备好的语句的另一个好处 - 可以多次执行一次准备好的语句。但是,如上所述,它很少需要。

【讨论】:

如果这两种模式同样安全,那你为什么说最好保持仿真模式打开呢?当查询只执行一次时,只是为了避免两次往返?这是一个正当的理由,我只是在问。 @BillKarwin 实际上,我也没有发现额外的往返那么重要。而是奥卡姆剃刀将其消除。此外,模拟模式允许多个具有相同名称的占位符。 @BillKarwin 感谢您提及two roundtrips。从安全的角度来看,您是否同意这两种方法是相同的?也许我太偏执了,但我会关闭仿真(如果可能的话) PDO 现在已经相当成熟和可靠,所以我同意@YourCommonSense 的观点——只要你不使用古老版本的 PHP,不要认为存在重大风险。如果您偏执并希望获得额外的安全性,您可以在将应用程序变量作为参数传递之前对其进行过滤或白名单。【参考方案2】:

取决于对您来说最重要的是什么 - 简单的编码和几行代码或正确的方法来避免 sql 注入。 只要您不使用庞大的数据库,它对速度没有影响,所以最好不要使用它 你可以像这样写代码

$result = $this->db->select('SELECT * FROM tbl_users WHERE login = :login AND password = :password', $arraiul);

或者那样

function editusers()
        $id = $_POST['id'];
        $name = $_POST['name'];
        $login = $_POST['username'];
        $password = $_POST['password'];
        $email = $_POST['email'];
        $power = $_POST['power'];
        if ($password =='')
            $sqlstm = "UPDATE tbl_users SET name='$name', login='$login', email='$email', power='$power' WHERE id='$id'";
         else 
            $sqlstm = "UPDATE tbl_users SET name='$name', login='$login', password=MD5('$password'), email='$email', power='$power' WHERE id='$id'";
        
        $sth = $this->db->prepare($sqlstm);
        $sth->execute();        
    
enter code here

【讨论】:

这如何回答这个问题? 此外,通过将 $_POST 变量中的内容直接插入 SQL 中,此答案极易受到 SQL 注入的攻击。在答案中显示不好的做法是不好的做法。

以上是关于PDO::ATTR_EMULATE_PREPARES => 假的主要内容,如果未能解决你的问题,请参考以下文章