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

index 40967500c757c019ff6d7d729d7718cd05b16305..41b87baa02516ab7e6954420162777a101687c8c 100755 (executable)
@@ -1939,7 +1939,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;
        
@@ -1972,6 +1972,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);
@@ -1999,21 +2000,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 */
diff --git a/ext/pdo_mysql/tests/bug46292.phpt b/ext/pdo_mysql/tests/bug46292.phpt
new file mode 100644 (file)
index 0000000..11e2d6f
--- /dev/null
@@ -0,0 +1,72 @@
+--TEST--
+Bug #46292 (PDO::setFetchMode() shouldn't requires the 2nd arg when using FETCH_CLASSTYPE)
+--FILE--
+<?php  
+       
+       require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+       $pdoDb = MySQLPDOTest::factory();
+       
+
+       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)#3 (1) {
+  ["value"]=>
+  string(1) "1"
+}
+myclass::__construct()
+object(myclass2)#3 (1) {
+  ["value"]=>
+  string(1) "2"
+}
+myclass::__construct()
+array(2) {
+  [0]=>
+  object(myclass)#3 (1) {
+    ["value"]=>
+    NULL
+  }
+  [1]=>
+  object(stdClass)#4 (1) {
+    ["value"]=>
+    NULL
+  }
+}