-3

Possible Duplicate:
PHP __get and __set magic methods

Just starting with OOP. . Anyway not sure if I understand it correctly but shouldn't the code not change the value of $attribute, because of function __set()?

<?php
class aclass
{
    protected $attribute; //edited from public to protected
    public function __get ($name)
    {
        return $this->$name;    
    }
    public function __set ($name, $value)
    {
        if($name == "foo")
        {
            $this->$name = $value;
        }
    }
} 
$a = new aclass();
$a->attribute = "bar";
echo $a->attribute;
?>

When I run this an error message shows:

"Fatal error: Cannot access protected property aclass::$attribute . . . on line 16" Line 16 is "echo $a->attribute" - Other posts say that the attribute must be set to PROTECTED but its not working. Im using PHP 5.4.3 - Any ideas?

Community
  • 1
  • 1
Jo E.
  • 6,278
  • 11
  • 44
  • 79
  • 1
    You should check other questions like http://stackoverflow.com/questions/4713680/php-get-and-set-magic-methods – Deele Jan 22 '13 at 12:02
  • This is been asked many times before, please do a long search before opening a question. – Wouter J Jan 22 '13 at 12:05
  • 2
    if you're just starting with OOP, I'd suggest leaving `__get` and `__set` for later; they're useful but not compulsory to learn in the first case; get a good grasp of the major concepts, and come back to the magic methods later. Some people dislike them and stick to writing individual methods named `getPropname()` and `setPropname()`; this might be an easier way to get started. Also, the forthcoming PHP version 5.5 will provide more syntax options for defining properties which will mean there's a lot less need for the magic methods. – SDC Jan 22 '13 at 12:08
  • Sorry the book I'm reading talked about it and it wasn't very clear and it used a lot of it so I just had to understand it. When I read the php manual I got lost even more. I posted a question about it cause the results I got when I made a search was a little too deep for what I was looking for. @Deele's link is a help thanks. Thanks for the tip too @SDC! – Jo E. Jan 22 '13 at 12:35
  • This is not about OOP. It's about basic language features and visibility. – tereško Jan 22 '13 at 19:09

2 Answers2

5

Your __set() magic method will be invoked only when trying to access non-public or undefined properties, but the attribute property IS defined and IS public, so it is accessed directly.

If you want the __set() method to "intecept" accesses to attribute, it must be made protected or private.

Matteo Tassinari
  • 16,776
  • 5
  • 55
  • 77
  • It also fires for undefined properties – Dale Jan 22 '13 at 12:06
  • 1
    @Dale thanks, answer updated! – Matteo Tassinari Jan 22 '13 at 12:14
  • Setting $attribute to protected or private isn't working. It gives out an error: "cannot access protected property". Any ideas on this? I went to the suggested link above on the same topic but the same answers which is to not set the attribute to public but to protected or private. What am I missing? – Jo E. Jan 22 '13 at 13:08
  • I just tried it by replacing `public $attribute` with `protected $attribute` and it works correctly for me. – Matteo Tassinari Jan 22 '13 at 13:11
  • I also tried that. Same code but replaced public with protected. It says cannot access PROTECTED PROPERTY aclass::$attribute ... on line 20. Which is echo $a->attribute; any ideas? – Jo E. Jan 22 '13 at 13:20
  • Please update your question with this modified code you are trying and the PHP version used. – Matteo Tassinari Jan 22 '13 at 13:29
  • @MatteoTassinari updated and posted the PHP version I'm using . . – Jo E. Jan 22 '13 at 13:43
  • 1
    Tried it and it gave no error, see http://sandbox.onlinephpfunctions.com/code/7983f20fa41dc5d12f879bce27852cd75a1068fb – Matteo Tassinari Jan 22 '13 at 13:49
  • Yeah it worked after I restarted my laptop. Don't know what happened but its working now. Thanks for the help @MatteoTassinari! – Jo E. Jan 22 '13 at 14:03
1

__set() will be called when you try to assign value to an undefined property. In your case the $attribute is already defined with class hence __set will not be called.

sunlight
  • 138
  • 1
  • 8
  • 1
    this is not true. It will be invoked when trying to access a private or protected property, see @MatteoTassinari 's anwser – Wouter J Jan 22 '13 at 12:04
  • @WouterJ This is actually true and should be merged with the other answer – Dale Jan 22 '13 at 12:05
  • @Dale ok, I was a bit to quick. This is correct, while it doesn't answer the question. I have removed my downvote. – Wouter J Jan 22 '13 at 12:06
  • @WouterJ I wonder what the access level of the newly created property is when doing it via __set() ? hmm..., after a quick test it appears to be "public" which is funny because then it can't be access via __set() again, lol, PHP – Dale Jan 22 '13 at 12:07
  • @Dale yes, I just found the same answer. That doesn't look correct... – Wouter J Jan 22 '13 at 12:20