|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2010-01-31 20:21 UTC] EdwardDrapkin at gmail dot com
Description:
------------
When you have two classes that extend the same base class, if the protected members are declared in the base class, they are visible to each other. Because the class variables are protected, they should not be available to other classes, even if they share the same parent (but are of different types themselves)!
Reproduce code:
---------------
<?php
class foo {
public $public = "a";
private $private = "b";
protected $protected = "protected";
}
class bar extends foo {
}
class kid extends foo {
public function test() {
$b = new bar();
var_dump(get_object_vars($b));
var_dump($b->protected);
}
}
$k = new kid();
$k->test();
Expected result:
----------------
array(1) {
["public"]=>
string(1) "a"
}
Visibility error.
Actual result:
--------------
array(2) {
["public"]=>
string(1) "a"
["protected"]=>
string(9) "protected"
}
string(9) "protected"
PatchesPull Requests
Pull requests:
HistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 21:00:01 2025 UTC |
Our problem differs slightly from this issue, but I think they share a root cause. Here's a sample of code with the expected outcome. abstract class A { /** * undocumented function * * @return void */ public function __get($propertyName) { $val = $this->$propertyName; echo "Current Value of '{$propertyName}' is '{$val}'\n"; return $val; } public function __set($propertyName, $propertyValue) { echo "Setting Property '{$propertyName}' to '{$propertyValue}'\n"; $this->$propertyName = $propertyValue; } } class B extends A { protected $name; public function populateName($val) { $a = 'name'; $this->$a = $val; } public function testit() { $b = new B(); $b->name = 'internal'; $b->name; } } $two = new B(); $two->name = 'external'; $two->name; $two->testit(); Expected Results: ----------------- Setting Property 'name' to 'external' Current Value of 'name' is 'external' Setting Property 'name' to 'internal' Current Value of 'name' is 'internal' Actual Results: ---------------- Setting Property 'name' to 'external' Current Value of 'name' is 'external'Another one example, even without "extends": class Page_Element { protected $name = 'name*'; public function __construct(Page_Element $child = null) { echo $this->name; echo $child->name; } } new Page_Element(new Page_Element(null)); (from http://youtrack.jetbrains.net/issue/WI-4663) So why $child->name can be accessed? It's new object!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@giovanni: Why would the expected behaviour there be to print 10? Re-declaring a property doesn't create a second property with the same name, it changes it polymorphically just like re-declaring a method does. Either the method can see the value 10, or it cannot see any value. class C { protected $x = 10; public function m() { print "x=" . $this->x . "\n"; } } class D extends C { protected $x = 20; } $d = new D(); $d->m(); // "x=20"