php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #66355 PDO::FETCH_INTO $this + protected properties throws Fatal error
Submitted: 2013-12-26 15:41 UTC Modified: 2021-05-06 15:55 UTC
Votes:6
Avg. Score:4.0 ± 0.8
Reproduced:5 of 6 (83.3%)
Same Version:1 (20.0%)
Same OS:0 (0.0%)
From: sjon at hortensius dot net Assigned:
Status: Open Package: PDO related
PHP Version: 5.5.7 OS: archlinux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2013-12-26 15:41 UTC] sjon at hortensius dot net
Description:
------------
I like FETCH_CLASS being able to put stuff in protected properties, but why can't FETCH_INTO do the same (for $this)?

Test script:
---------------
<?php

class User
{
    protected $id;

    public static function get()
    {
        global $db;
        
		$q = $db->query("SELECT * FROM User WHERE `id` = 1");
		$q->setFetchMode(PDO::FETCH_CLASS, 'User');

		return $q->fetch();
    }

    public function load()
    {
		global $db;

		$q = $db->query("SELECT * FROM User WHERE `id` = 1");
        $q->setFetchMode(PDO::FETCH_INTO, $this);

		return $q->fetch();
    }
}

$db = new PDO('sqlite::memory:');
$db->exec("CREATE TABLE User(id INTEGER PRIMARY KEY, name TEXT)");
$db->query("INSERT INTO User VALUES(1, 'test')");

// worko
var_dump(User::get());

// no-worko
$user = new User;
var_dump($user->load());

Expected result:
----------------
Both var_dumps should return the same object

Actual result:
--------------
object(User)#3 (2) {
  ["id":protected]=>
  string(1) "1"
  ["name"]=>
  string(4) "test"
}

Fatal error: Cannot access protected property User::$id in /in/DCjXc on line 24

Process exited with code 255.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-05-06 15:36 UTC] cmb@php.net
> […] , but why can't FETCH_INTO do the same (for $this)?

Because PDO doe not provide a fake scope for FETCH_INTO, so the
property is set from PDOStatement where modifications of protected
User properties are not allowed.

From looking at commit 883ee83478[1], this looks unintentional.
*Simplified* PoC fix:


 ext/pdo/pdo_stmt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index adc921bbd7..45d22d5152 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -1082,7 +1082,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_
 
 				case PDO_FETCH_OBJ:
 				case PDO_FETCH_INTO:
-					zend_update_property_ex(NULL, return_value,
+					zend_update_property_ex(Z_OBJCE_P(return_value), return_value,
 						stmt->columns[i].name,
 						&val);
 					zval_ptr_dtor(&val);


[1] <https://github.com/php/php-src/commit/883ee83478177ebb220bef6634dcc2c6749a8625>
 [2021-05-06 15:55 UTC] cmb@php.net
Well, according to pdo_025.phpt[1] this is supposed to fail.
Apparently, the documention does not clarify.

Not sure what to do.

[1] <https://github.com/php/php-src/blob/php-7.4.19/ext/pdo/tests/pdo_025.phpt>
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Tue Jun 15 13:01:24 2021 UTC