Welcome! Log In Create A New Profile

Advanced

[PHP] Bazar behavior w/ private member variables

Posted by Nathan Nobbe 
Nathan Nobbe
[PHP] Bazar behavior w/ private member variables
July 13, 2012 04:20AM
Hi all,

Strangely PHP seems to let each class have its own layer of private scope
for member variables. If a subclass defines a member variable of the same
name as one defined in the parent the values are maintained independently
in instances of the child class.

First off a simple class with a private member variable $_myPrivate, and a
public accessor method which returns its value:

class A
{
private $_myPrivate = 5;

public function getMyPrivate()
{
return $this->_myPrivate;
}
}


Second, a subclass, that gets weird right away, first we define a private
member variable that already has been defined in the parent class, and give
it a different initial value. To illustrate the behavior we have two
accessor methods, setMyPrivate that uses the $this keyword to get the value
of $_myPrivate, which returns the value of the subclasse's version of the
variable, and getParentsMyPrivate, that calls A::getMyPrivate via the
parent keyword and it returns the value of $_myPrivate as defined in the
base class.

class B extends A
{
private $_myPrivate = 6;

public function setMyPrivate()
{
$this->_myPrivate = 6;
}

public function getMyPrivate()
{
return $this->_myPrivate;
}

public function getParentsMyPrivate()
{
return parent::getMyPrivate();
}
}


Look at a var_dump of an instance of B:

object(B)#2 (2) {
["_myPrivate":"B":private]=>
int(6)
["_myPrivate":"A":private]=>
int(5)
}

clearly storage is allocated for two different values. Now I'm sure you
all know that if I were to define a private method in A and try to call it
from B a Fatal error is raised, something on the order of

PHP Fatal error: Call to private method A::tryToCallMeFromB() from context
'B'

so why the special treatment for member variables, is this supposed to be a
feature?

-nathan
Tommy Pham
Re: [PHP] Bazar behavior w/ private member variables
July 13, 2012 04:50AM
On Thu, Jul 12, 2012 at 7:19 PM, Nathan Nobbe <[email protected]> wrote:
> Hi all,
>
> Strangely PHP seems to let each class have its own layer of private scope
> for member variables. If a subclass defines a member variable of the same
> name as one defined in the parent the values are maintained independently
> in instances of the child class.
>
> First off a simple class with a private member variable $_myPrivate, and a
> public accessor method which returns its value:
>
> class A
> {
> private $_myPrivate = 5;
>
> public function getMyPrivate()
> {
> return $this->_myPrivate;
> }
> }
>
>
> Second, a subclass, that gets weird right away, first we define a private
> member variable that already has been defined in the parent class, and give
> it a different initial value. To illustrate the behavior we have two
> accessor methods, setMyPrivate that uses the $this keyword to get the value
> of $_myPrivate, which returns the value of the subclasse's version of the
> variable, and getParentsMyPrivate, that calls A::getMyPrivate via the
> parent keyword and it returns the value of $_myPrivate as defined in the
> base class.
>
> class B extends A
> {
> private $_myPrivate = 6;
>
> public function setMyPrivate()
> {
> $this->_myPrivate = 6;
> }
>
> public function getMyPrivate()
> {
> return $this->_myPrivate;
> }
>
> public function getParentsMyPrivate()
> {
> return parent::getMyPrivate();
> }
> }
>
>
> Look at a var_dump of an instance of B:
>
> object(B)#2 (2) {
> ["_myPrivate":"B":private]=>
> int(6)
> ["_myPrivate":"A":private]=>
> int(5)
> }
>
> clearly storage is allocated for two different values. Now I'm sure you
> all know that if I were to define a private method in A and try to call it
> from B a Fatal error is raised, something on the order of
>
> PHP Fatal error: Call to private method A::tryToCallMeFromB() from context
> 'B'
>
> so why the special treatment for member variables, is this supposed to be a
> feature?
>
> -nathan

That is OOP accross all languages. If you want the child class to
modify the variable, then set it to protected. Private is only
accessible within that class.

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Nathan Nobbe
Re: [PHP] Bazar behavior w/ private member variables
July 13, 2012 05:30AM
On Thu, Jul 12, 2012 at 8:38 PM, Tommy Pham <[email protected]> wrote:

> On Thu, Jul 12, 2012 at 7:19 PM, Nathan Nobbe <[email protected]>
> wrote:
> > Hi all,
> >
> > Strangely PHP seems to let each class have its own layer of private scope
> > for member variables. If a subclass defines a member variable of the
> same
> > name as one defined in the parent the values are maintained independently
> > in instances of the child class.
> >
> > First off a simple class with a private member variable $_myPrivate, and
> a
> > public accessor method which returns its value:
> >
> > class A
> > {
> > private $_myPrivate = 5;
> >
> > public function getMyPrivate()
> > {
> > return $this->_myPrivate;
> > }
> > }
> >
> >
> > Second, a subclass, that gets weird right away, first we define a private
> > member variable that already has been defined in the parent class, and
> give
> > it a different initial value. To illustrate the behavior we have two
> > accessor methods, setMyPrivate that uses the $this keyword to get the
> value
> > of $_myPrivate, which returns the value of the subclasse's version of the
> > variable, and getParentsMyPrivate, that calls A::getMyPrivate via the
> > parent keyword and it returns the value of $_myPrivate as defined in the
> > base class.
> >
> > class B extends A
> > {
> > private $_myPrivate = 6;
> >
> > public function setMyPrivate()
> > {
> > $this->_myPrivate = 6;
> > }
> >
> > public function getMyPrivate()
> > {
> > return $this->_myPrivate;
> > }
> >
> > public function getParentsMyPrivate()
> > {
> > return parent::getMyPrivate();
> > }
> > }
> >
> >
> > Look at a var_dump of an instance of B:
> >
> > object(B)#2 (2) {
> > ["_myPrivate":"B":private]=>
> > int(6)
> > ["_myPrivate":"A":private]=>
> > int(5)
> > }
> >
> > clearly storage is allocated for two different values. Now I'm sure you
> > all know that if I were to define a private method in A and try to call
> it
> > from B a Fatal error is raised, something on the order of
> >
> > PHP Fatal error: Call to private method A::tryToCallMeFromB() from
> context
> > 'B'
> >
> > so why the special treatment for member variables, is this supposed to
> be a
> > feature?
> >
> > -nathan
>
> That is OOP accross all languages. If you want the child class to
> modify the variable, then set it to protected. Private is only
> accessible within that class.
>

I know that sounds like it should make sense but if it's true, it's an
aspect I've never known about, at least maybe I'm just spacing really bad
or something...

Anyway, this chokes in javac:

public class PrivateAccess
{
private Boolean isAccessible = true;
}

class PrivateAccessChild extends PrivateAccess
{
public Boolean getAccessible()
{
return isAccessible;
}
}

PrivateAccessChild.java:5: isAccessible has private access in PrivateAccess
return isAccessible;
^

-nathan
Nathan Nobbe
Re: [PHP] Bazar behavior w/ private member variables
July 13, 2012 05:30AM
On Thu, Jul 12, 2012 at 9:23 PM, Nathan Nobbe <[email protected]>wrote:

> On Thu, Jul 12, 2012 at 8:38 PM, Tommy Pham <[email protected]> wrote:
>
>> On Thu, Jul 12, 2012 at 7:19 PM, Nathan Nobbe <[email protected]>
>> wrote:
>> > Hi all,
>> >
>> > Strangely PHP seems to let each class have its own layer of private
>> scope
>> > for member variables. If a subclass defines a member variable of the
>> same
>> > name as one defined in the parent the values are maintained
>> independently
>> > in instances of the child class.
>> >
>> > First off a simple class with a private member variable $_myPrivate,
>> and a
>> > public accessor method which returns its value:
>> >
>> > class A
>> > {
>> > private $_myPrivate = 5;
>> >
>> > public function getMyPrivate()
>> > {
>> > return $this->_myPrivate;
>> > }
>> > }
>> >
>> >
>> > Second, a subclass, that gets weird right away, first we define a
>> private
>> > member variable that already has been defined in the parent class, and
>> give
>> > it a different initial value. To illustrate the behavior we have two
>> > accessor methods, setMyPrivate that uses the $this keyword to get the
>> value
>> > of $_myPrivate, which returns the value of the subclasse's version of
>> the
>> > variable, and getParentsMyPrivate, that calls A::getMyPrivate via the
>> > parent keyword and it returns the value of $_myPrivate as defined in the
>> > base class.
>> >
>> > class B extends A
>> > {
>> > private $_myPrivate = 6;
>> >
>> > public function setMyPrivate()
>> > {
>> > $this->_myPrivate = 6;
>> > }
>> >
>> > public function getMyPrivate()
>> > {
>> > return $this->_myPrivate;
>> > }
>> >
>> > public function getParentsMyPrivate()
>> > {
>> > return parent::getMyPrivate();
>> > }
>> > }
>> >
>> >
>> > Look at a var_dump of an instance of B:
>> >
>> > object(B)#2 (2) {
>> > ["_myPrivate":"B":private]=>
>> > int(6)
>> > ["_myPrivate":"A":private]=>
>> > int(5)
>> > }
>> >
>> > clearly storage is allocated for two different values. Now I'm sure you
>> > all know that if I were to define a private method in A and try to call
>> it
>> > from B a Fatal error is raised, something on the order of
>> >
>> > PHP Fatal error: Call to private method A::tryToCallMeFromB() from
>> context
>> > 'B'
>> >
>> > so why the special treatment for member variables, is this supposed to
>> be a
>> > feature?
>> >
>> > -nathan
>>
>> That is OOP accross all languages. If you want the child class to
>> modify the variable, then set it to protected. Private is only
>> accessible within that class.
>>
>
> I know that sounds like it should make sense but if it's true, it's an
> aspect I've never known about, at least maybe I'm just spacing really bad
> or something...
>
> Anyway, this chokes in javac:
>
> public class PrivateAccess
> {
> private Boolean isAccessible = true;
> }
>
> class PrivateAccessChild extends PrivateAccess
> {
> public Boolean getAccessible()
> {
> return isAccessible;
> }
> }
>
> PrivateAccessChild.java:5: isAccessible has private access in PrivateAccess
> return isAccessible;
> ^
>
> -nathan
>

