簡體   English   中英

PHP Postgres PDO驅動程序不支持預處理語句?

[英]PHP Postgres PDO driver does not support prepared statement?

我是否會失去理智,或者Postgres PDO驅動程序是否不支持預備語句,而是模仿客戶端?

以下代碼為prepare()調用返回NO ERROR,即使它應該。 相反,它在調用execute()時返回適用的錯誤。

編輯:因為根據DanielVérité我錯了,我添加了他建議的代碼。 我仍然得到錯誤。 我的代碼現在看起來如下,添加了Daniel的行。

<?php
$pdo = new PDO("pgsql:host=myhost;dbname=mydatabase");

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);  // as suggested by Daniel

$sth = $pdo->prepare('COMPLETE GARBAGE');
echo "[prepare] errorInfo = " . print_r($sth->errorInfo(), true);

$sth->execute();
echo "[execute] errorInfo = " . print_r($sth->errorInfo(), true);

PHP版本5.3.15,PHP Postgres客戶端版本9.1.4,Postgres服務器版本9.2.1。

http://www.php.net/manual/en/pdo.prepare.php

注意:

模擬的預准備語句不與數據庫服務器通信,因此PDO :: prepare()不檢查語句。

(事實上​​,無論如何都不會立即發送真實的預備聲明,請參閱下面的Q2答案)

無論如何你可以發出:

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

獲取使用SQL PREPARE命令實現的實際預准備語句。 有關更多信息,請參見http://www.php.net/manual/en/pdo.setattribute.php

在進一步的討論和測試中,出現了兩個問題:

Q1。 為什么pdo::getAttribute(PDO::ATTR_EMULATE_PREPARES)產生錯誤?
事實上, setAttribute不會出錯,但getAttribute(PDO::ATTR_EMULATE_PREPARES)說:

'SQLSTATE [IM001]:驅動程序不支持此功能:驅動程序不支持該屬性'

查看pdo :: getAttribute文檔 ,它說適用於數據庫連接的常量如下 ,並且從PDO::ATTR_AUTOCOMMITPDO::ATTR_TIMEOUT有許多常量,並且值得注意的是PDO::ATTR_EMULATE_PREPARES 不是在他們 嚴格來說,我們不應該期望getAttribute(PDO::ATTR_EMULATE_PREPARES)能夠正常工作。

現在查看源代碼以確定,似乎pdo_pgsql驅動程序提供了一個pdo_pgsql_get_attribute函數,該函數具有以下的switch語句:

  • PDO_ATTR_CLIENT_VERSION
  • PDO_ATTR_SERVER_VERSION
  • PDO_ATTR_CONNECTION_STATUS
  • PDO_ATTR_SERVER_INFO

就是這樣。 沒有PDO_ATTR_EMULATE_PREPARES的痕跡,這就是最終出現此錯誤的原因。

另一方面,函數pdo_pgsql_set_attr有一個switch語句:

  • PDO_ATTR_EMULATE_PREPARES
  • PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT

這確認了設置時實際考慮了該屬性。 所以PDO就是不一致getAttribute不匹配setAttribute

Q2 - 當准備仿真為假時,為什么偽造的聲明在准備好后不會立即引發錯誤?

考慮pgsql_statement.c這段代碼:

        if (!S->is_prepared) {
stmt_retry:
            /* we deferred the prepare until now, because we didn't
             * know anything about the parameter types; now we do */
            S->result = PQprepare(H->server, S->stmt_name, S->query, 
                        stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0,
                        S->param_types);

它表明使用了PQprepare (這是一個“真正的”預處理語句),但是該語句也沒有立即發送到服務器。 這就是為什么dbo::prepare("bogus statement")不會返回false:實際上由於缺少參數類型而沒有發送到服務器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM