]> granicus.if.org Git - php/commitdiff
- Fixed bug #49521 (PDO fetchObject sets values before calling constructor)
authorFelipe Pena <felipe@php.net>
Sun, 15 Nov 2009 16:20:37 +0000 (16:20 +0000)
committerFelipe Pena <felipe@php.net>
Sun, 15 Nov 2009 16:20:37 +0000 (16:20 +0000)
  (patch by Pierrick)

ext/pdo/pdo_stmt.c
ext/pdo/tests/pdo_005.phpt
ext/pdo_mysql/tests/pdo_mysql_stmt_fetchobject.phpt
ext/pdo_sqlite/tests/bug49521.phpt [new file with mode: 0644]

index 1e443c224612a518678b9c7fcac1cca7f9838f46..0ab02319b72b17f24912d4806e15238875cb7e0c 100755 (executable)
@@ -1107,6 +1107,32 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value,
                        }
                }
 
+               switch (how) {
+                       case PDO_FETCH_CLASS:
+                               if (ce->constructor && !(flags & (PDO_FETCH_PROPS_LATE | PDO_FETCH_SERIALIZE))) {
+                                       stmt->fetch.cls.fci.object_ptr = return_value;
+                                       stmt->fetch.cls.fcc.object_ptr = return_value;
+                                       if (zend_call_function(&stmt->fetch.cls.fci, &stmt->fetch.cls.fcc TSRMLS_CC) == FAILURE) {
+                                               pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "could not call class constructor" TSRMLS_CC);
+                                               return 0;
+                                       } else {
+                                               if (stmt->fetch.cls.retval_ptr) {
+                                                       zval_ptr_dtor(&stmt->fetch.cls.retval_ptr);
+                                               }
+                                       }
+                               }
+                               if (flags & PDO_FETCH_CLASSTYPE) {
+                                       do_fetch_opt_finish(stmt, 0 TSRMLS_CC);
+                                       stmt->fetch.cls.ce = old_ce;
+                                       stmt->fetch.cls.ctor_args = old_ctor_args;
+                                       stmt->fetch.cls.fci.param_count = old_arg_count;
+                               }
+                               break;
+                       
+                       default:
+                               break;
+               }
+
                for (idx = 0; i < stmt->column_count; i++, idx++) {
                        zval *val;
                        MAKE_STD_ZVAL(val);
@@ -1245,27 +1271,6 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value,
                }
                
                switch (how) {
-                       case PDO_FETCH_CLASS:
-                               if (ce->constructor && !(flags & (PDO_FETCH_PROPS_LATE | PDO_FETCH_SERIALIZE))) {
-                                       stmt->fetch.cls.fci.object_ptr = return_value;
-                                       stmt->fetch.cls.fcc.object_ptr = return_value;
-                                       if (zend_call_function(&stmt->fetch.cls.fci, &stmt->fetch.cls.fcc TSRMLS_CC) == FAILURE) {
-                                               pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "could not call class constructor" TSRMLS_CC);
-                                               return 0;
-                                       } else {
-                                               if (stmt->fetch.cls.retval_ptr) {
-                                                       zval_ptr_dtor(&stmt->fetch.cls.retval_ptr);
-                                               }
-                                       }
-                               }
-                               if (flags & PDO_FETCH_CLASSTYPE) {
-                                       do_fetch_opt_finish(stmt, 0 TSRMLS_CC);
-                                       stmt->fetch.cls.ce = old_ce;
-                                       stmt->fetch.cls.ctor_args = old_ctor_args;
-                                       stmt->fetch.cls.fci.param_count = old_arg_count;
-                               }
-                               break;
-
                        case PDO_FETCH_FUNC:
                                stmt->fetch.func.fci.param_count = idx;
                                stmt->fetch.func.fci.retval_ptr_ptr = &retval;
index 06421a1ccbc0c0a0e4cc93a46685539be59b228b..4eac938aa8839fb104505f3017aa619c34ec80e1 100644 (file)
@@ -34,7 +34,7 @@ class TestDerived extends TestBase
 
        public function __construct(&$row)
        {
-               echo __METHOD__ . "($row,{$this->id})\n";
+               echo __METHOD__ . "($row)\n";
                $this->row = $row++;
        }
 }
@@ -108,9 +108,9 @@ array(3) {
     unicode(2) "CC"
   }
 }
-TestDerived::__construct(0,1)
-TestDerived::__construct(1,2)
-TestDerived::__construct(2,3)
+TestDerived::__construct(0)
+TestDerived::__construct(1)
+TestDerived::__construct(2)
 array(3) {
   [0]=>
   object(TestDerived)#%d (5) {
index 067f9ca7046efd94f5e0a206bf19c0d2f1c02a82..672094cd2a7526d34f70e7e853ffbe668912aaa5 100644 (file)
@@ -71,21 +71,21 @@ require dirname(__FILE__) . '/mysql_pdo_test.inc';
 MySQLPDOTest::dropTestTable();
 ?>
 --EXPECTF--
+myclass::__construct(0, 1): 0 / 0
 myclass::__set(id, -'1'-) 1
 myclass::__set(, -''-) 2
 myclass::__set(null, -NULL-) 3
 myclass::__set(, -''-) 4
-myclass::__construct(0, 1): 4 / 4
+myclass::__construct(1, 2): 4 / 0
 myclass::__set(id, -'2'-) 1
 myclass::__set(, -''-) 2
 myclass::__set(null, -NULL-) 3
 myclass::__set(, -''-) 4
-myclass::__construct(1, 2): 8 / 4
+myclass::__construct(2, 3): 8 / 0
 myclass::__set(id, -'3'-) 1
 myclass::__set(, -''-) 2
 myclass::__set(null, -NULL-) 3
 myclass::__set(, -''-) 4
-myclass::__construct(2, 3): 12 / 4
 object(myclass)#%d (4) {
   [%u|b%"set_calls":"myclass":private]=>
   int(4)
@@ -96,4 +96,4 @@ object(myclass)#%d (4) {
   [%u|b%"null"]=>
   NULL
 }
-done!
\ No newline at end of file
+done!
diff --git a/ext/pdo_sqlite/tests/bug49521.phpt b/ext/pdo_sqlite/tests/bug49521.phpt
new file mode 100644 (file)
index 0000000..26cd2b2
--- /dev/null
@@ -0,0 +1,39 @@
+--TEST--
+Bug #49521 (PDO fetchObject sets values before calling constructor)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_sqlite')) die ("skip Need PDO_SQlite support");
+?>
+--FILE--
+<?php
+
+class Book {
+    public $title = 'test';
+    public $author;
+    
+       public function __construct($x) {
+               $this->title = '';
+               echo __METHOD__,"\n";
+       }
+       public function __set($a, $b) {
+               echo __METHOD__,"\n";
+               var_dump($a);
+       }
+}
+
+$pdo = new PDO('sqlite::memory:');
+$pdo->exec('CREATE TABLE book(title,author)');
+$pdo->exec('INSERT INTO book VALUES ("PHP","Rasmus")');
+$statement = $pdo->prepare('SELECT * FROM book WHERE title="PHP"');
+$statement->execute();
+var_dump($statement->fetchObject('Book', array(1)));
+
+?>
+--EXPECTF--
+Book::__construct
+object(Book)#%d (2) {
+  [%u|b%"title"]=>
+  string(3) "PHP"
+  [%u|b%"author"]=>
+  string(6) "Rasmus"
+}