Ahhh, but if I add the private declaration in the subclass it works. Where
have I been??

-nathan
Sebastian Krebs
[PHP] Bazar behavior w/ private member variables
July 13, 2012 10:10AM
Should go to the mailinlist :>

---------- Forwarded message ----------
From: Sebastian Krebs <[email protected]>
Date: 2012/7/13
Subject: Re: [PHP] Bazar behavior w/ private member variables
To: Nathan Nobbe <[email protected]>


Hi,

Private properties are only accessable from within an object of the class,
where it's defined. If you define a new private property with the same name
in a subclass, then you just have two properties with the same name, but in
different classes. They are separate from each other ;) It seems, that you
are _really_ looking for protected properties instead.

Regards,
Sebastian


2012/7/13 Nathan Nobbe <[email protected]>

> On Thu, Jul 12, 2012 at 9:23 PM, Nathan Nobbe <[email protected]
> >wrote:
>
> > On Thu, Jul 12, 2012 at 8:38 PM, Tommy Pham <[email protected]> wrote:
> >
> >> On Thu, Jul 12, 2012 at 7:19 PM, Nathan Nobbe <[email protected]>
> >> wrote:
> >> > Hi all,
> >> >
> >> > Strangely PHP seems to let each class have its own layer of private
> >> scope
> >> > for member variables. If a subclass defines a member variable of the
> >> same
> >> > name as one defined in the parent the values are maintained
> >> independently
> >> > in instances of the child class.
> >> >
> >> > First off a simple class with a private member variable $_myPrivate,
> >> and a
> >> > public accessor method which returns its value:
> >> >
> >> > class A
> >> > {
> >> > private $_myPrivate = 5;
> >> >
> >> > public function getMyPrivate()
> >> > {
> >> > return $this->_myPrivate;
> >> > }
> >> > }
> >> >
> >> >
> >> > Second, a subclass, that gets weird right away, first we define a
> >> private
> >> > member variable that already has been defined in the parent class, and
> >> give
> >> > it a different initial value. To illustrate the behavior we have two
> >> > accessor methods, setMyPrivate that uses the $this keyword to get the
> >> value
> >> > of $_myPrivate, which returns the value of the subclasse's version of
> >> the
> >> > variable, and getParentsMyPrivate, that calls A::getMyPrivate via the
> >> > parent keyword and it returns the value of $_myPrivate as defined in
> the
> >> > base class.
> >> >
> >> > class B extends A
> >> > {
> >> > private $_myPrivate = 6;
> >> >
> >> > public function setMyPrivate()
> >> > {
> >> > $this->_myPrivate = 6;
> >> > }
> >> >
> >> > public function getMyPrivate()
> >> > {
> >> > return $this->_myPrivate;
> >> > }
> >> >
> >> > public function getParentsMyPrivate()
> >> > {
> >> > return parent::getMyPrivate();
> >> > }
> >> > }
> >> >
> >> >
> >> > Look at a var_dump of an instance of B:
> >> >
> >> > object(B)#2 (2) {
> >> > ["_myPrivate":"B":private]=>
> >> > int(6)
> >> > ["_myPrivate":"A":private]=>
> >> > int(5)
> >> > }
> >> >
> >> > clearly storage is allocated for two different values. Now I'm sure
> you
> >> > all know that if I were to define a private method in A and try to
> call
> >> it
> >> > from B a Fatal error is raised, something on the order of
> >> >
> >> > PHP Fatal error: Call to private method A::tryToCallMeFromB() from
> >> context
> >> > 'B'
> >> >
> >> > so why the special treatment for member variables, is this supposed to
> >> be a
> >> > feature?
> >> >
> >> > -nathan
> >>
> >> That is OOP accross all languages. If you want the child class to
> >> modify the variable, then set it to protected. Private is only
> >> accessible within that class.
> >>
> >
> > I know that sounds like it should make sense but if it's true, it's an
> > aspect I've never known about, at least maybe I'm just spacing really bad
> > or something...
> >
> > Anyway, this chokes in javac:
> >
> > public class PrivateAccess
> > {
> > private Boolean isAccessible = true;
> > }
> >
> > class PrivateAccessChild extends PrivateAccess
> > {
> > public Boolean getAccessible()
> > {
> > return isAccessible;
> > }
> > }
> >
> > PrivateAccessChild.java:5: isAccessible has private access in
> PrivateAccess
> > return isAccessible;
> > ^
> >
> > -nathan
> >
>
> Ahhh, but if I add the private declaration in the subclass it works. Where
> have I been??
>
> -nathan
>
Sorry, only registered users may post in this forum.

Click here to login