Warum sind diese beiden PDO-Klassen unterschiedlich (und wie kann ich sie gleich machen)?

Warum sind diese beiden PDO-Klassen unterschiedlich (und wie kann ich sie gleich machen)?

Ich habe einen webbasierten PHP-E-Mail-Client (Runder Würfel), das ich auf einem UNIX-Server installiert habe, und sofort wurde dieser Fehler angezeigt:

Fatal error: Undefined class constant 'MYSQL_ATTR_FOUND_ROWS' in /path/to/file.php on line 134

Es ist diese Codezeile:

$result[PDO::MYSQL_ATTR_FOUND_ROWS] = true;

Lokal funktioniert es auf meiner Windows-Installation einwandfrei, daher habe ich die beiden PDO-Klassen folgendermaßen verglichen:

<?php ReflectionClass::export('PDO');

Die MYSQL_ATTR_FOUND_ROWSEigenschaft und einige andere waren auf dem Live-UNIX-Server nicht vorhanden. Ich habe einen schnellen Patch durchgeführt, indem ich den unbekannten Wert fest codiert habe, und es hat gut funktioniert, aber ich kann nicht sicher sein, dass es nicht noch mehr Fehler gibt (und wir möchten sowieso keine gehackte Version verwenden).

Die PDO-Klasse ist definitiv geladen, wir mussten sie eigentlich aktivieren, um Roundcube überhaupt mit der MySQL/PDO-Option installieren zu können. Ich vermute, die PDO-Klasse des Live-Servers muss aktualisiert werden. Ich habe keine direkte Kontrolle über den Live-Server, aber ich kann demjenigen, der sie hat, Anweisungen geben. Kann mir jemand helfen, herauszufinden, was getan werden muss?

Hier sind die Statistiken:


Lokaler Windows Apache-Server (funktioniert), PHP-Version 5.3.8

PDO-Klasse-Debug-Ausgabe:

