将PDO :: ATTR_EMULATE_PREPARES设置为false不起作用

时间:2013-04-28 16:03:32

标签: php mysql pdo

我已经尝试在PDO中禁用模拟准备,但我无法让它工作。其他一切都有效。查询成功。我认为它不起作用的原因是因为它没有逃避引号等因此我得到了语法错误。

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

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

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

我也注意到getAttribute不起作用。

这样做......

    $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

这是我的数据库类,其中包含动作。 (在我测试时,我可能在那里留下了一些不必要的/愚蠢的代码。)

<?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 个答案:

答案 0 :(得分:1)

  1. 正如manual所述,getAttribute()不支持ATTR_EMULATE_PREPARES
  2. 根本不应该有本地准备逃脱。
  3. 要检查您是否处于仿真模式,可以使用LIMIT clause with lazy binding。如果启用仿真,则会引发错误。
  4. 你的主要问题是你提到的“语法错误”,你必须先解决它。
  5. 正如ÁlvaroG。Vicario在评论中指出的那样,您没有使用准备好的陈述。这显然是问题的根源。 PDO本身并不“逃避”您的数据。只有在使用占位符在查询中表示数据时,它才能执行此操作。您可以阅读更多here