]> granicus.if.org Git - php/commitdiff
- MFH: Fixed bug #46292 (PDO::setFetchMode() shouldn't requires the 2nd arg when...
authorFelipe Pena <felipe@php.net>
Tue, 14 Oct 2008 17:43:20 +0000 (17:43 +0000)
committerFelipe Pena <felipe@php.net>
Tue, 14 Oct 2008 17:43:20 +0000 (17:43 +0000)
NEWS
ext/pdo/pdo_stmt.c
ext/pdo_mysql/tests/bug46292.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 25191ddeedf38139cd6db066d524ee7f953d4135..b25595e5768271e7459502e9a2f27198f25aa204 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 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))
index 17e7687c89f6b086c95ef4637df1045800d66567..145e318084368f4f4c50a85983076776c3fbe26b 100755 (executable)
@@ -1922,7 +1922,7 @@ static PHP_METHOD(PDOStatement, getColumnMeta)
 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;
        
@@ -1955,6 +1955,7 @@ fail_out:
        
        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);
@@ -1982,21 +1983,30 @@ fail_out:
                        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) {
diff --git a/ext/pdo_mysql/tests/bug46292.phpt b/ext/pdo_mysql/tests/bug46292.phpt
new file mode 100644 (file)
index 0000000..df66dbb
--- /dev/null
@@ -0,0 +1,80 @@
+--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
+  }
+}