Магические методы
Имена методов __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() и __debugInfo() зарезервированы для "магических" методов в PHP. Не стоит называть свои методы этими именами, если вы не хотите использовать их "магическую" функциональность.
PHP оставляет за собой право все методы, начинающиеся с __, считать "магическими". Не рекомендуется использовать имена методов с __ в PHP, если вы не желаете использовать соответствующий "магический" функционал.
__sleep() и __wakeup()
Функция serialize() проверяет, присутствует ли в вашем классе метод с "магическим" именем __sleep(). Если это так, то этот метод выполняется прежде любой операции сериализации. Он может очистить объект и предполагается, что будет возвращен массив с именами всех переменных объекта, который должен быть сериализован. Если метод ничего не возвращает кроме NULL , то это значит, что объект сериализован и выдается предупреждение E_NOTICE .
Замечание:
Недопустимо возвращать в __sleep() имена приватных свойств объекта в родительский класс. Это приведет к предупреждению E_NOTICE . Вместо этого вы можете использовать интерфейс Serializable.
Рекомендованное использование __sleep() состоит в завершении работы над данными, ждущими обработки или других подобных задач очистки. Кроме того, этот метод можно выполнять в тех случаях, когда нет необходимости сохранять полностью очень большие объекты.
С другой стороны, функция unserialize() проверяет наличие метода с "магическим" именем __wakeup(). Если такой имеется, то он может воссоздать все ресурсы объекта, принадлежавшие ему.
Обычно __wakeup() используется для восстановления любых соединений с базой данных, которые могли быть потеряны во время операции сериализации и выполнения других операций повторной инициализации.
Пример #1 Sleep и wakeup
<?php
class Connection
<
protected $link ;
private $dsn , $username , $password ;
public function __construct ( $dsn , $username , $password )
<
$this -> dsn = $dsn ;
$this -> username = $username ;
$this -> password = $password ;
$this -> connect ();
>
private function connect ()
<
$this -> link = new PDO ( $this -> dsn , $this -> username , $this -> password );
>
public function __sleep ()
<
return array( ‘dsn’ , ‘username’ , ‘password’ );
>
public function __wakeup ()
<
$this -> connect ();
>
> ?>
__toString()
Метод __toString() позволяет классу решать самостоятельно, как он должен реагировать при преобразовании в строку. Например, что напечатает echo $obj;. Этот метод должен возвращать строку, иначе выдастся неисправимая ошибка E_RECOVERABLE_ERROR .
Нельзя бросить исключение из метода __toString(). Попытка это сделать закончится фатальной ошибкой.
Пример #2 Простой пример
<?php
// Объявление простого класса
class TestClass
<
public $foo ;
public function __construct ( $foo )
<
$this -> foo = $foo ;
>
public function __toString ()
<
return $this -> foo ;
>
>
$class = new TestClass ( ‘Привет’ );
echo $class ;
?>
Результат выполнения данного примера:
Ранее, до PHP 5.2.0, метод __toString() вызывался только непосредственно в сочетании с функциями echo или print . Начиная с PHP 5.2.0, он вызывается в любом строчном контексте (например, в printf() с модификатором %s), но не в контекстах других типов (например, с %d модификатором). Начиная с PHP 5.2.0, преобразование объекта в строку при отсутствии метода __toString() вызывает ошибку E_RECOVERABLE_ERROR .
__invoke()
Метод __invoke() вызывается, когда скрипт пытается выполнить объект как функцию.
Замечание:
Данный метод доступен начиная с PHP 5.3.0.
# Magic Methods
__call() and __callStatic() are called when somebody is calling nonexistent object method in object or static context.
# Example:
# __get(), __set(), __isset() and __unset()
Whenever you attempt to retrieve a certain field from a class like so:
PHP invokes the magic method __get($name) , with $name equal to "height" in this case. Writing to a class field like so:
Will invoke the magic method __set($name, $value) , with $name equal to "height" and $value equal to 10 .
PHP also has two built-in functions isset() , which check if a variable exists, and unset() , which destroys a variable. Checking whether a objects field is set like so:
Will invoke the __isset($name) function on that object. Destroying a variable like so:
Will invoke the __unset($name) function on that object.
Normally, when you don’t define these methods on your class, PHP just retrieves the field as it is stored in your class. However, you can override these methods to create classes that can hold data like an array, but are usable like an object:
# empty() function and magic methods
Note that calling empty()
(opens new window) on a class attribute will invoke __isset() because as the PHP manual states:
empty() is essentially the concise equivalent to !isset($var) || $var == false
# __construct() and __destruct()
__construct() is the most common magic method in PHP, because it is used to set up a class when it is initialized. The opposite of the __construct() method is the __destruct() method. This method is called when there are no more references to an object that you created or when you force its deletion. PHP’s garbage collection will clean up the object by first calling its destructor and then removing it from memory.
# __toString()
Whenever an object is treated as a string, the __toString() method is called. This method should return a string representation of the class.
# __clone()
__clone is invoked by use of the clone keyword. It is used to manipulate object state upon cloning, after the object has been actually cloned.
# __invoke()
This magic method is called when user tries to invoke object as a function. Possible use cases may include some approaches like functional programming or some callbacks.
# __sleep() and __wakeup()
__sleep and __wakeup are methods that are related to the serialization process. serialize function checks if a class has a __sleep method. If so, it will be executed before any serialization. __sleep is supposed to return an array of the names of all variables of an object that should be serialized.
__wakeup in turn will be executed by unserialize if it is present in class. It’s intention is to re-establish resources and other things that are needed to be initialized upon unserialization.
# __debugInfo()
This method is called by var_dump() when dumping an object to get the properties that should be shown. If the method isn’t defined on an object, then all public, protected and private properties will be shown. — PHP Manual
Какие магические методы вы знаете и как их применяют php
Магические методы — это специальные методы, которые переопределяют действие PHP по умолчанию, когда над объектом выполняются определённые действия.
Все имена методов, начинающиеся с __ , зарезервированы PHP. Не рекомендуется использовать имена методов с __ в PHP, если вы не хотите использовать соответствующую магическую функциональность.
Все магические методы, за исключением __construct(), __destruct() и __clone(), ДОЛЖНЫ быть объявлены как public , в противном случае будет вызвана ошибка уровня E_WARNING . До PHP 8.0.0 для магических методов __sleep(), __wakeup(), __serialize(), __unserialize() и __set_state() не выполнялась проверка.
Если объявления типа используются в определении магического метода, они должны быть идентичны сигнатуре, описанной в этом документе. В противном случае выдаётся фатальная ошибка. До PHP 8.0.0 диагностические сообщения не отправлялись. Однако __construct() и __destruct() не должны объявлять возвращаемый тип; в противном случае выдаётся фатальная ошибка.
__sleep() и __wakeup()
Функция serialize() проверяет, присутствует ли в классе метод с магическим именем __sleep(). Если это так, то этот метод выполняется до любой операции сериализации. Он может очистить объект и должен возвращать массив с именами всех переменных этого объекта, которые должны быть сериализованы. Если метод ничего не возвращает, то сериализуется null и выдаётся предупреждение E_NOTICE .
Замечание:
Недопустимо возвращать в __sleep() имена закрытых свойств в родительском классе. Это приведёт к ошибке уровня E_NOTICE . Вместо этого вы можете использовать __serialize().
Предполагаемое использование __sleep() состоит в завершении работы над данными, ждущими обработки или других подобных задач очистки. Кроме того, этот метод может быть полезен, когда есть очень большие объекты, которые нет необходимости полностью сохранять.
С другой стороны, функция unserialize() проверяет наличие метода с магическим именем __wakeup(). Если она имеется, эта функция может восстанавливать любые ресурсы, которые может иметь объект.
Предполагаемое использование __wakeup() заключается в восстановлении любых соединений с базой данных, которые могли быть потеряны во время операции сериализации и выполнения других операций повторной инициализации.
Пример #1 Сериализация и десериализация
<?php
class Connection
<
protected $link ;
private $dsn , $username , $password ;
public function __construct ( $dsn , $username , $password )
<
$this -> dsn = $dsn ;
$this -> username = $username ;
$this -> password = $password ;
$this -> connect ();
>
private function connect ()
<
$this -> link = new PDO ( $this -> dsn , $this -> username , $this -> password );
>
public function __sleep ()
<
return array( ‘dsn’ , ‘username’ , ‘password’ );
>
public function __wakeup ()
<
$this -> connect ();
>
> ?>
__serialize() и __unserialize()
serialize() проверяет, есть ли в классе функция с магическим именем __serialize(). Если да, функция выполняется перед любой сериализацией. Она должна создать и вернуть ассоциативный массив пар ключ/значение, которые представляют сериализованную форму объекта. Если массив не возвращён, будет выдано TypeError .
Замечание:
Если и __serialize() и __sleep() определены в одном и том же объекте, будет вызван только метод __serialize(). __sleep() будет игнорироваться. Если объект реализует интерфейс Serializable, метод serialize() интерфейса будет игнорироваться, а вместо него будет использован __serialize().
Предполагаемое использование __serialize() заключается в определении удобного для сериализации произвольного представления объекта. Элементы массива могут соответствовать свойствам объекта, но это не обязательно.
И наоборот, unserialize() проверяет наличие магической функции __unserialize(). Если функция присутствует, ей будет передан восстановленный массив, который был возвращён из __serialize(). Затем он может восстановить свойства объекта из этого массива соответствующим образом.
Замечание:
Если и __unserialize() и __wakeup() определены в одном и том же объекте, будет вызван только метод __unserialize(). __wakeup() будет игнорироваться.
Замечание:
Функция доступна с PHP 7.4.0.
Пример #2 Сериализация и десериализация
<?php
class Connection
<
protected $link ;
private $dsn , $username , $password ;
public function __construct ( $dsn , $username , $password )
<
$this -> dsn = $dsn ;
$this -> username = $username ;
$this -> password = $password ;
$this -> connect ();
>
private function connect ()
<
$this -> link = new PDO ( $this -> dsn , $this -> username , $this -> password );
>
public function __serialize (): array
<
return [
‘dsn’ => $this -> dsn ,
‘user’ => $this -> username ,
‘pass’ => $this -> password ,
];
>
public function __unserialize (array $data ): void
<
$this -> dsn = $data [ ‘dsn’ ];
$this -> username = $data [ ‘user’ ];
$this -> password = $data [ ‘pass’ ];
__toString()
Метод __toString() позволяет классу решать, как он должен реагировать при преобразовании в строку. Например, что вывести при выполнении echo $obj; .
Начиная с PHP 8.0.0, возвращаемое значение следует стандартной семантике типа PHP, что означает, что оно будет преобразовано в строку ( string ), если возможно, и если strict typing отключён.
Начиная с PHP 8.0.0, любой класс, содержащий метод __toString(), также будет неявно реализовывать интерфейс Stringable и, таким образом, будет проходить проверку типа для этого интерфейса В любом случае рекомендуется явно реализовать интерфейс.
В PHP 7.4 возвращаемое значение ДОЛЖНО быть строкой ( string ), иначе выдаётся Error .
До PHP 7.4.0 возвращаемое значение должно быть строкой ( string ), в противном случае выдаётся фатальная ошибка E_RECOVERABLE_ERROR . is emitted.
Нельзя выбросить исключение из метода __toString() до PHP 7.4.0. Это приведёт к фатальной ошибке.
Пример #3 Простой пример
<?php
// Объявление простого класса
class TestClass
<
public $foo ;
public function __construct ( $foo )
<
$this -> foo = $foo ;
>
public function __toString ()
<
return $this -> foo ;
>
>
$class = new TestClass ( ‘Привет’ );
echo $class ;
?>
Результат выполнения данного примера:
__invoke()
Метод __invoke() вызывается, когда скрипт пытается выполнить объект как функцию.
Пример #4 Использование __invoke()
Результат выполнения данного примера:
Пример #5 Пример использования __invoke()
<?php
class Sort
<
private $key ;
public function __construct ( string $key )
<
$this -> key = $key ;
>
public function __invoke (array $a , array $b ): int
<
return $a [ $this -> key ] <=> $b [ $this -> key ];
>
>
$customers = [
[ ‘id’ => 1 , ‘first_name’ => ‘John’ , ‘last_name’ => ‘Do’ ],
[ ‘id’ => 3 , ‘first_name’ => ‘Alice’ , ‘last_name’ => ‘Gustav’ ],
[ ‘id’ => 2 , ‘first_name’ => ‘Bob’ , ‘last_name’ => ‘Filipe’ ]
];
// сортировка клиентов по имени
usort ( $customers , new Sort ( ‘first_name’ ));
print_r ( $customers );
// сортировка клиентов по фамилии
usort ( $customers , new Sort ( ‘last_name’ ));
print_r ( $customers );
?>
Результат выполнения данного примера:
__set_state()
Этот статический метод вызывается для тех классов, которые экспортируются функцией var_export() .
Единственным параметром этого метода является массив, содержащий экспортируемые свойства в виде ['property' => value, . ] .
Пример #6 Использование __set_state()
class A
<
public $var1 ;
public $var2 ;
public static function __set_state ( $an_array )
<
$obj = new A ;
$obj -> var1 = $an_array [ ‘var1’ ];
$obj -> var2 = $an_array [ ‘var2’ ];
return $obj ;
>
>
$a = new A ;
$a -> var1 = 5 ;
$a -> var2 = ‘foo’ ;
$b = var_export ( $a , true );
var_dump ( $b );
eval( ‘$c = ‘ . $b . ‘;’ );
var_dump ( $c );
?>
Результат выполнения данного примера:
Замечание: При экспорте объекта var_export() не проверяет, реализует ли класс объекта метод __set_state(), поэтому повторный импорт объектов приведёт к исключению Error , если метод __set_state() не реализован. В частности, это относится к некоторым внутренним классам. Необходимость проверки, реализует ли импортируемый класс метод __set_state(), полностью лежит на разработчике.
__debugInfo()
Этот метод вызывается функцией var_dump() , когда необходимо вывести список свойств объекта. Если этот метод не определён, тогда будут выведены все свойства объекта c модификаторами public, protected и private.
Пример #7 Использование __debugInfo()
<?php
class C <
private $prop ;
public function __construct ( $val ) <
$this -> prop = $val ;
>
public function __debugInfo () <
return [
‘propSquared’ => $this -> prop ** 2 ,
];
>
>
var_dump (new C ( 42 ));
?>
Результат выполнения данного примера:
User Contributed Notes 30 notes
The __toString() method is extremely useful for converting class attribute names and values into common string representations of data (of which there are many choices). I mention this as previous references to __toString() refer only to debugging uses.
I have previously used the __toString() method in the following ways:
— representing a data-holding object as:
— XML
— raw POST data
— a GET query string
— header name:value pairs
— representing a custom mail object as an actual email (headers then body, all correctly represented)
When creating a class, consider what possible standard string representations are available and, of those, which would be the most relevant with respect to the purpose of the class.
Being able to represent data-holding objects in standardised string forms makes it much easier for your internal representations of data to be shared in an interoperable way with other applications.
Be very careful to define __set_state() in classes which inherit from a parent using it, as the static __set_state() call will be called for any children. If you are not careful, you will end up with an object of the wrong type. Here is an example:
public static function __set_state ( $an_array )
<
$obj = new A ;
$obj -> var1 = $an_array [ ‘var1’ ];
return $obj ;
>
>
class B extends A <
>
$b = new B ;
$b -> var1 = 5 ;
eval( ‘$new_b = ‘ . var_export ( $b , true ) . ‘;’ );
var_dump ( $new_b );
/*
object(A)#2 (1) <
[«var1»]=>
int(5)
>
*/
?>
__debugInfo is also utilised when calling print_r on an object:
$ cat test.php
<?php
class FooQ <
public function __construct ( $val ) <
public function __debugInfo ()
<
return [ ‘_bar’ => $this -> bar ];
>
>
$fooq = new FooQ ( «q» );
print_r ( $fooq );
$ php test . php
FooQ Object
(
[ _bar ] => q
)
$
IMHO a bug or need feature change
providing a object as a array index doesn’t try to us __toString() method so some volatile object identifier is used to index the array, which is breaking any persistency. Type hinting solves that, but while other than «string» type hinting doesn’t work on ob jects, the automatic conversion to string should be very intuitive.
PS: tried to submit bug, but withot patch the bugs are ignored, unfortunately, I don’t C coding
protected $shop_name ;
protected $product_id ;
function __construct ( $shop_name , $product_id ) <
$this -> shop_name = $shop_name ;
$this -> product_id = $product_id ;
>
function __toString () <
return $this -> shop_name . ‘:’ . $this -> product_id ;
>
>
$shop_name = ‘Shop_A’ ;
$product_id = 123 ;
$demo_id = $shop_name . ‘:’ . $product_id ;
$demo_name = ‘Some product in shop A’ ;
$all_products = [ $demo_id => $demo_name ];
$pid = new shop_product_id ( $shop_name , $product_id );
echo «with type hinting: » ;
echo ( $demo_name === $all_products [(string) $pid ]) ? «ok» : «fail» ;
echo «\n» ;
echo «without type hinting: » ;
echo ( $demo_name === $all_products [ $pid ]) ? «ok» : «fail» ;
echo «\n» ;
If you use the Magical Method ‘__set()’, be shure that the call of
<?php
$myobject -> test [ ‘myarray’ ] = ‘data’ ;
?>
will not appear!
For that u have to do it the fine way if you want to use __set Method 😉
<?php
$myobject -> test = array( ‘myarray’ => ‘data’ );
?>
If a Variable is already set, the __set Magic Method already wont appear!
My first solution was to use a Caller Class.
With that, i ever knew which Module i currently use!
But who needs it. :]
There are quiet better solutions for this.
Here’s the Code:
<?php
class Caller <
public $caller ;
public $module ;
function __call ( $funcname , $args = array()) <
$this -> setModuleInformation ();
if ( is_object ( $this -> caller ) && function_exists ( ‘call_user_func_array’ ))
$return = call_user_func_array (array(& $this -> caller , $funcname ), $args );
else
trigger_error ( «Call to Function with call_user_func_array failed» , E_USER_ERROR );
$this -> unsetModuleInformation ();
return $return ;
>
function __construct ( $callerClassName = false , $callerModuleName = ‘Webboard’ ) <
if ( $callerClassName == false )
trigger_error ( ‘No Classname’ , E_USER_ERROR );
$this -> module = $callerModuleName ;
if ( class_exists ( $callerClassName ))
$this -> caller = new $callerClassName ();
else
trigger_error ( ‘Class not exists: \» . $callerClassName . ‘\» , E_USER_ERROR );
if ( is_object ( $this -> caller ))
<
$this -> setModuleInformation ();
if ( method_exists ( $this -> caller , ‘__init’ ))
$this -> caller -> __init ();
$this -> unsetModuleInformation ();
>
else
trigger_error ( ‘Caller is no object!’ , E_USER_ERROR );
>
function __destruct () <
$this -> setModuleInformation ();
if ( method_exists ( $this -> caller , ‘__deinit’ ))
$this -> caller -> __deinit ();
$this -> unsetModuleInformation ();
>
function __isset ( $isset ) <
$this -> setModuleInformation ();
if ( is_object ( $this -> caller ))
$return = isset( $this -> caller ->< $isset >);
else
trigger_error ( ‘Caller is no object!’ , E_USER_ERROR );
$this -> unsetModuleInformation ();
return $return ;
>
function __unset ( $unset ) <
$this -> setModuleInformation ();
if ( is_object ( $this -> caller )) <
if (isset( $this -> caller ->< $unset >))
unset( $this -> caller ->< $unset >);
>
else
trigger_error ( ‘Caller is no object!’ , E_USER_ERROR );
$this -> unsetModuleInformation ();
>
function __set ( $set , $val ) <
$this -> setModuleInformation ();
if ( is_object ( $this -> caller ))
$this -> caller -> < $set >= $val ;
else
trigger_error ( ‘Caller is no object!’ , E_USER_ERROR );
$this -> unsetModuleInformation ();
>
function __get ( $get ) <
$this -> setModuleInformation ();
if ( is_object ( $this -> caller )) <
if (isset( $this -> caller ->< $get >))
$return = $this -> caller ->< $get >;
else
$return = false ;
>
else
trigger_error ( ‘Caller is no object!’ , E_USER_ERROR );
$this -> unsetModuleInformation ();
return $return ;
>
function setModuleInformation () <
$this -> caller -> module = $this -> module ;
>
function unsetModuleInformation () <
$this -> caller -> module = NULL ;
>
>
// Well this can be a Config Class?
class Config <
public $module ;
function __construct ()
<
print( ‘Constructor will have no Module Information. Use __init() instead!<br />’ );
print( ‘—> ‘ . print_r ( $this -> module , 1 ). ‘ <—‘ );
print( ‘<br />’ );
print( ‘<br />’ );
$this -> test = ‘123’ ;
>
function __init ()
<
print( ‘Using of __init()!<br />’ );
print( ‘—> ‘ . print_r ( $this -> module , 1 ). ‘ <—‘ );
print( ‘<br />’ );
print( ‘<br />’ );
>
function testFunction ( $test = false )
<
if ( $test != false )
$this -> test = $test ;
>
>
echo( ‘<pre>’ );
$wow = new Caller ( ‘Config’ , ‘Guestbook’ );
print_r ( $wow -> test );
print( ‘<br />’ );
print( ‘<br />’ );
$wow -> test = ‘456’ ;
print_r ( $wow -> test );
print( ‘<br />’ );
print( ‘<br />’ );
$wow -> testFunction ( ‘789’ );
print_r ( $wow -> test );
print( ‘<br />’ );
print( ‘<br />’ );
print_r ( $wow -> module );
echo( ‘</pre>’ );
?>
Outputs something Like:
Constructor will have no Module Information. Use __init() instead!
—> <—
Constructor and Magic methods