Class [ <internal:PDO> class PDO ] {

  - Constants [86] {
    Constant [ integer PARAM_BOOL ] { 5 }
    Constant [ integer PARAM_NULL ] { 0 }
    Constant [ integer PARAM_INT ] { 1 }
    Constant [ integer PARAM_STR ] { 2 }
    Constant [ integer PARAM_LOB ] { 3 }
    Constant [ integer PARAM_STMT ] { 4 }
    Constant [ integer PARAM_INPUT_OUTPUT ] { -2147483648 }
    Constant [ integer PARAM_EVT_ALLOC ] { 0 }
    Constant [ integer PARAM_EVT_FREE ] { 1 }
    Constant [ integer PARAM_EVT_EXEC_PRE ] { 2 }
    Constant [ integer PARAM_EVT_EXEC_POST ] { 3 }
    Constant [ integer PARAM_EVT_FETCH_PRE ] { 4 }
    Constant [ integer PARAM_EVT_FETCH_POST ] { 5 }
    Constant [ integer PARAM_EVT_NORMALIZE ] { 6 }
    Constant [ integer FETCH_LAZY ] { 1 }
    Constant [ integer FETCH_ASSOC ] { 2 }
    Constant [ integer FETCH_NUM ] { 3 }
    Constant [ integer FETCH_BOTH ] { 4 }
    Constant [ integer FETCH_OBJ ] { 5 }
    Constant [ integer FETCH_BOUND ] { 6 }
    Constant [ integer FETCH_COLUMN ] { 7 }
    Constant [ integer FETCH_CLASS ] { 8 }
    Constant [ integer FETCH_INTO ] { 9 }
    Constant [ integer FETCH_FUNC ] { 10 }
    Constant [ integer FETCH_GROUP ] { 65536 }
    Constant [ integer FETCH_UNIQUE ] { 196608 }
    Constant [ integer FETCH_KEY_PAIR ] { 12 }
    Constant [ integer FETCH_CLASSTYPE ] { 262144 }
    Constant [ integer FETCH_SERIALIZE ] { 524288 }
    Constant [ integer FETCH_PROPS_LATE ] { 1048576 }
    Constant [ integer FETCH_NAMED ] { 11 }
    Constant [ integer ATTR_AUTOCOMMIT ] { 0 }
    Constant [ integer ATTR_PREFETCH ] { 1 }
    Constant [ integer ATTR_TIMEOUT ] { 2 }
    Constant [ integer ATTR_ERRMODE ] { 3 }
    Constant [ integer ATTR_SERVER_VERSION ] { 4 }
    Constant [ integer ATTR_CLIENT_VERSION ] { 5 }
    Constant [ integer ATTR_SERVER_INFO ] { 6 }
    Constant [ integer ATTR_CONNECTION_STATUS ] { 7 }
    Constant [ integer ATTR_CASE ] { 8 }
    Constant [ integer ATTR_CURSOR_NAME ] { 9 }
    Constant [ integer ATTR_CURSOR ] { 10 }
    Constant [ integer ATTR_ORACLE_NULLS ] { 11 }
    Constant [ integer ATTR_PERSISTENT ] { 12 }
    Constant [ integer ATTR_STATEMENT_CLASS ] { 13 }
    Constant [ integer ATTR_FETCH_TABLE_NAMES ] { 14 }
    Constant [ integer ATTR_FETCH_CATALOG_NAMES ] { 15 }
    Constant [ integer ATTR_DRIVER_NAME ] { 16 }
    Constant [ integer ATTR_STRINGIFY_FETCHES ] { 17 }
    Constant [ integer ATTR_MAX_COLUMN_LEN ] { 18 }
    Constant [ integer ATTR_EMULATE_PREPARES ] { 20 }
    Constant [ integer ATTR_DEFAULT_FETCH_MODE ] { 19 }
    Constant [ integer ERRMODE_SILENT ] { 0 }
    Constant [ integer ERRMODE_WARNING ] { 1 }
    Constant [ integer ERRMODE_EXCEPTION ] { 2 }
    Constant [ integer CASE_NATURAL ] { 0 }
    Constant [ integer CASE_LOWER ] { 2 }
    Constant [ integer CASE_UPPER ] { 1 }
    Constant [ integer NULL_NATURAL ] { 0 }
    Constant [ integer NULL_EMPTY_STRING ] { 1 }
    Constant [ integer NULL_TO_STRING ] { 2 }
    Constant [ string ERR_NONE ] { 00000 }
    Constant [ integer FETCH_ORI_NEXT ] { 0 }
    Constant [ integer FETCH_ORI_PRIOR ] { 1 }
    Constant [ integer FETCH_ORI_FIRST ] { 2 }
    Constant [ integer FETCH_ORI_LAST ] { 3 }
    Constant [ integer FETCH_ORI_ABS ] { 4 }
    Constant [ integer FETCH_ORI_REL ] { 5 }
    Constant [ integer CURSOR_FWDONLY ] { 0 }
    Constant [ integer CURSOR_SCROLL ] { 1 }
    Constant [ integer MYSQL_ATTR_USE_BUFFERED_QUERY ] { 1000 }
    Constant [ integer MYSQL_ATTR_LOCAL_INFILE ] { 1001 }
    Constant [ integer MYSQL_ATTR_INIT_COMMAND ] { 1002 }
    Constant [ integer MYSQL_ATTR_DIRECT_QUERY ] { 1003 }
    Constant [ integer MYSQL_ATTR_FOUND_ROWS ] { 1004 }
    Constant [ integer MYSQL_ATTR_IGNORE_SPACE ] { 1005 }
    Constant [ integer MYSQL_ATTR_SSL_KEY ] { 1006 }
    Constant [ integer MYSQL_ATTR_SSL_CERT ] { 1007 }
    Constant [ integer MYSQL_ATTR_SSL_CA ] { 1008 }
    Constant [ integer MYSQL_ATTR_SSL_CAPATH ] { 1009 }
    Constant [ integer MYSQL_ATTR_SSL_CIPHER ] { 1010 }
    Constant [ integer ODBC_ATTR_USE_CURSOR_LIBRARY ] { 1000 }
    Constant [ integer ODBC_ATTR_ASSUME_UTF8 ] { 1001 }
    Constant [ integer ODBC_SQL_USE_IF_NEEDED ] { 0 }
    Constant [ integer ODBC_SQL_USE_DRIVER ] { 2 }
    Constant [ integer ODBC_SQL_USE_ODBC ] { 1 }
  }

  - Static properties [0] {
  }

  - Static methods [1] {
    Method [ <internal:PDO> static public method getAvailableDrivers ] {

      - Parameters [0] {
      }
    }
  }

  - Properties [0] {
  }

  - Methods [16] {
    Method [ <internal:PDO, ctor> public method __construct ] {

      - Parameters [4] {
        Parameter #0 [ <required> $dsn ]
        Parameter #1 [ <required> $username ]
        Parameter #2 [ <required> $passwd ]
        Parameter #3 [ <optional> $options ]
      }
    }

    Method [ <internal:PDO> public method prepare ] {

      - Parameters [2] {
        Parameter #0 [ <required> $statment ]
        Parameter #1 [ <optional> $options ]
      }
    }

    Method [ <internal:PDO> public method beginTransaction ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> public method commit ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> public method rollBack ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> public method inTransaction ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> public method setAttribute ] {

      - Parameters [2] {
        Parameter #0 [ <required> $attribute ]
        Parameter #1 [ <required> $value ]
      }
    }

    Method [ <internal:PDO> public method exec ] {

      - Parameters [1] {
        Parameter #0 [ <required> $query ]
      }
    }

    Method [ <internal:PDO> public method query ] {
    }

    Method [ <internal:PDO> public method lastInsertId ] {

      - Parameters [1] {
        Parameter #0 [ <optional> $seqname ]
      }
    }

    Method [ <internal:PDO> public method errorCode ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> public method errorInfo ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> public method getAttribute ] {

      - Parameters [1] {
        Parameter #0 [ <required> $attribute ]
      }
    }

    Method [ <internal:PDO> public method quote ] {

      - Parameters [2] {
        Parameter #0 [ <required> $string ]
        Parameter #1 [ <optional> $paramtype ]
      }
    }

    Method [ <internal:PDO> final public method __wakeup ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> final public method __sleep ] {

      - Parameters [0] {
      }
    }
  }
}

