php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48286 ReflectionProperty::getDeclaringClass() does not work with redeclared properties
Submitted: 2009-05-14 20:29 UTC Modified: 2009-05-15 00:22 UTC
From: Markus dot Lidel at shadowconnect dot com Assigned:
Status: Not a bug Package: Reflection related
PHP Version: 5.*, 6CVS (2009-05-14) OS: *
Private report: No CVE-ID: None
 [2009-05-14 20:29 UTC] Markus dot Lidel at shadowconnect dot com
Description:
------------
ReflectionProperty::getDeclaringClass() called on derived properties always return the class where the property was first defined, instead of the class where the property was redeclared. If $prop is private it works. (properly related to #39104)

Reproduce code:
---------------
class A
{
  protected $prop;
}

class B extends A
{
  protected $prop;
}

$rp = new ReflectionProperty('B', 'prop');
echo $rp->getDeclaringClass()->getName();


Expected result:
----------------
B

Actual result:
--------------
A

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-05-14 21:51 UTC] johannes@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

It is declared in A, the 2nd declaration has no actual effect when the class is being bound.
 [2009-05-14 22:19 UTC] Markus dot Lidel at shadowconnect dot com
Thank you for you fast response.

But how do you find out, if the property is redeclard in a derived class?

Note: ReflectionProperty::getDeclaringClass() also displays A if property is static. Shouldn't getDeclaringClass() in this case display the class from which the value is retrieved?

BTW, ReflectionMethod::getDeclaringClass() works as expected (displays B). Although i don't know the internals, it is a bit confusing that two identically named functions behave differently.
 [2009-05-15 00:09 UTC] Markus dot Lidel at shadowconnect dot com
This patch resolves the problem and display redeclared properties in the class where it is defined.

--- php_reflection.c.ori        2008-12-31 12:17:42.000000000 +0100
+++ php_reflection.c    2009-05-15 02:04:51.000000000 +0200
@@ -4125,6 +4125,10 @@
                        break;
                }
                ce = tmp_ce;
+               if (ce == tmp_info->ce) {
+                       /* it's a redeclared property, so no further inheritance needed */
+                       break;
+               }
                tmp_ce = tmp_ce->parent;
        }
 [2009-05-15 00:22 UTC] Markus dot Lidel at shadowconnect dot com
Description:
------------
Here is a little test case which demonstrates that the patch is working. Hope it helps.

testing code:
-------------
class A {
}

class B extends A {
  static protected $prop;
}

class C extends B {
  static protected $prop;
}

class D extends C {
}

class E extends D {
}

class F extends E {
  static protected $prop;
}

$class = 'A';
for($class = 'A'; $class <= 'F'; $class ++) {
  print($class.' => ');
  try {
    $rp = new ReflectionProperty($class, 'prop');
    print($rp->getDeclaringClass()->getName());
  } catch(Exception $e) {
    print('N/A');
  }
  print("\n");
}

result after patch:
-------------------
A => N/A
B => B
C => C
D => C
E => C
F => F

result before patch:
--------------------
A => N/A
B => B
C => B
D => B
E => B
F => B
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 13:01:29 2024 UTC