It is time to sprinkle some stardust over this article.
I am sure you have already come across some strange symbols in your web development career.
In this particular case,
I am talking about methods that have two weird underscores (__) prefixed to the original name.
Those are called “Magic Methods” and they are used in Object Oriented programming, allowing you to respond to specified circumstances when using a specific object.
In simple words, these methods specify how to react in those occasions.
The Constructor
The constructor is probably the most used magic method in PHP.
There are several design patterns that take advantage of the function of this method,
It is defined by the command:
function __construct()
If a class has this method it is going to be invoked every time a new object will be instantiated.
When using the constructor method, the behavior of the class change depending on if the class is a child or not.
If the child class does not specify a constructor the object’s behavior will be inherited from the parent like the other method you have already seen previously.
You can also overwrite the behavior specifically or load the parent behavior and edited as you prefer.
What happens when a new apartment block is being constructed?
The manager of the building needs to make some money to cover its expenses.
To do that he starts looking for tenants.
Here is how you can do that in the code
On the instantiation of our apartment located in $mainStreet1025 the program will automatically output the defined lines.
If the code examples in this post seem a bit too complicated or you just want to go over the syntax used above, you can take a look at the basics of PHP
Dependency injection
Some among the more expert of you might be wondering why I haven’t explained what dependency injection is yet, some other have been surely looking weirdly to that parenthesis affixed to the methods’ names asking what they mean and why they are there.
That moment has arrived.
Jeffrey Way, the curator of Laracasts, has a theory that I want to share with you:

