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:
- 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. - This doesnt works if cc is a own class with same property name (ie.
interface or something like this) - 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
Hi Marco,
Conclusion:
- 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.
- This doesnt works if cc is a own class with same property name (ie.
interface or something like this)
cc is another class.
- 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
Hello,
Conclusion:
- 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.- 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.
- 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
--
--
Etienne Kneuss
http://www.colder.ch
Men never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal
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();
?>
Hello,
Conclusion:
- 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.- 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.
- 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(); // 3Thats just some questions :)
-- Marco
--
--
Etienne Kneuss
http://www.colder.chMen 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
Hi,
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
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.
Hi,
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
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.
Hi,
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!"
Hello,
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 classThis 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:
- it reduces the readability
- 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
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
Hello,
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();
?>Hello,
Conclusion:
- 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.- 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.
- 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(); // 3Thats just some questions :)
-- Marco
--
--
Etienne Kneuss
http://www.colder.chMen 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