bnrfly
bnrfly

Reputation: 165

function __get() not giving any effect in PHP

So I'm following a tutorial about OOP in PHP and got stuck in understanding how __get() function works. Here's the code:

<?php

class Animal{

    protected $name;
    protected $favorite_food;
    protected $sound;
    protected $id;

    public static $number_of_animals = 0;
    const PI = "3.14159";

    //function to return the name
    //encapsulation
    function getName(){

        //when you want to refer attribute in a class
        return $this->name;

    }

    //initialize things
    function __construct(){

        //generate random 100-10 
        $this->id = rand(1,10);
        echo $this->id ." has been assigned<br/>";

        //akses static attribute in a class
        Animal::$number_of_animals++;

    }

    //destruct the object
    function __destruct(){

        echo $this->name ." is being destroyed :(";

    }

    //getter : to get protected attribute of a function
    function __get($name){
        echo "Asked for " . $name . "<br/>";
        return $this->$name;
    }

    //setter : set the attribute to 
    function __set($name, $value){

        switch($name){

            case "name" :
                $this->name = $value;
                break;
            case "favorite_food" :
                $this->favorite_food = $value;
                break;
            case "sound" :
                $this->sound = $value;
                break;

            default :
                echo $name ."Name not found";
        }

        echo "Set " .$name. " to " .$value. "<br/>";
    }

    function run(){
        echo $this->name. " runs<br/>";
    }
}

class Dog extends Animal{

    function run(){
        echo $this->name. " runs like crazy<br/>";
    }   

}

$animal_one = new Animal();

$animal_one->name = " SPOT";
$animal_one->favorite_food = " MEAT";
$animal_one->sound = " RUFF";

echo $animal_one->name ." says". $animal_one->sound. " give me some " .$animal_one->favorite_food. " my id is " .$animal_one->id. " total animal is " .Animal::$number_of_animals. "<br/><br/>";

?>

The output will be like this :

5 has been assigned
Set name to SPOT
Set favorite_food to MEAT
Set sound to RUFF
Asked for name
Asked for sound
Asked for favorite_food
Asked for id
SPOT says RUFF give me some MEAT my id is 5 total animal is 1

SPOT is being destroyed :(

When I try to change the argument and value in __get() function to another attribute like $sound or $favorite_food, it doesn't give any change to the output. The output will still the same. I don't get it why we should set it only to $name.

Upvotes: 1

Views: 96

Answers (1)

Jeff Puckett
Jeff Puckett

Reputation: 40861

The name of the parameter inside any function is scoped to that function alone, and doesn't have any reference anywhere else.

You're probably getting confused in that your local function parameter $name has the same name as one of it's class properties $this->name

Notice in your __get method, $name is a stand-in variable for what could be any protected/private property, which is dynamically evaluated at run-time:

$this->$name

as opposed to a hard-coded property

$this->name

Consider this example:

class MyClass {
    protected $one  = 'first';
    protected $name = 'fred';

    public function __get(String $property){
        return $this->$property;
    }

    public function getOne(){
        return $this->one;
    }

    public function foo(String $variable_could_be_named_anything){
        return $variable_could_be_named_anything;
    }
}

$object = new MyClass;

echo $object->one; // first (using __get)
echo $object->getOne(); // first

$object->two = 'second'; // because this property isn't declared protected, accessed normally
echo $object->two; // second

$name = 'jon';
echo $object->name; // fred
echo $object->foo($name); // jon

echo $object->three; // PHP Notice:  Undefined property: MyClass::$three
$object->one = 'something'; // Fatal error:  Cannot access protected property

Upvotes: 2

Related Questions