Maison  >  Article  >  développement back-end  >  Décrire brièvement les méthodes magiques fournies en PHP

Décrire brièvement les méthodes magiques fournies en PHP

墨辰丷
墨辰丷original
2018-06-09 10:26:411310parcourir

Cet article présente principalement les méthodes magiques fournies en PHP. Les amis intéressés peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

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.

Avant de commencer

Avant de résumer les méthodes magiques de PHP, définissons deux classes à utiliser dans des 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. Lors de la création d'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 du membre 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.

__desctruct()

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() est appelée lorsque l'on tente 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 montre 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 méthode magique est le plus couramment utilisé est d'étendre le contrôle d'accès en créant un attribut "lecture seule". Dans la classe Battery ci-dessus, il existe un attribut privé $charge. Nous pouvons étendre cet attribut via la méthode magique __get() pour qu'il 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()

__set() méthode magique quand on essaie pour modifier une propriété inaccessible sera appelée lorsqu'elle recevra deux paramètres, un représentant le nom de l'attribut et un représentant 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()

La méthode magique __isset() est appelée sur une propriété inaccessible La méthode isset() sera appelée, et elle recevra un paramètre indiquant 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()

__la méthode magique unset() appelle le unset () fonction pour détruire un objet qui ne peut pas. Il est appelé lors de l'accès à une propriété et 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 directement un objet, le programme affichera un message d'erreur : Erreur fatale PHP Catchable : L'objet de classe Device n'a pas pu être converti en chaîne

__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)

Méthode magique statique __set_state (), dans notre Cette méthode est appelée lorsqu'un objet est exporté à l'aide de la fonction var_export(). 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()函数。

总结:以上就是本篇文的全部内容,希望能对大家的学习有所帮助。

相关推荐:

php针对数组的删除、转换、分组、排序

php针对文件操作及字符串加密的方法

php模拟post请求的三种常见用法

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