Рейтинг@Mail.ru
 
Магические методы.

Ну вот тут более менее приземленное название, вполне отражающее суть. Метод - это мы проходили. Функция внутри класса. А магический, потому что волшебным образом работает сам, вызываясь в зависимости от каких то условий.

Мы уже сталкивались с двумя - конструктор и деструктор. Первый вызывается при инициализации объекта, второй непосредственно перед уничтожением. Вообще всего их 14.
__construct
__destruct
__set
__get
__call
__callStatic
__isset
__unset
__sleep
__wakeup
__toString
__invoke
__set_state
__clone


Магические методы всегда начинаются с двух нижих подчеркиваний. Не желательно так начинать собственные методы.
Итак по порядку.
__construct
__destruct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

class Example  

  
    public function 
__construct() 
    { 
       echo 
'Старт<br>';  
    } 
     
    public function 
__destruct() 
    { 
       echo 
'Финиш';  
    }     

  
    
$obj = new Example(); 
  
    unset(
$obj);

__set
Вызывается автоматически когда происходит изменение или инициализация несуществующей в классе переменной.
__get
Вызывается при попытке получить значение несуществующей в классе переменной

Вот так в действии:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

class Example   
{  
   
    public function 
__set($name$value)  
    {  
       
$this->$name $value;   
    }  
      
    public function 
__get($name)  
    {  
        return 
$this->$name;   
    }      
}  
   
    
$obj = new Example();  
   
    
$obj->variable 'Меня в классе нет';  
      
    echo 
$obj->variable;


__call
__callStatic (PHP >= 5.3)
Вызываются при попытке обратиться к недоступному или несуществующему методу. Это для отлова всех не реализованных методов в классе.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

class Example  

  
    public function 
__call($name$args
    { 
       echo 
'Нет тут метода '$name .'('$args[0] .')';  
    } 
     

  
    
$obj = new Example(); 
  
    
$obj->method(100);

Эти методы применяются для так называемой перегрузки. То есть мы можем вызывать метод (или определять свойства), которых не существует.

__isset
__unset
Вызываются при попытке проверить или разустановить несуществующие свойства (переменные) класса соответственно.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

class Example  

    public function 
__isset($name)   
    { 
        echo 
'Свойство ' $name .  ' не установлено.<br>'
    } 
  
    public function 
__unset($name)   
    { 
        echo 
'Кому сказано? ' $name .  ' не установлено!'
    } 

  
    
$obj = new Example(); 
  
    isset(
$obj->var); 
    unset(
$obj->var);


__sleep
__wakeup
Этл методы исключительно для сериализации объекта. Объект(экземпляр класса), если Вам еще не известно, можно сериализовать так же, как массив. Так вот первый вызывается непосредственно перед сериализацией, второй - сразу после десериализации. Метод __sleep должен вернуть массив имен свойств и методов, которые нужно сериализовать. Иначе десериализовывать будет нечего и вызов __wakeup потеряет смысл. Этот метод применяется для восстановления коннекта с сервером БД к примеру.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php

class Example  

    public 
$var 'Объект' 

     
    public function 
__sleep()   
    { 
       echo 
$this->var .' сериализован<br>'
       return array(
'var''foo'); 
    } 
  
    public function 
__wakeup()   
    { 
       
$this->foo(); 
    }  

    public function 
foo()   
    { 
       echo 
$this->var .' десериализован'
    }        

  
    
$obj = new Example(); 
  
    
$pack serialize($obj); 
    
var_dump($pack); 
    
$obj  unserialize($pack);


__toString
Вызывается, если объект преобразуется в строку.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

class Example  


    public function 
__toString()   
    { 
       return 
'Привет'
    } 
    

  
    
$obj = new Example(); 
     
    echo 
$obj;


__invoke
Этот метод сработает при попытке обратиться к объекту, как к функции
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

class Example  


    public function 
__invoke()   
    { 
       echo 
'Это не функция!'
    } 
    

  
    
$obj = new Example();     
    
$obj();


__set_state
Этот метод похож на __sleep, только подготавливает весь объект для экспорта функцией var_export()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

class Example  

    public 
$var1
    public 
$var2

    public function 
__set_state($an_array
    { 
        
$obj = new Example
        
$obj->var1 $an_array['var1']; 
        
$obj->var2 $an_array['var2']; 
        return 
$obj
    } 

  
    
$obj = new Example();     
    
$obj -> var1 5
    
$obj -> var2 'строка'

    eval(
'$new = 'var_export($objtrue) .';'); 
    
var_dump($new);


Ну и последний
__clone
Вызывается при клонировании объекта. Полезен тогда, когда нужно изменить какие то параметры в клоне, потому что если этот метод не писать, он будет вызван автоматически со всеми параметрами и сделает полную копию.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

class Example 

    public 
$inst 'Оригинал<br>'

    function 
__clone()  
    { 
        
$this->inst "Клон"
    } 


    
$obj = new Example(); 

    echo 
$obj -> inst

    
$cloned = clone $obj
    echo 
$cloned -> inst;


Ну вот и вся магия. Здесь показаны только механизмы срабатывания, а использовать эти методы можно по разному, но это уже высший пилотаж.
По этому мы тут и пробежались так, вскользь. Для введения вполне достаточно.