private properties ....

php.internals

Marco Kaiser

18 years ago
Hi List, <?php error_reporting(E_ALL); class aaa { protected $_parent = null; private $_value = 0; public function setValue($value) { $this->_value = $value; } public function getValue) { return $this->_value; } public function setParent( $oParent ) { $this->_parent = $oParent; } public function showParentValue() { return $this->_parent->_value; } } $aa = new aaa(); $aa->setValue(500); $bb = new aaa(); $bb->setParent($aa); echo $bb->showParentValue() . PHP_EOL; ?> The code above shows me a feature thats bypass my class design. :) With this code it is possible to access the private class property _value from $aa. Output: 500 If i us a other class like : class cc { private $_value = 'foo'; } $aa = new cc(); $bb = new aaa(); $bb->setParent($aa); echo $bb->showParentValue() . PHP_EOL; i get an error that tells me cc:$_value is private and could not be accessed. Thats ok. But with this change i cant overload or change my property in any way. class cc extends aaa { private $_value = 'foo'; } $aa = new cc(); $bb = new aaa(); $bb->setParent($aa); echo $bb->showParentValue() . PHP_EOL; echo $aa->getValue() . PHP_EOL; the output is: 0 0 Thats a bit strange to me because i expected a different behavior. Conclusion: 1. Why i can access a private property from a different class instance (name) but same type ? $aa and $bb are instances of aaa but not the same. 2. This doesnt works if cc is a own class with same property name (ie. interface or something like this) 3. Is it a bug that i can't use same property name in my child class? (normaly the parent property isnt visible to the child) cc extends aaa. Thats just some questions :) -- Marco

Johannes Schlueter

18 years ago
Hi Marco, On Fri, 2007-11-30 at 12:43 +0100, "Marco Kaiser" wrote:
> Conclusion: > 1. Why i can access a private property from a different class instance > (name) but same type ? > $aa and $bb are instances of aaa but not the same.
Since PHP's object model is based n the class concept and these limitations are bound to the class, not the object.
> 2. This doesnt works if cc is a own class with same property name (ie. > interface or something like this)
cc is another class.
> 3. Is it a bug that i can't use same property name in my child class? > (normaly the parent property isnt visible to the child) > cc extends aaa.
That's a feature: Extended classes know nothing about private stuff in the parent class. Without that the encapsulation won't be complete.
> Thats just some questions :)
And some answers. johannes

Etienne Kneuss

18 years ago
Hello, On 11/30/07, Marco Kaiser <marco.kaiser@gmail.com> wrote:
> > Conclusion: > 1. Why i can access a private property from a different class instance > (name) but same type ? > $aa and $bb are instances of aaa but not the same. > 2. This doesnt works if cc is a own class with same property name (ie. > interface or something like this)
The check whether a class property/method is accessible is based on the class of the scope you're in. It's not based on the instance. Note that encapsulation is still conserved as private properties are accessible only from methods of the class they're defined in. It also allows you to work with static methods that access private properties. 3. Is it a bug that i can't use same property name in my child class?
> (normaly the parent property isnt visible to the child) > cc extends aaa.
I'm not sure what you mean. As you can do: class A { private $foo = 2; } class B extends A { private $foo = 3; public function foo() { echo $this->foo; } } $b = new B; $b->foo(); // 3 Thats just some questions :)
> > -- Marco > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > > >
-- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal

Jingcheng Zhang

