1

我尝试在 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;
    }
}

?>
4

1 回答 1

1
  1. 手册所述,getAttribute()不支持ATTR_EMULATE_PREPARES
  2. 根本不应该使用原生准备来逃避。
  3. 要检查您是否处于仿真模式,您可以使用带有惰性绑定的 LIMIT 子句。如果仿真打开,它将引发错误。
  4. 您的主要问题是您提到的任何“语法错误”,您必须先解决它。
  5. 正如 Álvaro G. Vicario 在评论中指出的那样,您没有使用准备好的语句。这显然是问题的根源。PDO 不会自行“转义”您的数据。只有当您使用占位符在查询中表示您的数据时,它才能做到这一点。你可以在这里阅读更多
于 2013-04-28T16:27:32.863 回答