Maison  >  Article  >  développement back-end  >  Résumé de l'utilisation courante des méthodes et fonctions magiques de PHP

Résumé de l'utilisation courante des méthodes et fonctions magiques de PHP

伊谢尔伦
伊谢尔伦original
2017-07-03 13:43:371421parcourir

Vue d'ensemble

Dans la programmation orientée objet, PHP fournit une série de méthodes magiques, qui offrent beaucoup de commodité pour la programmation. Les méthodes magiques en PHP commencent généralement par (deux traits de soulignement) et ne nécessitent pas d'appels explicites mais sont déclenchées par certaines conditions spécifiques. Cet article résume brièvement les méthodes magiques disponibles en PHP.

Avant de commencer

Avant de résumer les méthodes magiques de PHP, définissons deux classes à utiliser dans les exemples ultérieurs :

Le code est le suivant :

<?php
class Device {
    public $name;           
    public $battery;        
    public $data = array(); 
    public $connection;     
 
    protected function connect() {
        $this->connection = &#39;resource&#39;;
        echo $this->name . &#39; connected&#39; . PHP_EOL;
    }
 
    protected function disconnect() {
        $this->connection = null;
        echo $this->name . &#39; disconnected&#39; . PHP_EOL;
    }
}
 
class Battery {
    private $charge = 0;
 
    public function setCharge($charge) {
        $charge = (int)$charge;
        if($charge < 0) {
            $charge = 0;
        }
        elseif($charge > 100) {
            $charge = 100;
        }
        $this->charge = $charge;
    }
}
?>


La classe Device a quatre propriétés membres et deux méthodes membres. La classe Battery a une propriété membre et une méthode membre.

Constructeur et destructeur

Le constructeur et le destructeur sont appelés lorsque l'objet est créé et détruit respectivement. Lorsqu'un objet est "détruit", cela signifie qu'il n'y a aucune référence à l'objet. Par exemple, si la variable qui fait référence à l'objet est supprimée (non définie), réaffectée ou si l'exécution du script se termine, le destructeur sera appelé.

construct()

construct() Le constructeur est de loin la fonction la plus couramment utilisée. Lorsque crée un objet, vous pouvez effectuer un travail d'initialisation dans le constructeur. Vous pouvez définir n'importe quel nombre de paramètres pour le constructeur, à condition que le nombre correspondant de paramètres soit transmis lors de l'instanciation. Toute exception qui se produit dans le constructeur empêche la création de l'objet.

Le code est le suivant :

class Device {
   public function  construct(Battery $battery, $name) {
       $this->battery = $battery;
       $this->name = $name;
       $this->connect();
    }
}

Dans l'exemple de code ci-dessus, le constructeur de la classe Device attribue des valeurs aux propriétés des membres et appelle la méthode connect().

Déclarer le constructeur comme méthode privée empêche la création d'objets en dehors de la classe, qui est souvent utilisée dans le modèle simplex.

destruct()

Le destructeur est généralement appelé lorsque l'objet est détruit. Le destructeur ne reçoit aucun paramètre. Certains travaux de nettoyage sont souvent effectués dans le destructeur, comme la fermeture de la connexion à la base de données, etc.

Surcharge de propriétés

Une chose à noter est que la "surcharge" en PHP n'est pas la même chose que la surcharge dans la plupart des autres langages, bien qu'ils implémentent tous la même fonction. .
Les deux méthodes magiques impliquées dans la surcharge de propriétés sont principalement utilisées pour gérer l'accès aux propriétés, définissant ce qui se passe lorsque nous essayons d'accéder à une propriété inexistante (ou inaccessible).

get()

La méthode magique get() sera appelée lorsque nous tenterons d'accéder à une propriété inexistante. Il reçoit un paramètre qui représente le nom de l'attribut accédé et renvoie la valeur de l'attribut. Dans la classe Device ci-dessus, il y a un attribut data, qui joue ici un rôle, comme le code suivant :

Le code est le suivant :

class Device {
    public function  get($name) {
         if(array_key_exists($name, $this->data)) {
            return $this->data[$name];
        }
        return null;
    }
}

Cette magie L'endroit le plus courant pour les méthodes est d'étendre le contrôle d'accès en créant un attribut "lecture seule". Dans la classe Battery ci-dessus, il existe une propriété privée $charge, que nous pouvons étendre via la méthode magique get() pour qu'elle soit lisible mais non modifiable en dehors de la classe. Le code est le suivant :

Le code est le suivant :

class Battery {
    private $charge = 0;
 
    public function  get($name) {
        if(isset($this->$name)) {
            return $this->$name;
        }
        return null;
    }
}

set()

méthode magique set() n'est pas disponible lorsque nous essayons de le modifier. Il sera appelé lors de l'accès à l'attribut. Il reçoit deux paramètres, un indiquant le nom de l'attribut et un indiquant la valeur de l'attribut. L'exemple de code est le suivant :

Le code est le suivant :

class Device {
    public function  set($name, $value) {
        // use the property name as the array key
        $this->data[$name] = $value;
    }
}

isset()

isset() magique La méthode isset() d'un attribut est appelée lorsqu'elle est appelée. Elle reçoit un paramètre représentant le nom de l'attribut. Il doit renvoyer une valeur booléenne indiquant si la propriété existe. Le code est le suivant :

Le code est le suivant :

class Device {
    public function  isset($name) {
        return array_key_exists($name, $this->data);
    }
}

unset()

méthode magique unset() appelle la fonction unset() Appelée lorsqu'une propriété inaccessible est détruite, elle reçoit un paramètre représentant le nom de la propriété.

Convertir un objet en chaîne

