PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? Oct 2008, PHP 5.2.7RC2
+- Fixed bug #46292 (PDO::setFetchMode() shouldn't requires the 2nd arg when
+ using FETCH_CLASSTYPE). (Felipe)
- Fixed bug #46274, #46249 (pdo_pgsql always fill in NULL for empty BLOB and
segfaults when returned by SELECT). (Felipe)
- Fixed bug #46246 (difference between call_user_func(array($this, $method))
int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, int skip)
{
long mode = PDO_FETCH_BOTH;
- int argc = ZEND_NUM_ARGS() - skip;
+ int flags, argc = ZEND_NUM_ARGS() - skip;
zval ***args;
zend_class_entry **cep;
convert_to_long_ex(args[skip]);
mode = Z_LVAL_PP(args[skip]);
+ flags = mode & PDO_FETCH_FLAGS;
if (!pdo_stmt_verify_mode(stmt, mode, 0 TSRMLS_CC)) {
efree(args);
break;
case PDO_FETCH_CLASS:
- if (argc < 2 || argc > 3) {
- goto fail_out;
- }
- convert_to_string_ex(args[skip+1]);
-
- if (FAILURE == zend_lookup_class(Z_STRVAL_PP(args[skip+1]),
- Z_STRLEN_PP(args[skip+1]), &cep TSRMLS_CC)) {
- goto fail_out;
- }
+ /* Gets its class name from 1st column */
+ if ((flags & PDO_FETCH_CLASSTYPE) == PDO_FETCH_CLASSTYPE) {
+ if (argc != 1) {
+ goto fail_out;
+ }
+ stmt->fetch.cls.ce = NULL;
+ } else {
+ if (argc < 2 || argc > 3) {
+ goto fail_out;
+ }
+ convert_to_string_ex(args[skip+1]);
- if (!cep || !*cep) {
- goto fail_out;
+ if (FAILURE == zend_lookup_class(Z_STRVAL_PP(args[skip+1]),
+ Z_STRLEN_PP(args[skip+1]), &cep TSRMLS_CC)) {
+ goto fail_out;
+ }
+
+ if (!cep || !*cep) {
+ goto fail_out;
+ }
+
+ stmt->fetch.cls.ce = *cep;
}
-
- stmt->fetch.cls.ce = *cep;
+
stmt->fetch.cls.ctor_args = NULL;
#ifdef ilia_0 /* we'll only need this when we have persistent statements, if ever */
if (stmt->dbh->is_persistent) {
--- /dev/null
+--TEST--
+Bug #46292 (PDO::setFetchMode() shouldn't requires the 2nd arg when using FETCH_CLASSTYPE)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+ require dirname(__FILE__) . '/config.inc';
+ require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+
+ $pdoDb = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+
+
+ class myclass implements Serializable {
+ public function __construct() {
+ printf("%s()\n", __METHOD__);
+ }
+
+ public function serialize() {
+ printf("%s()\n", __METHOD__);
+ return "any data from serialize()";
+ }
+
+ public function unserialize($dat) {
+ printf("%s(%s)\n", __METHOD__, var_export($dat, true));
+ return $dat;
+ }
+ }
+
+ class myclass2 extends myclass { }
+
+ $pdoDb->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
+
+ $pdoDb->query('DROP TABLE IF EXISTS testz');
+
+ $pdoDb->query('CREATE TABLE testz (name VARCHAR(20) NOT NULL, value INT)');
+
+ $pdoDb->query("INSERT INTO testz VALUES ('myclass', 1), ('myclass2', 2), ('myclass', NULL), ('myclass3', NULL)");
+
+ $stmt = $pdoDb->prepare("SELECT * FROM testz");
+
+ var_dump($stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE | PDO::FETCH_GROUP));
+ $stmt->execute();
+
+ var_dump($stmt->fetch());
+ var_dump($stmt->fetch());
+ var_dump($stmt->fetchAll());
+
+ $pdoDb->query('DROP TABLE IF EXISTS testz');
+
+?>
+--EXPECTF--
+bool(true)
+myclass::__construct()
+object(myclass)#%d (1) {
+ ["value"]=>
+ string(1) "1"
+}
+myclass::__construct()
+object(myclass2)#%d (1) {
+ ["value"]=>
+ string(1) "2"
+}
+myclass::__construct()
+array(2) {
+ [0]=>
+ object(myclass)#%d (1) {
+ ["value"]=>
+ NULL
+ }
+ [1]=>
+ object(stdClass)#%d (1) {
+ ["value"]=>
+ NULL
+ }
+}