Live-UNIX-Apache-Server (funktioniert nicht), PHP-Version 5.3.18

PDO-Klasse-Debug-Ausgabe:

Class [ <internal:PDO> class PDO ] {

  - Constants [77] {
    Constant [ integer PARAM_BOOL ] { 5 }
    Constant [ integer PARAM_NULL ] { 0 }
    Constant [ integer PARAM_INT ] { 1 }
    Constant [ integer PARAM_STR ] { 2 }
    Constant [ integer PARAM_LOB ] { 3 }
    Constant [ integer PARAM_STMT ] { 4 }
    Constant [ integer PARAM_INPUT_OUTPUT ] { -2147483648 }
    Constant [ integer PARAM_EVT_ALLOC ] { 0 }
    Constant [ integer PARAM_EVT_FREE ] { 1 }
    Constant [ integer PARAM_EVT_EXEC_PRE ] { 2 }
    Constant [ integer PARAM_EVT_EXEC_POST ] { 3 }
    Constant [ integer PARAM_EVT_FETCH_PRE ] { 4 }
    Constant [ integer PARAM_EVT_FETCH_POST ] { 5 }
    Constant [ integer PARAM_EVT_NORMALIZE ] { 6 }
    Constant [ integer FETCH_LAZY ] { 1 }
    Constant [ integer FETCH_ASSOC ] { 2 }
    Constant [ integer FETCH_NUM ] { 3 }
    Constant [ integer FETCH_BOTH ] { 4 }
    Constant [ integer FETCH_OBJ ] { 5 }
    Constant [ integer FETCH_BOUND ] { 6 }
    Constant [ integer FETCH_COLUMN ] { 7 }
    Constant [ integer FETCH_CLASS ] { 8 }
    Constant [ integer FETCH_INTO ] { 9 }
    Constant [ integer FETCH_FUNC ] { 10 }
    Constant [ integer FETCH_GROUP ] { 65536 }
    Constant [ integer FETCH_UNIQUE ] { 196608 }
    Constant [ integer FETCH_KEY_PAIR ] { 12 }
    Constant [ integer FETCH_CLASSTYPE ] { 262144 }
    Constant [ integer FETCH_SERIALIZE ] { 524288 }
    Constant [ integer FETCH_PROPS_LATE ] { 1048576 }
    Constant [ integer FETCH_NAMED ] { 11 }
    Constant [ integer ATTR_AUTOCOMMIT ] { 0 }
    Constant [ integer ATTR_PREFETCH ] { 1 }
    Constant [ integer ATTR_TIMEOUT ] { 2 }
    Constant [ integer ATTR_ERRMODE ] { 3 }
    Constant [ integer ATTR_SERVER_VERSION ] { 4 }
    Constant [ integer ATTR_CLIENT_VERSION ] { 5 }
    Constant [ integer ATTR_SERVER_INFO ] { 6 }
    Constant [ integer ATTR_CONNECTION_STATUS ] { 7 }
    Constant [ integer ATTR_CASE ] { 8 }
    Constant [ integer ATTR_CURSOR_NAME ] { 9 }
    Constant [ integer ATTR_CURSOR ] { 10 }
    Constant [ integer ATTR_ORACLE_NULLS ] { 11 }
    Constant [ integer ATTR_PERSISTENT ] { 12 }
    Constant [ integer ATTR_STATEMENT_CLASS ] { 13 }
    Constant [ integer ATTR_FETCH_TABLE_NAMES ] { 14 }
    Constant [ integer ATTR_FETCH_CATALOG_NAMES ] { 15 }
    Constant [ integer ATTR_DRIVER_NAME ] { 16 }
    Constant [ integer ATTR_STRINGIFY_FETCHES ] { 17 }
    Constant [ integer ATTR_MAX_COLUMN_LEN ] { 18 }
    Constant [ integer ATTR_EMULATE_PREPARES ] { 20 }
    Constant [ integer ATTR_DEFAULT_FETCH_MODE ] { 19 }
    Constant [ integer ERRMODE_SILENT ] { 0 }
    Constant [ integer ERRMODE_WARNING ] { 1 }
    Constant [ integer ERRMODE_EXCEPTION ] { 2 }
    Constant [ integer CASE_NATURAL ] { 0 }
    Constant [ integer CASE_LOWER ] { 2 }
    Constant [ integer CASE_UPPER ] { 1 }
    Constant [ integer NULL_NATURAL ] { 0 }
    Constant [ integer NULL_EMPTY_STRING ] { 1 }
    Constant [ integer NULL_TO_STRING ] { 2 }
    Constant [ string ERR_NONE ] { 00000 }
    Constant [ integer FETCH_ORI_NEXT ] { 0 }
    Constant [ integer FETCH_ORI_PRIOR ] { 1 }
    Constant [ integer FETCH_ORI_FIRST ] { 2 }
    Constant [ integer FETCH_ORI_LAST ] { 3 }
    Constant [ integer FETCH_ORI_ABS ] { 4 }
    Constant [ integer FETCH_ORI_REL ] { 5 }
    Constant [ integer CURSOR_FWDONLY ] { 0 }
    Constant [ integer CURSOR_SCROLL ] { 1 }
    Constant [ integer MYSQL_ATTR_USE_BUFFERED_QUERY ] { 1000 }
    Constant [ integer MYSQL_ATTR_LOCAL_INFILE ] { 1001 }
    Constant [ integer MYSQL_ATTR_INIT_COMMAND ] { 1002 }
    Constant [ integer MYSQL_ATTR_READ_DEFAULT_FILE ] { 1003 }
    Constant [ integer MYSQL_ATTR_READ_DEFAULT_GROUP ] { 1004 }
    Constant [ integer MYSQL_ATTR_MAX_BUFFER_SIZE ] { 1005 }
    Constant [ integer MYSQL_ATTR_DIRECT_QUERY ] { 1006 }
  }

  - Static properties [0] {
  }

  - Static methods [1] {
    Method [ <internal:PDO> static public method getAvailableDrivers ] {

      - Parameters [0] {
      }
    }
  }

  - Properties [0] {
  }

  - Methods [16] {
    Method [ <internal:PDO, ctor> public method __construct ] {

      - Parameters [4] {
        Parameter #0 [ <required> $dsn ]
        Parameter #1 [ <required> $username ]
        Parameter #2 [ <required> $passwd ]
        Parameter #3 [ <optional> $options ]
      }
    }

    Method [ <internal:PDO> public method prepare ] {

      - Parameters [2] {
        Parameter #0 [ <required> $statment ]
        Parameter #1 [ <optional> $options ]
      }
    }

    Method [ <internal:PDO> public method beginTransaction ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> public method commit ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> public method rollBack ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> public method inTransaction ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> public method setAttribute ] {

      - Parameters [2] {
        Parameter #0 [ <required> $attribute ]
        Parameter #1 [ <required> $value ]
      }
    }

    Method [ <internal:PDO> public method exec ] {

      - Parameters [1] {
        Parameter #0 [ <required> $query ]
      }
    }

    Method [ <internal:PDO> public method query ] {
    }

    Method [ <internal:PDO> public method lastInsertId ] {

      - Parameters [1] {
        Parameter #0 [ <optional> $seqname ]
      }
    }

    Method [ <internal:PDO> public method errorCode ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> public method errorInfo ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> public method getAttribute ] {

      - Parameters [1] {
        Parameter #0 [ <required> $attribute ]
      }
    }

    Method [ <internal:PDO> public method quote ] {

      - Parameters [2] {
        Parameter #0 [ <required> $string ]
        Parameter #1 [ <optional> $paramtype ]
      }
    }

    Method [ <internal:PDO> final public method __wakeup ] {

      - Parameters [0] {
      }
    }

    Method [ <internal:PDO> final public method __sleep ] {

      - Parameters [0] {
      }
    }
  }
}

