mirror of
https://github.com/php/php-src.git
synced 2024-11-28 04:14:26 +08:00
- Fixed bug #49521 (PDO fetchObject sets values before calling constructor)
(patch by Pierrick)
This commit is contained in:
parent
3a9f74967d
commit
4bafbf58f8
2
NEWS
2
NEWS
@ -47,6 +47,8 @@ PHP NEWS
|
||||
- Fixed bug #49719 (ReflectionClass::hasProperty returns true for a private
|
||||
property in base class). (Felipe)
|
||||
- Fixed bug #49647 (DOMUserData does not exist). (Rob)
|
||||
- Fixed bug #49521 (PDO fetchObject sets values before calling constructor).
|
||||
(Pierrick)
|
||||
- Fixed bug #49244 (Floating point NaN cause garbage characters). (Sjoerd)
|
||||
- Fixed bug #49224 (Compile error due to old DNS functions on AIX systems).
|
||||
(Scott)
|
||||
|
@ -1106,6 +1106,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);
|
||||
@ -1239,27 +1265,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;
|
||||
|
@ -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) {
|
||||
string(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) {
|
||||
@ -151,4 +151,4 @@ array(3) {
|
||||
["val2"]=>
|
||||
string(2) "CC"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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!
|
||||
done!
|
||||
|
39
ext/pdo_sqlite/tests/bug49521.phpt
Normal file
39
ext/pdo_sqlite/tests/bug49521.phpt
Normal file
@ -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"
|
||||
}
|
Loading…
Reference in New Issue
Block a user