0

PDO で bindParam または bindValue のいずれかを使用する場合、「バインディング」は PDOStatement オブジェクトのどこに格納されますか? この設定されたプロパティ/参照/などを表示することは可能ですか?

これらおよび他の PDOStatement メソッドが PDOStatement オブジェクト内でデータを格納/配置する場所を理解しようとしています (PDOStatement メソッドを介して設定する以外にアクセスすることさえ可能であれば)。

(この質問は、他の PDO/PDOStatement メソッドにも及ぶと思います。また、プロパティやその他のもののように、物がどこに保存されているのか興味があります)

4

1 に答える 1

1

準備済みステートメントは、プロトコル機能 (mysql など) であるか、舞台裏で C ライブラリで実行されます。つまり、ステートメントを解析する作業は PDO コードによって行われません。これは、データベース サーバーまたは libsqlite のような C ライブラリによって行われます。PDO はそれ自体でステートメントを解析せず、それを下位レベルのコンポーネントに渡すだけなので、param 情報は使用できません。

そのため、プレーンな PHPを使用すると、PDOStatement オブジェクトを使用したクエリで関連付けプレースホルダー => 値に置き換えられません。これは、準備済みステートメントの設計によるものです。

PDOStatement回避策として、param プレースホルダーを現在のクエリ文字列の値で置き換えるメソッドを拡張して追加することが考えられます。以下に例を用意しました。この例は:bar、引用符で囲まれた文字列で発生した場合でも置換されるため、防弾ではないことに注意してください。しかし、内部で使用する場合、このようなソリューションはこれまでのところ私にとって良い仕事をしてくれました.

カスタム ステートメント クラス:

class MyStatement extends PDOStatement
{

    protected $params;
    protected $pdo;

    protected function __construct($pdo) {
        $this->pdo = $pdo;
    }

    public function execute($params = null) {
        $this->params = $params;
        return parent::execute($params);
    }


    public function printQuery(){
        $_params = $this->params;
        $sql = $this->queryString;
        foreach($this->params as $key => $value) {
            $_value = is_null($value) ?
                'NULL' : '\'' . $value . '\'';
            $sql = str_replace(':'. $key, $_value, $sql);
        }
        return $sql;
    }
}

変更された PDO が必要です:

class MyPDO extends PDO
{

    public function __construct($dsn, $username="", $password="", $driver_options=array()) {
        parent::__construct($dsn, $username, $password, array(
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_STATEMENT_CLASS => array('MyStatement', array($this))
        ));
    }
}

テストコード:

$pdo = new MyPDO('mysql:host=localhost;dbname=test', 'root', '******');

// preapre stupid query
$stmt = $pdo->prepare('SELECT FROM `foo` WHERE name = :bar');

try {
    // execute stmt
    $stmt->execute(array('bar' => 'hek2mgl'));
} catch (PDOException $e) {
    echo $stmt->printQuery();
}
于 2013-07-17T21:43:40.740 に答える