18 years ago
Hi Etienne, Is "private" only an access limiter between classes?If so, I think private properties and methods should be OK to be extended into the child class, but currently that's not the case, and there is also a bug here, consider the following example: <?php class P { private $name = 'hello'; } class C extends P { public function f() { echo $this->name; } } $o = new C(); var_dump($o); // object(C)#1 (1) { ["name:private"]=> string(5) "hello" } $o->f(); // Notice: Undefined property: C::$name in D:\Development\Workspace\index.php on line 7 ?> When using var_dump on $o, it shouldn't display the private property "name" here as it is not extended. If we allow private properties be extended into the child class, then the codes above and following should both work OK: <?php class P { private $name = 'hello'; } class C extends P { public function f() { $o = new P(); echo $o->name; // Incorrect, as the code scope is not class P } public function g() { echo $this->name; // This should be OK, as $name is extended from P, and is property of class C, not class P } } $c = new C(); $c->f(); $c->g(); ?> On Nov 30, 2007 10:08 PM, Etienne Kneuss <colder@php.net> wrote:
> Hello, > > On 11/30/07, Marco Kaiser <marco.kaiser@gmail.com> wrote: > > > > Conclusion: > > 1. Why i can access a private property from a different class instance > > (name) but same type ? > > $aa and $bb are instances of aaa but not the same. > > 2. This doesnt works if cc is a own class with same property name (ie. > > interface or something like this) > > > The check whether a class property/method is accessible is based on the > class of the scope you're in. It's not based on the instance. Note that > encapsulation is still conserved as private properties are accessible only > from methods of the class they're defined in. It also allows you to work > with static methods that access private properties. > > 3. Is it a bug that i can't use same property name in my child class? > > (normaly the parent property isnt visible to the child) > > cc extends aaa. > > > I'm not sure what you mean. As you can do: > > class A { private $foo = 2; } > class B extends A { private $foo = 3; public function foo() { echo > $this->foo; } } > $b = new B; $b->foo(); // 3 > > > Thats just some questions :) > > > > -- Marco > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: http://www.php.net/unsub.php > > > > > > > > > -- > Etienne Kneuss > http://www.colder.ch > > Men never do evil so completely and cheerfully as > when they do it from a religious conviction. > -- Pascal >
-- Best regards, Jingcheng Zhang Room 304, Dormitory 26 of Yuquan Campus, Zhejiang University P.R.China

Johannes Schlueter

18 years ago
Hi, On Sat, 2007-12-01 at 00:24 +0800, "Jingcheng Zhang" wrote:
> Hi Etienne, > Is "private" only an access limiter between classes?If so, I think private > properties and methods should be OK to be extended into the child class, but > currently that's not the case, and there is also a bug here, consider the > following example:
The child class is another class, "private" gives you encapsulation inside the base class's context. and preventing acces from other class's context. johannes

Jingcheng Zhang

18 years ago
Well, yes, "private" denies accessing from other class(including its child class), this is what "encapsulation" means. But when refering to inheritance, why forbids private properties/methods being *extended* to child classes? This is what I mean, as the following example: <?php class p { protected $foo = 'foo'; private $bar = 'bar'; } class c extends p { public function f() { $o = new p(); $o->foo = 'FOO'; // Correct, "foo" is protected property of p and thus allow accessing from child class $o->bar = 'BAR'; // Incorrect, "bar" is private property of *class p* here } public function g() { $this->foo = 'FOO'; // Correct, "foo" is $this->bar = 'BAR'; // Should be OK, as "bar" is private property of *class c* here } } ?> Thanks. On Dec 1, 2007 12:57 AM, Johannes Schlüter <johannes@php.net> wrote: > Hi, > > On Sat, 2007-12-01 at 00:24 +0800, "Jingcheng Zhang" wrote: > > Hi Etienne, > > Is "private" only an access limiter between classes?If so, I think > private > > properties and methods should be OK to be extended into the child class, > but > > currently that's not the case, and there is also a bug here, consider > the > > following example: > > The child class is another class, "private" gives you encapsulation > inside the base class's context. and preventing acces from other class's > context. > > johannes > > -- Best regards, Jingcheng Zhang Room 304, Dormitory 26 of Yuquan Campus, Zhejiang University P.R.China

Richard Quadling

18 years ago
On 01/12/2007, Jingcheng Zhang <diogin@gmail.com> wrote: > Well, yes, "private" denies accessing from other class(including its child > class), this is what "encapsulation" means. But when refering to > inheritance, why forbids private properties/methods being *extended* to > child classes? This is what I mean, as the following example: > > <?php > class p { > protected $foo = 'foo'; > private $bar = 'bar'; > } > class c extends p { > public function f() { > $o = new p(); > $o->foo = 'FOO'; // Correct, "foo" is protected property of p and > thus allow accessing from child class This is not allowed. $o is in a different context (I think that's the right way of describing this) and as such has no access to the private or protected members of $o. Just because it $o is created within class c, it is not related. > $o->bar = 'BAR'; // Incorrect, "bar" is private property of > *class p* here > } > public function g() { > $this->foo = 'FOO'; // Correct, "foo" is > $this->bar = 'BAR'; // Should be OK, as "bar" is private property of > *class c* here Private means only of use in the class in which is created, not sub-classes or public space. > } > } > ?> > > Thanks. > > > On Dec 1, 2007 12:57 AM, Johannes Schlüter <johannes@php.net> wrote: > > > Hi, > > > > On Sat, 2007-12-01 at 00:24 +0800, "Jingcheng Zhang" wrote: > > > Hi Etienne, > > > Is "private" only an access limiter between classes?If so, I think > > private > > > properties and methods should be OK to be extended into the child class, > > but > > > currently that's not the case, and there is also a bug here, consider > > the > > > following example: > > > > The child class is another class, "private" gives you encapsulation > > inside the base class's context. and preventing acces from other class's > > context. > > > > johannes > > > > > > > -- > Best regards, > Jingcheng Zhang > Room 304, Dormitory 26 of Yuquan Campus, Zhejiang University > P.R.China > -- ----- Richard Quadling Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731 "Standing on the shoulders of some very clever giants!"

Etienne Kneuss

18 years ago
Hello, On Dec 1, 2007 9:38 PM, Richard Quadling <rquadling@googlemail.com> wrote:
> On 01/12/2007, Jingcheng Zhang <diogin@gmail.com> wrote: > > Well, yes, "private" denies accessing from other class(including its > child > > class), this is what "encapsulation" means. But when refering to > > inheritance, why forbids private properties/methods being *extended* to > > child classes? This is what I mean, as the following example: > > > > <?php > > class p { > > protected $foo = 'foo'; > > private $bar = 'bar'; > > } > > class c extends p { > > public function f() { > > $o = new p(); > > $o->foo = 'FOO'; // Correct, "foo" is protected property of p > and > > thus allow accessing from child class > > This is not allowed. $o is in a different context (I think that's the > right way of describing this) and as such has no access to the private > or protected members of $o. Just because it $o is created within class > c, it is not related.
Again, the context check is based on the class and not on the instance, which is "correct" (same behavior in other OO languages like java, scala, or C++) I believe what he means is that private properties are simply masked, allowing one user to dynamically create an "overloaded" property, like: class A { private $a; } class B extends A{ private $a; // allowed, but I guess what he wants is to have that optional public function foo() { $this->a = 3; } } Having this optional is a bad thing because: 1) it reduces the readability 2) the access type of the dynamically created B::$a would be ambiguous. So, you should always explicitly define the overloaded property, and the language shouldn't be modified to allow such concept. Please take this to php_generals as this is not really the right place anymore. Regards
-- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal

Etienne Kneuss

18 years ago
Hello, Sorry late replies shouldn't be allowed ;) class A { private $foo = 2; } class B extends A { } $b = new B; $b->foo = 3; // Allowed already, it will create a public property foo in $b
-- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal

Mike Lively

18 years ago
Jingcheng Zhang wrote:
> Well, yes, "private" denies accessing from other class(including its child > class), this is what "encapsulation" means. But when refering to > inheritance, why forbids private properties/methods being *extended* to > child classes? This is what I mean, as the following example: > > <?php > class p { > protected $foo = 'foo'; > private $bar = 'bar'; > } > class c extends p { > public function f() { > $o = new p(); > $o->foo = 'FOO'; // Correct, "foo" is protected property of p and > thus allow accessing from child class > $o->bar = 'BAR'; // Incorrect, "bar" is private property of > *class p* here > } > public function g() { > $this->foo = 'FOO'; // Correct, "foo" is > $this->bar = 'BAR'; // Should be OK, as "bar" is private property of > *class c* here > } > } > ?> >
Access modifiers aren't for specifying access that "instances" have to members, it is for specifying access that "classes" have to members. Instances != Classes. The behavior you want above can be done just as easily just using protected members and I don't see how using protected members would hurt you.

Etienne Kneuss

18 years ago
Hello, On Nov 30, 2007 5:24 PM, Jingcheng Zhang <diogin@gmail.com> wrote:
> Hi Etienne, > Is "private" only an access limiter between classes?If so, I think > private > properties and methods should be OK to be extended into the child class, > but > currently that's not the case,
You're describing what "protected" does here. About the "bug", var_dump in 5_3 already states the origin of the private var: <?php class A { private $a = 2; protected $b = 3; } class B extends A { } var_dump(new B); ?> will produce: object(B)#1 (2) { ["a":"A":private]=> int(2) ["b":protected]=> int(3) } and there is also a bug here, consider the
> following example: > > <?php > class P { > private $name = 'hello'; > } > class C extends P { > public function f() { > echo $this->name; > } > } > $o = new C(); > var_dump($o); // object(C)#1 (1) { ["name:private"]=> string(5) "hello" } > $o->f(); // Notice: Undefined property: C::$name in > D:\Development\Workspace\index.php on line 7 > ?> > > When using var_dump on $o, it shouldn't display the private property > "name" > here as it is not extended. If we allow private properties be extended > into > the child class, then the codes above and following should both work OK: > > <?php > class P { > private $name = 'hello'; > } > class C extends P { > public function f() { > $o = new P(); > echo $o->name; // Incorrect, as the code scope is not class P > } > public function g() { > echo $this->name; // This should be OK, as $name is extended from > P, > and is property of class C, not class P > } > } > $c = new C(); > $c->f(); > $c->g(); > ?> > > > On Nov 30, 2007 10:08 PM, Etienne Kneuss <colder@php.net> wrote: > > > Hello, > > > > On 11/30/07, Marco Kaiser <marco.kaiser@gmail.com> wrote: > > > > > > Conclusion: > > > 1. Why i can access a private property from a different class instance > > > (name) but same type ? > > > $aa and $bb are instances of aaa but not the same. > > > 2. This doesnt works if cc is a own class with same property name (ie. > > > interface or something like this) > > > > > > The check whether a class property/method is accessible is based on the > > class of the scope you're in. It's not based on the instance. Note that > > encapsulation is still conserved as private properties are accessible > only > > from methods of the class they're defined in. It also allows you to work > > with static methods that access private properties. > > > > 3. Is it a bug that i can't use same property name in my child class? > > > (normaly the parent property isnt visible to the child) > > > cc extends aaa. > > > > > > I'm not sure what you mean. As you can do: > > > > class A { private $foo = 2; } > > class B extends A { private $foo = 3; public function foo() { echo > > $this->foo; } } > > $b = new B; $b->foo(); // 3 > > > > > > Thats just some questions :) > > > > > > -- Marco > > > > > > -- > > > PHP Internals - PHP Runtime Development Mailing List > > > To unsubscribe, visit: http://www.php.net/unsub.php > > > > > > > > > > > > > > > -- > > Etienne Kneuss > > http://www.colder.ch > > > > Men never do evil so completely and cheerfully as > > when they do it from a religious conviction. > > -- Pascal > > > > > > -- > Best regards, > Jingcheng Zhang > Room 304, Dormitory 26 of Yuquan Campus, Zhejiang University > P.R.China >
-- Etienne Kneuss http://www.colder.ch Men never do evil so completely and cheerfully as when they do it from a religious conviction. -- Pascal