Do you know how are called the smallest stars in the universe?
Can you tell me what’s the name of the region of the spacetime exhibiting such strong gravitational effects that nothing, not even particles and electromagnetic radiation such as light, can escape from inside it?
Nothing more than Blackhole.
You see, he thinks and I agree that astronomers are among the smartest people in the world, he knows it, I know it, they know it.
For us developer, the situation is a bit different.
We must feel smart, we have the necessity to exhibit all our neurons all the time.
This most of the time is translate in something like dependency injection.
Dependency injection is nothing else than a very easy technique that was named in a really fancy way, to make it look like very difficult to understand and make whoever use it look the smartest person in the room.
Dependency injection is a method of supplying an object that a given piece of code requires.
The required object is called a dependency.
Basically, instead of having your objects creating a dependency you pass the needed dependencies into the object from outside,
This permit the developer to create objects using variables parameters rather than using fixed ones.
Here you have it,
You just discovered what’s goes inside that parenthesis.
As you can see leveraging this technique will be very useful, it allows your code to create different objects and any of them will have different characteristics.
$myBuilding, for instance, has red walls and 4 rooms, whereas $yourBuilding has 6 rooms and green walls.
As I told you, it is a 25-dollar term for a 5-cent concept.
Even though this is a simple concept, I decided to wait until now because now that you know what is a construct you can easily understand the following examples in this article.
The __construct method is automatically invoked when a new object is instantiated.
So now you are able to do this:
You have just seen dependency injection at work!
If this looks a bit overwhelming let me explain what’s happening.
The constructor requires 3 parameters: $windowsCount, $wallsColor and $roomsCount.
Once this method is invoked those 3 paramethers are included into the class using:
When a new object is created (in our case $myBuilding) the three parameters are specified within the parentheses:
$myBuilding = new Building($windowsCount, $wallsColor, $roomsCount);
A very important note that you need to keep in mind is that the order of the parameters must be the same in both the places otherwise you might end up with $roomCount equal to red and 50 windows in a building with 1 room.
but we didn’t finish yet.
There are several improvements we can implement this technique to enhance the quality of our code.
Here are brief explanations of them.

