将PDO :: ATTR_EMULATE_PREPARES设置为false无效 [英] Setting PDO::ATTR_EMULATE_PREPARES to false not working

查看:398
本文介绍了将PDO :: ATTR_EMULATE_PREPARES设置为false无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在PDO中禁用模拟准备,但是我无法使其正常工作.其他一切正常.查询成功.我认为它不起作用的原因是因为它不能转义引号,所以我会遇到语法错误.

I've tried disabling emulated prepares in PDO but I cannot get it to work. Everything else works. The query is successful. The reason I believe it's not working is because it does not escape quotes and such so I get syntax errors.

我尝试过两种不同的方式.

I've tried doing it two different ways.

$this->dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

$insert = $database->$con->prepare($insert, array(PDO::ATTR_EMULATE_PREPARES => false));

我还注意到getAttribute不起作用.

I've also noticed that getAttribute does not work.

通过此操作...

    $emul = $database->$con->getAttribute(PDO::ATTR_EMULATE_PREPARES);
    var_dump($emul);

...我收到此错误

SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute

这是发生操作的我的数据库类. (在测试时,我可能在其中留下了一些不必要的/愚蠢的代码.)

And here's my database class where the action happens. (I might have left some unneccessary/stupid code in there while I was testing.)

<?php
class Database
{
    public $dbh;
    public $dbh1;
    public $dbh2;
    private static $instance;

    public $numResults;
    private $result = array();          // Results that are returned from the query

    public function __construct()
    {
        try
        {
            $this->dbh = new PDO(DB_TYPE.':host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8', DB_USER, DB_PASS);
            $this->dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

            $this->dbh1 = new PDO(DB_TYPE1.':host='.DB_HOST1.';dbname='.DB_NAME1.';charset=utf8', DB_USER1, DB_PASS1);
            $this->dbh1->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            $this->dbh1->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

            $this->dbh2 = new PDO(DB_TYPE2.':host='.DB_HOST2.';dbname='.DB_NAME2.';charset=utf8', DB_USER2, DB_PASS2);
            $this->dbh2->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            $this->dbh2->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
        catch (PDOException $e)
        {
            die("Database Error: ". $e->getMessage() . "<br />");

        }
    }

    public static function getInstance()
    {
        if (!isset(self::$instance))
        {
            $object = __CLASS__;
            self::$instance = new $object;
        }
        return self::$instance;
    }

    private function tableExists($table, $con)
    {
        switch($con)
        {
            case 'dbh':
            $db_name = DB_NAME;
            break;
            case 'dbh1':
            $db_name = DB_NAME1;
            break;
            case 'dbh2':
            $db_name = DB_NAME2;
            break;
        }

        $database = Database::getInstance();

        if(is_array($table))
        {
            for($i = 0; $i < count($table); $i++)
            {
                $tablesInDb = $database->$con->prepare('SHOW TABLES FROM '.$db_name.' LIKE "'.$table[$i].'"');
                $tablesInDb->execute();
                $rowCount = $tablesInDb->rowCount();

                if($tablesInDb)
                {
                    if($rowCount <> 1)
                    {
                        die('Error: Table does not exist'.$table[$i]);
                    }
                }
            }
        }else
        {
            $tablesInDb = $database->$con->prepare('SHOW TABLES FROM '.$db_name.' LIKE "'.$table.'"');
            $tablesInDb->execute();
            $rowCount = $tablesInDb->rowCount();

            if($tablesInDb)
            {
                if($rowCount <> 1)
                {
                    die('Error: Table does not exist'.$table);
                }
            }
        }

        return true;
    }

    public function insert($con, $table, $values, $cols = null)
    {
        if($this->tableExists($table, $con))
        {
            $insert = 'INSERT INTO '.$table;

            if($cols != null)
            {
                $cols = implode(',', $cols);
                $insert.= '('.$cols.')';
            }

            for($i = 0; $i < count($values); $i++)
            {
                if(is_string($values[$i]))
                    $values[$i] = "'".$values[$i]."'";
            }

            $values = implode(',', $values);
            $insert .= ' VALUES ('.$values.')';

            $database = Database::getInstance();
            $insert = $database->$con->prepare($insert, array(PDO::ATTR_EMULATE_PREPARES => false));
            $insert->execute();

            if($insert)
            {
                return true;
            }else
            {
                return false;
            }
        }
    }

    public function getResult()
    {
        return $this->result;
    }
}

?>

推荐答案

  1. 由于手册状态,getAttribute()不支持ATTR_EMULATE_PREPARES
  2. 不应该完全逃避本地准备工作.
  3. 要检查您是否处于仿真模式,可以使用带有懒惰绑定的LIMIT子句.如果打开仿真,将引发错误.
  4. 您的主要问题是您提到的任何语法错误",您必须首先解决它.
  5. 正如ÁlvaroG. Vicario在评论中指出的那样,您未使用准备好的语句.这显然是问题的根源. PDO不会自行转义"您的数据.仅当您使用占位符表示查询中的数据时,它才能执行此操作.您可以在此处
  6. 阅读更多内容.
  1. As manual states, getAttribute() don't support ATTR_EMULATE_PREPARES
  2. There shouldn't be no escaping with native prepares at all.
  3. To check if you are in emulation mode or not you can use LIMIT clause with lazy binding. It will raise an error if emulation is on.
  4. Your main problem is whatever "syntax error" you mentioned and you have to solve it first.
  5. As Álvaro G. Vicario noted in comments, you are not using prepared statements. It is apparently the root of the problem. PDO doesn't "escape" your data by itself. It can do it only if you are using placeholders to represent your data in the query. You can read more here

这篇关于将PDO :: ATTR_EMULATE_PREPARES设置为false无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