Forum Moderators: coopster

Message Too Old, No Replies

Calling __get()

help!

         

matthewwithanm

5:15 pm on Aug 14, 2005 (gmt 0)

10+ Year Member



I have a simple question that I just can't figure out.

class myClass {
var $attribute;
.
.
.
public function __get($name) {
return $this->$name;
}
}

According to what I'm reading, the following code

$obj = new myClass();
echo $obj->attribute;

should echo the value of the attribute variable. But for some reason, it doesn't. Instead, I need to use $obj->$attribute; (note the extra $). What could be causing this?

[edit] Even using the extra $ won't actually return a value. But at least __get() is called then.[/edit]

Thanks for the help, I really appreciate it.

matthewwithanm

6:00 pm on Aug 14, 2005 (gmt 0)

10+ Year Member



After rechecking the code, I realized that $attribute was being given an incorrect value which, for some reason, triggered this problem.

It's solved now but if anybody could point me to a reference of how __get actually works, I'd be thankful.

ergophobe

6:08 pm on Aug 14, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month




These methods will only be triggered when your object or inherited object doesn't contain the member or method you're trying to access.

See
[us2.php.net...]

So by declaring it as

var = $attribute;

you are preventing use of __get() on that member. Also, a member should be private, protected or public, not var.

matthewwithanm

11:37 pm on Aug 14, 2005 (gmt 0)

10+ Year Member



Thank you very much.

Unfortunately, for what I'm doing it would be much more convenient to allow me to process all calls to get. I wonder why this isn't allowed.

Is there any way around this? I mean, is there any way to have a class filter input provided by the __set() method? I want to set class variables this way ($obj->var) but before the value is stored, I want to make sure that it's clean.

Thanks.

matthewwithanm

4:17 am on Aug 15, 2005 (gmt 0)

10+ Year Member



I guess the best solution is to make all class attributes private and create your own get() and set() functions. This way, you can make sure that all the incoming and outgoing data is filtered.

Seems like a pretty silly oversight, though, and a detriment to encapsulation.

ergophobe

4:02 pm on Aug 17, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I more or less agree.

I don't think it's an oversight. I suspect it has to do with wanting PHP5 to behave like PHP4 in as many situations as possible or something. It also promotes a certain granularity

- public properties are set directly
- private can only be set by functions within the class, so therefore need get and set methods associated with them
- protected - ditto but can be inherited
- undefined array properties can be wholesale run through generic __get and __set

That set of privileges (for lack of a better word) doesn't seem silly or detrimental to encapsulation, but the actual implementation doesn't make sense to me. What I find odd is the decision to essentially tell people to define pseudo-properties that are, in essence, undefined. It's like saying that to achieve one type of abstraction, you do something that appears like a hack or a workaround. It seems like it would have been more clear to introduce a fourth classification like "overloaded" or something like that would be "public" from the perspective exterior to the class, but which would pass the properties through generic setters and getters and, lacking a __set(), for example, would only permit one-way access.

I know people a lot smarter than me thought their way through this and probably had a lot contstraints with respect to backward compatibility and so forth, but it does strike me as strange indeed that only undefined properties actually use __set and __get.