__get() and __set()
Moderator: General Moderators
__get() and __set()
I've been looking at __get() and __set(). Are they really as pointless as they appear? It's good practise to define all your object's properties, and as these only work for undefined properties .. why bother with them? They seem to encourage use of undefined, and therefore public, variables.
Because they only work on undefined properties. If you've defined the property (eg public $var; or private $var; etc) then you have to write your own accessors. Using __set() will create the property, but you have no control over the scope .. it's always public. And that's not a good thing.volka wrote:Why?onion2k wrote:They seem to encourage use of undefined, and therefore public, variables.
I define a class "user".volka wrote:What's the relevant difference between "your own accessors" and those implemented in __get/set()?
I decide I want 5 variables called firstName, lastName, userName, password, and status.
I decide I want firstName, and lastName to be public.
I decide I want userName, and password to be protected,
I decide I want status to be private.
My code:
Code: Select all
class user {
public $firstName, $lastName;
protected $userName, $password;
private $status;
}If I don't define the variables then I can use __get() and __set() to read and write them, but then all of them will be public. Which is bad.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
The fact that these magic methods were implemented as error handlers is unfortunate. I don't like it either. But that's just the way it is in PHP currently and __get() and __set() give some great functionality at the cost of not having real properties.onion2k wrote:Because they only work on undefined properties. If you've defined the property (eg public $var; or private $var; etc) then you have to write your own accessors. Using __set() will create the property, but you have no control over the scope .. it's always public. And that's not a good thing.volka wrote:Why?onion2k wrote:They seem to encourage use of undefined, and therefore public, variables.
(#10850)
Code: Select all
class Foo
{
private $bar = 'foo';
public __get ($name)
{
return 'bar!';
}
}
$foo = new Foo;
echo $foo->bar;Code: Select all
bar!Code: Select all
class foo {
private $array;
public function __construct ( ) {
$this->array = new Array();
}
public function __get ( $var ) {
if ( ! array_key_exists($var) )
throw new Exception( 'Variable No Exist!' );
return $this->array[ $var ];
}
public function __set ( $var, $val ) {
$this->array[ $var ] = $val;
}
}Do we actually want properties? Here are a couple of observations from the C# world:
- Properties were 'invented' to allow RAD designers.. In essence, properties are methods, with usually relatively simple logic...
- By default every property is show in the designer. If you want to hide or limit the manipulation of properties that can be done by the browser you have to add attributes such as Browsable and ReadOnly to the property signature...
Thus it makes me wonder: Why do we need properties? To me it seems we could do equally well with functions only... And then add an attribute to the methods we want to appear in the designer.... (Compare it to access rights: only give what is needed.. Don't give root and then take away what seems unneeded
)
Notice that this is probably off-topic since it's a different discussion than the one on having __get/__set magic
- Properties were 'invented' to allow RAD designers.. In essence, properties are methods, with usually relatively simple logic...
- By default every property is show in the designer. If you want to hide or limit the manipulation of properties that can be done by the browser you have to add attributes such as Browsable and ReadOnly to the property signature...
Thus it makes me wonder: Why do we need properties? To me it seems we could do equally well with functions only... And then add an attribute to the methods we want to appear in the designer.... (Compare it to access rights: only give what is needed.. Don't give root and then take away what seems unneeded
Notice that this is probably off-topic since it's a different discussion than the one on having __get/__set magic
- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
They are really for dynamic situations with variable property names. Say, data from a DB that you may store in an array but __get() and __set() make the data available through properties. They are just accessors, and you're not really making the data public, in fact, you can make a one-way read-or-write situation using them by implementing __get() but not __set() or so forth.
I agree that 9 times out of 10 you should be using real get() and set() methods to access that data but they do come in very useful for manipulating data in complex ways.
You can also use them as nice little factories:
$document->body->setTile('foo');
They are going to come in very useful in mocking requests to properties too. I think Marcus is already working on that now.
I agree that 9 times out of 10 you should be using real get() and set() methods to access that data but they do come in very useful for manipulating data in complex ways.
You can also use them as nice little factories:
$document->body->setTile('foo');
They are going to come in very useful in mocking requests to properties too. I think Marcus is already working on that now.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
I find this question a little startling because properties are really an essential part of objects. Remember that objects are Data + Methods. But it is the data that gives each object a large part if its identity and maintains it state. I think as programmers we tend to focus on the behavior part that it is data, not us, that is important.timvw wrote:Do we actually want properties? Here are a couple of observations from the C# world:
(#10850)
I think 'properties' is meant asit's masking the get/set method calls as a simple member access.
Code: Select all
public int primaryGroup {
get {
if (!valid())
fetchUserData();
return userdata.primaryGroup;
}
set {
userdata.primaryGroup = value;
dirty();
}
}
[...]
i = obj.primaryGroup;
In my opinion they aren't very suitable for object oriented programming... Since the interface doesn't expose which properties are available (you can only find out by 'trying' if $object->property doesn't throw an exception...)d11wtq wrote:They are really for dynamic situations with variable property names.
If i'm not mistaken PHP has operator chaining since 5.0 too, so it's not very different than:d11wtq wrote: You can also use them as nice little factories:
$document->body->setTile('foo');
$document->getBody()->setTile('foo');
I think that for a decent solution of that problem you would need a language that supports introspection/reflection..d11wtq wrote: They are going to come in very useful in mocking requests to properties too. I think Marcus is already working on that now.