PHP has made a big step forward in object-oriented programming with version 5. Since this version, it allows to implement methods in predefined behavior by PHP. These methods are called “magic methods”, the __set () and __get () are included.
We’ll be covering the following topics in this tutorial:
Reminders visibility of the properties and methods
Public access properties
Object-oriented programming lets you specify the visibility of a class methods and properties. In the case of properties, it is very advisable to give them a public visibility because that way it becomes possible to change them without that no monitoring is carried out on values.
<?php
class Kid {
public $age;
public function showAge() {
return 'His age is :'. $this-> age;
}
}
$billy = new Kid ();
$billy-> age = 'red';
echo $billy-> showAge ();
?>
This portion of code so you will return “His age is red” which, you will agree, means absolutely nothing.
Private and protected access for properties
So it is better to give them a limited visibility: private or protected.
<?php
class Kid {
private $age;
}
$billy = new Kid();
$billy-> age = "even red than before";
?>
This piece of code will return a fatal error:
Fatal error: Can not access private property Kid::$age in /path/to/Code-php/magicmethods.php on line 6.
One solution would be to create a public accessor setAge () that would specify the age by ensuring that you have passed it a number, and getAge () in order to display it.
This method is entirely feasible, provided that not having a large number of properties, the number of accessor becoming too important: you can implicitly use the magic methods __set () and __get ().
In addition, the following syntax is perfectly valid PHP:
<?php
class Kid {
}
$billy = new Kid();
$billy-> age =14;
$billy-> hair = 'black';
echo 'Billy is aged ', $billy-> age, ' years and her hair color ', $billy-> hair;
?>
And yes, you can learn and then retrieve properties in a php object without these have been declared in your class, not dirtier? It is therefore possible to “butcher” this little blunder, still implicitly using magic methods __set () and __get () to be called respectively when the property information and when trying to read the value.
Magic method __set ()
Magic method __set () to do what we call the overload of properties of a class. Indeed, when trying to fix the value of a nonexistent property of the class, PHP automatically calls this method implicitly. Here is its general structure.
<?php
class MyObject
{
/ **
* Magic Method __set ()
*
*param String $property Property name
*param Mixed $value The value to assign to the property
*return Void
* /
public function __set ($property, $value)
{
// Code to execute custom
}
}
?>
By overriding this method explicitly in the body of the class, this allows the developer to carry out access controls and ensure that only a few properties can be updated. This is what we introduce in our case of further application in this course.
Magic method __get ()
The magic __get () method, in turn, read the value of a nonexistent property of the class. Just like magic method __set (), the magic __get () method must be redefined in the class to run custom code when PHP implicitly calls this method. Again, this allows for an access control on the properties that are trying to read the values. The prototype of this method is presented below and will be further developed in the case of practical application of this tutorial.
<? php
class MyObject
{
/ **
* Method magic __get ()
*
*param String $property name of the property to achieve
*return Mixed | null
* /
public function __get ($property)
{
// Code to execute custom
}
}
?>
Practical application case
We will resume our previous example of our Kid class and we will integrate him two magic methods _get () and __set (). The objective is thus to achieve access control when trying to set or get the value of private property $age.
<?php
class Kid {
private $age;
public function __get ($property) {
if ('age' === $property) {
return $this->age;
} else {
throw new Exception ('Invalid property!');
}
}
public function __set ($property, $value) {
if ('age' === $property && ctype_digit($value)) {
$this-> age = (int) $value;
} else {
throw new Exception ('Invalid property or value!');
}
}
}
?>
In this way, it is ensured of being unable to specify the age of Billy, and nothing more. You will notice that one makes “hard” tests i.e. that we do not simply checks that $ age property exists, only that the user has attempted to specify “$age”. In addition, it controls the type of value using the ctype_digit () function that ensures that the format of the value corresponds to an integer.
It is quite possible to retrieve the properties of an object, but to do this properly, it is best to use reflection classes.