Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > PHP OOP question

PHP OOP question
Thread Tools
clam2000
Dedicated MacNNer
Join Date: Aug 2002
Status: Offline
Reply With Quote
Dec 28, 2005, 10:22 PM
 
I was getting some bugs i wasn't expecting, setup this test case, and still don't get what's going on. if anyone can clarify what's happening here, that would be great.

[PHP]
class a
{
private $prop=-1;
function __construct() {
$this->prop=0;
}
function getprop() {
return $this->prop;
}
}
class b extends a
{
function __construct() {
$this->prop=1;
}
}
class c extends a
{
function __construct() {
$this->prop=1;
}
function getprop() {
return $this->prop;
}
}

$a = new a();
echo($a->getprop()); // 0
$b = new b();
echo($b->getprop()); // -1
$c = new c();
echo($c->getprop()); // 1
[/PHP]

gives me the output
0 -1 1

so why does overloading the getprop method cause php to update the private property?
     
madmacgames
Grizzled Veteran
Join Date: Oct 2003
Status: Offline
Reply With Quote
Dec 29, 2005, 02:42 PM
 
Originally Posted by clam2000
so why does overloading the getprop method cause php to update the private property?
It doesn't.

"Private limits visibility only to the class that defines the item."

If you want your child classes to have direct access to the private properties/methods, you need to use protected, not private.

In the b and c class constructors, when you are doing $this->prop = 1, you are actually creating a new public property, "prop". You can verify this with print_r or var_dump:

Code:
php > $c = new c(); php > print_r($c); c Object ( [prop: private] => -1 [prop] => 1 ) php >
So, c::getprop is actually returning the public prop of object c.

The same is true of b as well. It has the private prop (which it cannot see), and a public prop from the constructor. But b::getprop is actually a::getprop. a has access to the private prop, so it returns that and not the public prop of b.

It has to do with visibly. You aren't changing the private property of a, but are creating a new public property.

We can go one further to help demonstrate this:
[php]class d extends a
{
function getprop() {
return $this->prop;
}
}[/php]

Code:
php > $d = new d(); php > echo $d->getprop(); PHP Notice: Undefined property: d::$prop in php shell code on line 4 Notice: Undefined property: d::$prop in php shell code on line 4 php >
Here we get a warning, because d cannot see the private prop, and we've not set a public one either.

It does seem a bit odd, but I don't think it is a bug. Normally you cannot have properties of the same name in a class even with different visualities. However, in b & c, they cannot see the property "prop" since it is private to a, so you can redeclare it, which is basically what is going on with your test code.

I tend to stay away from private as there is really no example I can think of where you would want to shield properties or methods from child classes, so mostly I stick to protected and public.
The only thing necessary for evil to flourish is for good men to do nothing
- Edmund Burke
     
clam2000  (op)
Dedicated MacNNer
Join Date: Aug 2002
Status: Offline
Reply With Quote
Dec 29, 2005, 08:53 PM
 
that's sort of what i figured was happening.

i just was sort of confused that php was auto creating a property I hadn't defined without generating any sort of warning.

--Will
     
madmacgames
Grizzled Veteran
Join Date: Oct 2003
Status: Offline
Reply With Quote
Dec 29, 2005, 09:18 PM
 
Originally Posted by clam2000
i just was sort of confused that php was auto creating a property I hadn't defined without generating any sort of warning.
PHP is a bit more relaxed than other languages. Variables, including object properties, do not need declared/defined before you assign them a value... you can basically think of it as assigning a variable a value also declares/defines it... so you can dynamically create object properties (and methods as well with some tricks), which can come in really handy for all kinds of things (for example a generic "settings" object that stores program settings as properties).

However, you should assign them before using them (or if you are unsure, check that they are set using isset()). It does generate a notice if you don't, just like in the class d example, "PHP Notice: Undefined property". And trying to use an undefined variable will result in a "PHP Notice: Undefined variable"

To make life easier, I find it is best to always declare any class properties. Remember private properties/methods are only visible to the class that declares them, so even though child classes *technically* do inherit them, they cannot see them (cannot read them and cannot write them). And again, I personally find it is best to avoid private when having parent/child classes and stick to protected/public in those cases. I think if you need to hide something the parent has from a child, there is probably a better way to approach the issue.
( Last edited by madmacgames; Dec 29, 2005 at 09:27 PM. )
The only thing necessary for evil to flourish is for good men to do nothing
- Edmund Burke
     
   
 
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Top
Privacy Policy
All times are GMT -4. The time now is 03:06 AM.
All contents of these forums © 1995-2017 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.8 © 2000-2017, Jelsoft Enterprises Ltd.,