When Do/Should I Use _Construct(), _Get(), _Set(), and _Call() in PHP

When do/should I use __construct(), __get(), __set(), and __call() in PHP?

This page will probably be useful. (Note that what you say is incorrect - __set() takes as a parameter both the name of the variable and the value. __get() just takes the name of the variable).

__get() and __set() are useful in library functions where you want to provide generic access to variables. For example in an ActiveRecord class, you might want people to be able to access database fields as object properties. For example, in Kohana PHP framework you might use:

$user = ORM::factory('user', 1);
$email = $user->email_address;

This is accomplished by using __get() and __set().

Something similar can be accomplished when using __call(), i.e. you can detect when someone is calling getProperty() and setProperty() and handle accordingly.

PHP __get and __set magic methods

__get, __set, __call and __callStatic are invoked when the method or property is inaccessible. Your $bar is public and therefor not inaccessible.

See the section on Property Overloading in the manual:

  • __set() is run when writing data to inaccessible properties.
  • __get() is utilized for reading data from inaccessible properties.

The magic methods are not substitutes for getters and setters. They just allow you to handle method calls or property access that would otherwise result in an error. As such, there are much more related to error handling. Also note that they are considerably slower than using proper getter and setter or direct method calls.

What is the function __construct in PHP used for?

The __construct method is usually the method called in a class when an instance of that class is created (called an object). The method is called the constructor because it constructs the object, but that doesn't mean you must use the method to do so.

The point of the method is to set the variables of the object to their inital values, which may be a primitive type such as an integer, or perhaps an instance of another class. If the variables are to be something other than a default value, the __construct method can accept arguments to set the values of the variables.

You don't have to set the variables using the constructor method, nor is it the only thing you can do. You could, for example, print a success message or call another method, either in that class or elsewhere. So your two examples are both valid. The first is how you would expect the constructor to be used, but the second is still vaild. Like I said, __construct is the method that is called on creation of the object, which doesn't mean you have to use it for the intended purpose.

In PHP, it is not required to have a constructor method in a class, but in many other object orientated programming languages, such as Java, if a constructor is not present then it will produce an error at compile time. This is because PHP is what is know as a weakly typed language, which has many pros and cons which you can research further.

Because __construct is one of the magic methods specifically used in a PHP class, it cannot be converted into procedural code. To call the method with arguments, when you assign a class in your code you should give your arguments in the creation statement, like this;

$object = new MyClass($arg1,$arg2);

You cannot call the constructor from outside the class, other than when creating a new object. The only exception to this is a child class (ie, a class that extends another class) can call the constructor of its parent using parent::__construct();.

Php __get and __set magic methods - why do we need those here?

You (usually) never call __set or __get directly. $foo->bar will call $foo->__get('bar') automatically if bar is not visible and __get exists.

In the tutorial you've linked to, the getter and setter get set up to automatically call the appropriate individual get/set functions. So $foo->comment = 'bar' will indirectly call $foo->setComment('bar'). This isn't necessary... it's only a convenience.

In other cases, __get can be useful to create what looks like a read-only variable.

Why should I use PHP magic setters for constructor parameter validation

You shouldn't. IMO.

Magic setters are intended to access (set) private, protected or even virtual (non-existing) properties from outside the object.

If each one of your properties has different validation rules I can't see why you should inflate a single method in order to check them all. Better you keep your validation logic in different setter methods like you have it now.

EDIT

In the case you had some common validation rules, you should put them rules into non-public methods to re-use them from your setters.

Reasons for basic __get implementation

If you are using them just as a glorified wrapper over an array (i.e. absolutely no extra logic), I don't believe they offer any benefit. They do offer a drawback however, in that you need to write the code for them. And that code may be buggy or incomplete.

Did you leave out __isset for brevity? Because if you do use __get and __set but do not provide an __isset, you 've just written yourself a bug.

See what I did there?

Use a variable from __construct() in other methods

Declare variable $data as global inside the constructor:

 function __construct() {
global $c;
global $data;
$data = array("name"=>$c['name'],
"family"=>$c['family']);
}

Then, it will be visible in other function as well.

Note that extensive usage of global variables is strongly discouraged, consider redesigning your class to use class variables with getters+setters.

A more proper way would be to use

class testObject
{
private $data;

function __construct(array $c)
{
$this->data = array(
"name"=>$c['name'],
"family"=>$c['family']
);
}

function showInfo()
{
print_r($this->data);
}

// getter: if you need to access data from outside this class
function getData()
{
return $this->data;
}
}

Also, consider separating data fields into separate class variables, as follows. Then you have a typical, clean data class.

class testObject
{
private $name;
private $family;

function __construct($name, $family)
{
$this->name = $name;
$this->family = $family;
}

function showInfo()
{
print("name: " . $this->name . ", family: " . $this->family);
}

// getters
function getName()
{
return $this->name;
}

function getFamily()
{
return $this->family;
}

}

And you can even construct this object with data from you global variable $c until you elimitate it from your code:

new testObject($c['name'], $c['family'])

Access function from public construct in php

The error outputted when I ran your code was;

'Object of class test could not be converted to string'

There are 2 ways you can solve this problem, you can use either;

  1. Instead of the line echo($j); change it to echo($j->var0);

Now instead of trying to print the object you are now printing the public variable from the object which was set in the constructor.


  1. Add a __toString() method to your object, and use this to output the var0 field.

    class test {

    public $var0 = null;

    public function __construct() {

    $this->var0 = Tfunction('lol');

    }

    public function __toString(){

    return $this->var0;

    }

    }

    function Tfunction ($String) {

    $S = ($String . ' !');

    return $S;

    }

    $j = new test();

    echo($j);

Now when you try to print the object with echo($j); it will use the __toString() you assigned to output your variable.

Both of theses fixes mean that 'lol!' was outputted to my browser window, as was originally expected.



Related Topics



Leave a reply



Submit