Parfois, nous devons exprimer l'objet sous la forme d'une chaîne. Si nous imprimons un objet directement, le programme affichera un message d'erreur : PHP Catchable fatal error : Object of class Device could not be convert to string

toString()

toString() sera appelé lorsque nous utiliserons l'objet comme chaîne. Il ne reçoit aucun paramètre. Cette méthode permet de définir la représentation de l'objet. Le code est le suivant :

Le code est le suivant :

class Device {
    public function  toString() {
       $connected = (isset($this->connection)) ? &#39;connected&#39; : &#39;disconnected&#39;;
       $count = count($this->data);
       return $this->name . &#39; is &#39; . $connected . &#39; with &#39; . $count . &#39; items in memory&#39; . PHP_EOL;
    }
    ...
}

set_state() (PHP 5.1)

Statique méthode magique set_state(), Cette méthode est appelée lorsque nous utilisons la fonction var_export() pour exporter un objet. La fonction var_export() est utilisée pour convertir les variables PHP en code PHP. Elle reçoit un tableau associatif contenant les valeurs des attributs d'objet en paramètre. L'exemple de code est le suivant :

Le code est le suivant :

class Battery {
    //...
    public static function  set_state(array $array) {
        $obj = new self();
        $obj->setCharge($array[&#39;charge&#39;]);
        return $obj;
    }
    //...
}

Cloner l'objet

默认的,对象都是按引用传值的。因此,在将一个对象赋值给另一个变量时,只是创建了指向该对象的一个引用,并没有复制该对象。为了实现真正得复制一个对象,我们需要使用clone关键字。
这种“按引用传递”的策略同样适用于包含在对象内部的对象。即使我们克隆了一个对象,在对象内部的任何对象都不会被克隆,因此最终的结果是两个对象共享了同一个内部对象。示例代码如下:

$device = new Device(new Battery(), &#39;iMagic&#39;);
$device2 = clone $device;
 
$device->battery->setCharge(65);
echo $device2->battery->charge;
// 65

clone()

clone()魔术方法clone()可以解决上面的问题。当对一个对象使用clone关键字时,该魔术方法会被调用。在这个魔术方法里,我们可以实现任何子对象的克隆,代码如下:

代码如下:

class Device {
    ...
    public function  clone() {
        // copy our Battery object
        $this->battery = clone $this->battery;
    }
    ...
}

对象序列化

序列化是讲任意数据转换为字符串格式的过程。序列化通常用来将整个对象存入数据库或写入文件中。当反序列化存储的数据时,我们可以得到序列化之前的对象。但是,并不是所有得数据都可以被序列化,比如数据库连接。幸运的是,有一个魔术方法可以帮我们解决这个问题。

sleep()

魔术方法sleep()在对一个对象序列化时(调用serialize())会被调用。它不接收任何参数,而且应该返回一个包含所有应该被序列化的属性的数组。在该魔术方法中,也可以执行一些其他操作。
有一点要注意的是,不要再该函数中进行任何的析构操作,因为这可能会影响正在运行的对象。

示例代码如下:

class Device {
    public $name;           
    public $battery;       
    public $data = array();
    public $connection;    
    //...
    public function  sleep() {
        return array(&#39;name&#39;, &#39;battery&#39;, &#39;data&#39;);
    }
    //...
}

wakeup()

魔术方法wakeup()在对存储的对象反序列化时会被调用。它不接收任何参数,也没有任何返回值。可以用它来处理在序列化时丢失的数据库连接或资源。代码如下:

代码如下:

class Device {
    //...
    public function  wakeup() {
        // reconnect to the network
        $this->connect();
    }
    //...
}

方法重载

PHP还有两个与成员方法相关的魔术方法call()和callStatic(),这两个魔术方法类似于属性重载方法。

call()

魔术方法call()在调用不存在或不可访问的方法时会被调用。它接收两个参数,一个是调用的方法的名字,一个是包含函数参数的数组。我们可以使用这种方法调用子对象中得同名函数。

在这个例子中,要注意函数call_user_func_array(),这个函数允许我们动态调用一个命名的函数。

示例代码如下:

class Device {
    //...
    public function  call($name, $arguments) {
        // make sure our child object has this method
        if(method_exists($this->connection, $name)) {
            // forward the call to our child object
            return call_user_func_array(array($this->connection, $name), $arguments);
        }
        return null;
    }
    //...
}

callStatic()

魔术方法callStatic()与call()的功能一样,唯一不同的是,该方法在尝试访问一个不存在或不可访问的静态方法时会被调用。示例代码如下:

class Device {
    //...
    public static function  callStatic($name, $arguments) {
        // make sure our class has this method
        if(method_exists(&#39;Connection&#39;, $name)) {
            // forward the static call to our class
            return call_user_func_array(array(&#39;Connection&#39;, $name), $arguments);
        }
        return null;
    }
    //...
}

将对象作为函数

有时候我们会需要将对象作为函数使用。将对象作为函数使用,就像我们使用其他普通的函数一样,可以传参。

invoke()(PHP 5.3)

魔术方法invoke()在尝试将对象作为函数使用时会被调用。在该方法中定义的任何参数,都将被作为函数的参数。示例代码如下:

class Device {
    //...
    public function invoke($data) {
        echo $data;
    }
    //...
}
$device = new Device(new Battery(), &#39;iMagic&#39;);
$device(&#39;test&#39;);
// equiv to $device->invoke(&#39;test&#39;)
// Outputs: test

其他:autoload()

autoload()方法并不是一个魔术方法,但是这个方法非常有用。但是,对着PHP版本的更新,该函数已经不建议使用,取而代之的是spl_auto_register()函数。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn