Bug #50892 [Com]: Protected members of non-congruent children classes are visible

From: Date: Sat, 26 May 2018 15:21:24 +0000
Subject: Bug #50892 [Com]: Protected members of non-congruent children classes are visible
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-215383@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=50892&edit=1

 ID:                 50892
 Comment by:         giovanni at giacobbi dot net
 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:

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


Previous Comments:
------------------------------------------------------------------------
[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

------------------------------------------------------------------------
[2017-02-22 09:32:30] mail at pmmaga dot net

A PR was prepared to fix this on the current master (7.2) but it was decided the the potential BC
break could possibly be too much for a minor and it was suggested that it should wait for the next
major.

------------------------------------------------------------------------


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


Thread (21 messages)

« previous php.bugs (#215383) next »