|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
I've been doing a bunch of reading about objects and overloading in
PHP5, but I've got a couple of questions that I can't seem to find the answer to online. Suppose the following code in PHP5.2.4: <?php class foo { public $x; private $z = 'z'; public function __set ($name, $val) { echo "Setting \$this->$name to $val...\n"; $this->{$name} = $val; } public function __get ($name) { return "The value of $name is {$this->{$name}}.\n"; } } ?> My questions are as follows: 1) It seems that the getter and setter are not called on every single call. For example, if I do the following: $bar = new foo; $bar->x = 'x'; There is no output. I would expect to see "Setting $this->x to x." Another example: $bar = new foo; $bar->y = 'y'; echo $bar->y; I would expect this to see "The value of y is y." but instead I just get 'y' as output. So when do the various setters/getters get used? 2) It seems that getters ignore the visibility of properties. Why is this? For example: $bar = new foo; echo $bar->z; I would expect this to throw an error about accessing a private member, but it outputs "The value of z is z." just fine. If I remove the __get() overloader, an error is thrown. I'm guessing that the answer to all of my questions is some how wrapped up in visibility and overloading. Unfortunately I cannot find any resource that documents the interactions. TIA. |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
> 1) It seems that the getter and setter are not called on every single
> call. For example, if I do the following: > > $bar = new foo; > $bar->x = 'x'; > > There is no output. I would expect to see "Setting $this->x to x." > Another example: > > $bar = new foo; > $bar->y = 'y'; > echo $bar->y; > > I would expect this to see "The value of y is y." but instead I just > get 'y' as output. So when do the various setters/getters get used? > > 2) It seems that getters ignore the visibility of properties. Why is > this? For example: > > $bar = new foo; > echo $bar->z; > > I would expect this to throw an error about accessing a private > member, but it outputs "The value of z is z." just fine. If I remove > the __get() overloader, an error is thrown. > > I'm guessing that the answer to all of my questions is some how > wrapped up in visibility and overloading. Unfortunately I cannot find > any resource that documents the interactions. TIA. > As I understand it, the __get and __set do not ignore visibility; rather, they only work for accessing private members. If a property is declared public, it does not need the __get and __set, so they aren't used. Likewise, $bar->y is public since it was added dynamically outside the class. Andrew |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Steve Brown wrote:
> I've been doing a bunch of reading about objects and overloading in > PHP5, but I've got a couple of questions that I can't seem to find the > answer to online. Suppose the following code in PHP5.2.4: > > <?php > class foo { > public $x; > private $z = 'z'; > > public function __set ($name, $val) { > echo "Setting \$this->$name to $val...\n"; > $this->{$name} = $val; > } > > public function __get ($name) { > return "The value of $name is {$this->{$name}}.\n"; > } > } > ?> > > My questions are as follows: > > 1) It seems that the getter and setter are not called on every single > call. For example, if I do the following: > > $bar = new foo; > $bar->x = 'x'; > > There is no output. I would expect to see "Setting $this->x to x." remove "public $x" and it works. __set() is only called for non-existent variables. > Another example: > > $bar = new foo; > $bar->y = 'y'; > echo $bar->y; > > I would expect this to see "The value of y is y." but instead I just > get 'y' as output. So when do the various setters/getters get used? again, because your code sets $y with $this->{$name} = $value, the variable $y now exists, and so __get() is not called. If you're using normal variables, then you don't need setters/getters. Instead, if you store the values inside an internal array (for instance), then a setter/getter can to abstract the array contents. For instance, this class: http://svn.pear.php.net/wsvn/PEARSVN...ile&rev=0&sc=0 (which is under development currently for the next incarnation of the PEAR installer) allows logical manipulation of maintainers of a package within package.xml. Instead of either direct array manipulation or the old way, which was a complex method call that is easy to mis-order: $pf->addMaintainer('cellog', 'Greg Beaver', 'cellog@php.net', 'yes'); One can do: $pf->maintainer['cellog'] ->name('Greg Beaver') ->email('cellog@php.net') ->active('yes'); and then values can be retrieved using normal stuff like: echo $pf->maintainer['cellog']->email; The entire time, the class is abstracting stuff that would be really complex as it is actually accessing the underlying XML of the package.xml directly when making the modifications. The examples you give don't need this kind of complexity. > 2) It seems that getters ignore the visibility of properties. Why is > this? For example: > > $bar = new foo; > echo $bar->z; > > I would expect this to throw an error about accessing a private > member, but it outputs "The value of z is z." just fine. If I remove > the __get() overloader, an error is thrown. private properties simply don't exist outside the class, so you can create public properties on external access with impunity. You should open a documentation bug for this at bugs.php.net Greg |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Tuesday 18 September 2007, Andrew Ballard wrote:
> > I'm guessing that the answer to all of my questions is some how > > wrapped up in visibility and overloading. Unfortunately I cannot find > > any resource that documents the interactions. TIA. > > As I understand it, the __get and __set do not ignore visibility; > rather, they only work for accessing private members. If a property is > declared public, it does not need the __get and __set, so they aren't > used. Likewise, $bar->y is public since it was added dynamically > outside the class. > > Andrew Untrue. If a property exists, then it is used as-is and __get()/__set()/__isset()/__unset() are never called. The property behaves normally, as if those methods were not defined. If they're not defined, the magic methods do whatever they do, which can include adding more properties to the object if appropriate (thus bypassing the magic methods in the future). -- Larry Garfield AIM: LOLG42 larry@garfieldtech.com ICQ: 6817012 "If nature has made any one thing less susceptible than all others of exclusive property, it is the action of the thinking power called an idea, which an individual may exclusively possess as long as he keeps it to himself; but the moment it is divulged, it forces itself into the possession of every one, and the receiver cannot dispossess himself of it." -- Thomas Jefferson |
|
![]() |
| Outils de la discussion | |
|
|