Optional parameters
Once you set classes or methods up and require dependency, you must give a parameter in order to do not bump into errors but, what if you do not have the required parameter?
Well, you can establish it in advance by giving a default value to it.
There is the main difference between the two objects created here.
At the moment we create the first object we did not provide any parameter but we want to be sure that people do not see only bricks and concrete so I have added a default value to the constructor to do that via $wallsColor = red.
What this bit of code is saying literary is:
If there is no parameter that specifies the color of the walls in this building uses a default color of red.
In the second object, you can see the blue string inside the parenthesis and that “blue” will overwrite the standard color of red.
Type-hinting
What is type hinting?
Type hinting is the practice to clearly point out the required data type (objects, interface, etc.).
From the early version of PHP5 until the new versions it is possible to type hint parameters inside methods.
Now the constructor is requiring an address variable of type array.
If you put everything that is not an array it will result in an error.
This procedure is very useful because it adds a new level of protection, leading to an improvement in security and better code.
A new feature of PHP7 is that now is even possible to do scalar type hinting, which means that if you use the last version of PHP you can hint boolean. string, integer and float variables.
The __destruct() method
You have seen that the constructor is the first method that is invoked when a new object has been instantiated,
As logical, the name of the magic method that is invoked the last is the deconstructor.
This method is automatically called when the object has no more references or when you compel the deletion.
You will rarely see this method but from my point of view, it is very useful because PHP will clean the object and remove from the memory, resulting in an enhancement in performance.
The __call() and __callStatic() methods
Those call methods are very easy to understand.
If a class has a __call() method (do not forget the double underscore) and you call a method that does not exist on an object then the __call() method is invoked instead.
The class in the example above does not have a buyAWindow() method, so, in this case, the __call() method is invoked and it returns the message.
The only difference between the __call() and the __callStatic() methods is that the first responds to non-static calls the second to static ones.
even though I did not specify any parameters the call methods have the name of the method as first and an array that contains the list of arguments available as the second parameter.
The getter and setter methods
The __get() and __set() methods are called when the code tries to read or write properties that do not exist or are not available in the class;
In the example above $securityCameraCount() is a method that does not exist in the Building class,
The __get() method has passed the name of the property that it is looked for so we can manage this error by returning a string that warns the user about it.
We have the same problem with the televisionCount,
This parameter is not available in the class, so when we try to assign the value of 10 to it PHP understand that it needs to invoke the __set() method,
Within the setter method, you can have several choices depending on what you want to do, the most common way to manage it is to show the error to the user via a message.
the toString() method
Sometimes it could happen that, either by mistake or on purpose, you will treat a class as a string.
For example when doing this:
The __toString() method allows you to manage the behavior of the class when that happens.
This is considered to be a very delicate method because it can easily throw fatal errors in case you code the wrong thing.
this magic method must return a string and you must not throw exceptions from inside, if one of those conditions is not respected PHP will return a fatal error.
You can see a full example of the __toString() method below.
The __sleep() and __wakeup() couple
These two methods are called when an object is serialized or is being unserialized.
To be precise the __sleep() is called just a moment before the serialization.
whereas the __wakeup() is called a bit after the unserialization.
How do they work?
The serialize() method check if within the call is present the magic method __sleep(), if so, serialize() stops for a second and let __sleep() do its things.
Since this method must return an array usually its goal is to return an array with the names of all the object’s variables that need to be serialized.
In case the method does not return anything then what’s returned is NULL that is serialized and an E_NOTICE will be shown.
Some helpful case in which the use of this method is justified may be to get large object data that do not need to be saved or execute some cleaning chores.
On the other side, you have the __wakeup() method.
It simply mirrors his close friend __sleep(),
This time is the unserialize() method that looks for the __wakeup(), if it exists within the class then the method restores all the connections of data lost during the serialization.
The __invoke() method
The __invoke() method is incredibly simple,
It is automatically called when the code does a call an object as it was a method or a function.
In the example above the outcome of the invoke method will show string(15) “23, Main Street”.
There are plenty of examples online on how to use this method but you can choose the best way to implement this method according to your needs.
Think of this method as a shortcut that let you do a specific task and is accessible by calling the object as a method.
This magic method is quite loose, which means you can do almost anything you want with it but be careful at one thing, arguments and parameters need to match,
If you call the object and you set 4 arguments, then the connected method needs to have 4 parameters.
Forgot to do this will result in an error thrown by the script.
The __set_state() and var_export
We just went from one of the easier to understand magic methods to one of the most complex The __set_state() method occurs when an instance of your object is passed to the var_export function.
What’s var_export() do?
var_export() needs two parameter,
the first one is mandatory and needs to represent the variable you need to export whereas the second is an optional boolean that indicates if it must return the variable representation as a string or outputting it.
We need a sample here:
As said __set_state() is called to respond to an instance of an object passed to the var_export function.
It has only one parameter that must be an array that contains exported properties as a key-value pair.
It will result in:
Debugging with __debuginfo()
Arrived with PHP 5.6 this characteristic is invoked by var_dump() when you dump an object in order to the determine which properties need to be output.
If the method is not defined on the object all public, protected and private properties will be shown.
In the above example, we are saying that __debugInfo() need to return only $windows and hide $doors
The conclusion of the fifth part
I hope you now are more aware of all the methods and trickery that the PHP language has to offer to Web Developers.
You probably won't use these methods described above on daily basis,
once you understand the concepts and maybe go back to this page from time to time in order to brush up their purpose will help you in better managing your code.
Also please, notice that you need to consider these only as helpers.
Even if, nobody can deny their power, start to use call method, getter, setter etc eventually will give you less control on the project you are writing.
Your main focus has to be writing clean code that is scalable and let you do what you need it to do not vice-versa.
Feel free and do not be scared of taking advantage of dependency injection, constructors and other methods after you have deeply understood how their works behind the scene.
In the next episode,
You will see what abstract methods are and extra features related to the Object Oriented paradigm
Stay tuned and subscribe using the form down here to get notified when it will be published.
Now it is your turn:
Are you going to update your methods and properties applying protected and private keywords or do you prefer spread static keywords everywhere?
let me know in the comment box below!
In the next episode,
we will focus on magic methods
I have prepared a complete list with a detailed description and code examples.
For this reason,
Stay tuned and subscribe using the form down here to get notified when it will be published.
Now it is your turn:
What Magic Method are you going to implement in your code?
let me know in the comment box below!