Edit report at https://bugs.php.net/bug.php?id=50892&edit=1
ID: 50892
Comment by: rowan dot collins at gmail dot com
Reported by: EdwardDrapkin at gmail dot com
Summary: Protected members of non-congruent children classes
are visible
Status: Open
Type: Bug
Package: Class/Object related
Operating System: Irrelevant
PHP Version: 5.3.1
Block user comment: N
Private report: N
New Comment:
> https://3v4l.org/TM6jk
This appears to be exactly the opposite complaint from the original: in this case, the protected
property *can't* be accessed in a different child.
So we certainly have an inconsistency here - between methods and properties, and based on whether
the member is inherited directly or over-ridden / re-declared. The case of a re-declared property is
currently the only one that errors, so the simplest change would be to remove that error.
Class C knows that the access is legal when given an A, so assumes it's valid for all
sub-classes of A; sub-class B2 is currently able to break this assumption for a property, but not
for a method.
Previous Comments:
------------------------------------------------------------------------
[2018-05-26 15:21:19] giovanni at giacobbi dot net
I agree with arth dot inbox at gmail dot com, the original bug report is wrong but this actually
should be filed as a new bug imho:
Reproduce code:
---------------
class C {
protected $x = 10;
}
class D extends C {
public function m(C $c) {
print "x=" . $c->x . "\n";
}
}
class E extends C {
protected $x = 20;
}
$d = new D();
$e = new E();
$d->m($d);
$d->m($e);
Expected result:
----------------
x=10
x=10 /* note 10, NOT 20! */
Actual result:
--------------
x=10
PHP Fatal error: Uncaught Error: Cannot access protected property E::$x in Standard input code:9
Stack trace:
#0 Standard input code(21): D->m(Object(E))
#1 {main}
thrown in Standard input code on line 9
------------------------------------------------------------------------
[2018-05-26 14:31:24] arth dot inbox at gmail dot com
We should not to stand on other language behavior.
One more time: https://3v4l.org/TM6jk
For now it just breaks SOLID.
------------------------------------------------------------------------
[2018-05-26 14:25:45] rowan dot collins at gmail dot com
Sorry, slight mistake in my example: to be equivalent to this report, the Subclass::add(ParentClass
$other) method should be declared on one of the child classes. But it still works in both languages:
https://3v4l.org/IInDq
https://tio.run/##vVPBThsxED1vvmKOm5Ya6LXihIS4IFWA2kPVw6w9ZA1eO7JnEyrEt6fe9YbYJDkgVbX2NH5@8@bN20dc4ZdH9bTZYBPYo2SQBkOA715LgpcZxLP0jkkyKVCubwzBCk1P38a7BIhVLdObOsfMJ4bhcKuDGKtwkTO87njeNOx1XBDf4vrH8Kqe73feoa6c75DjywmbCTg9hUs0JgBm/B1x6xS4B1i3Wra0Ig@y1UZNPugwCn8j8cS9t3CD3Arveqvqca5C33w72Otsllju8fnKEyVT6ZnJqncWpzkK3FEnQ78kX6fyttXhRRWyMoZpit1KSpokZuW0AlSqTnIct@T/hZ8j0aFYfL5Id@LAtjMzRzk/NbfRrdLMl700bmH/00v4BOfiayZ7NilK8m9Q2/i8moqBkbdmd/GqvmOv7eLXb0C/CEOjqipigfH3sbQuslKfn4mzqL@qiqmbCZoXd9C7P4GpE65nsYwt2dgaxYFf6Bi4OQqOXwzHNXk6AbSgbRzSDhF6KBO@1sYASknhfYi6JuYmwnPlkRXFkMfmw/KHNWw2fwE
------------------------------------------------------------------------
[2018-05-26 14:11:34] rowan dot collins at gmail dot com
This may seem odd, but is actually perfectly reasonable if you consider polymorphism:
- Access is class-based, not instance-based: you can call private members of a different instance of
the same class.
- For the same reason, you can access protected members on an instance of a parent class.
- If you ask for an instance of class A, you may at run-time actually receive an instance of some
sub-class of A.
- So, if classes B1 and B2 both inherit from A, a method on class B1 might ask for an instance of A,
and be given an instance of B2; when it calls a method on that instance, it's the definition in
B2 which will be accessed.
Here's a concrete example: https://3v4l.org/LeClo
Note that this example also works in Java: https://tio.run/##vZMxb9swEIVn61fcKKctbWctMhUIuhgomqIdigwn8mIxpUiDPNkpDP92hxJlW4rsIUBRQhP5@O670@MzbvDTs/pzOGAR2KNkkAZDgG9eS4JdBnGtvWOSTAqUqwtDsEFT0@f2LAnirpbpTt7XTDuHZnGpg2h34a7vsD/7nBhGFVfE33H7s7mVT8eVz6p75yvkeLPT9gBmM/iCxgTAnn9FXDoF7gm2pZYlbciDLLVR3Rx0aMFPJp649haWyKXwrrYqb/sa8E1HjXWYG6cVoFJ5mq7jkvy/IGyNLg36w106Exfmt8/2WZYsfuDLvSdKVPTCZNWbBCT@ge7qjw71mnyeto@lLudoQNVz6IZ8bmRE3CL80lxGpCHxbpTIo@x/AsMNLMRtDzvriBL@ErWN1yfdZmDkYzyqeJQ/sNd29fsR0K9CU2gySUPH@HYsbQd/Il/MxTyCHzVFp@k3f9Y8/A1MlXA1i3UswsbmKC48nGvi4qo4fjHAX8nTR0AL2sa2bBPzp2FwttoYQCkpvA16VcRsR3mfPLqiaN5M8W78ZvCHwys
The example from the original report also works in Java: https://tio.run/##fY9BDoMgEEXXcgriShflAqZH6Mpl0zSg1CAKDYy2TePZKQTUpovuZv7/mf@mpzM99K10rhmotfimNX6j7D6xQTS4BiNUh69pPeKc5lXmbaOBN8DbPbEpPrQteYUWhOJlRg3mT@Cq3Vp2U4r210yds/YWcAtFGdQsuMyXKP4IJ4uy8mL9ssBHoicgd88DgyoYSdT/AitnyCyBJpVGqBMV6ovEAoUVaPRWEX8/XzA1nY104Q@Z6Pwc6SSJ/KnEuQ8
I'm of the opinion that this is not a bug.
------------------------------------------------------------------------
[2017-07-21 18:42:58] cmb@php.net
Related To: Bug #74932
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=50892
--
Edit this bug report at https://bugs.php.net/bug.php?id=50892&edit=1