Hier sind Links zu Pasties der php.ini-Datei (der Inhalt war zu groß, um ihn diesem Beitrag hinzuzufügen):Teil 1,Teil 2


Was müssen wir mindestens tun, um diese fehlenden Eigenschaften in die PDO-Bibliothek des Live-Servers zu bekommen? Was ist hier überhaupt los, warum sind sie so unterschiedlich?

Antwort1

Sie haben mich also gezwungen, mein PHP neu zu erstellenohne mysqlnd(wie Ihr Build, nur mitlibmysql-Backend), um meine Theorie zu überprüfen. Zum Glück habe ich eine Gentoo-Installation, mit der ich das schnell erledigen kann!

Wie ich erwartet habe, gibt es ohne mysqlnd KEINEPDO::MYSQL_*Konstanten in der PDO-Klasse überhaupt. Um sie an die richtige Stelle zu bringen, sollten Sie mysqlnd verwenden: Kompilieren Sie entweder PHP neu oder holen Sie sich möglicherweise eine Erweiterung pdo_mysqlnd.so (oder php_mysql.so, das gegen mysqlnd gebaut wurde) und laden Sie sie.

Die Windows-PHP-Binärdatei scheint mit mysqlnd kompiliert worden zu sein.

Übrigens ist mysqlnd ab PHP 5.4.0 das Standard-Backend.

Antwort2

Die fehlende Konstante wird deklariert inext/pdo_mysql/pdo_mysql.c, das je nach System in einem der folgenden Module verfügbar ist:

  • pdo_mysqlnd.so
  • pdo_mysql.so

Beim Ausführen php -mkönnen Sie sehen, ob eines dieser Module tatsächlich geladen ist. Sie würden nach dem pdo_mysqlModul suchen.

So kompilieren Sie das Modul mysqlndin die PHP-Binärdatei selbst:

./config.nice --enable-mysqlnd --with-pdo-mysql=mysqlnd
make && make install

verwandte Informationen