Heim  >  Artikel  >  Backend-Entwicklung  >  Beschreiben Sie kurz die in PHP bereitgestellten magischen Methoden

Beschreiben Sie kurz die in PHP bereitgestellten magischen Methoden

墨辰丷
墨辰丷Original
2018-06-09 10:26:411362Durchsuche

In diesem Artikel werden hauptsächlich die in PHP bereitgestellten magischen Methoden vorgestellt. Ich hoffe, dass er für alle hilfreich ist.

Übersicht

Bei der objektorientierten Programmierung stellt PHP eine Reihe magischer Methoden bereit, die viel Komfort beim Programmieren bieten. Magische Methoden in PHP beginnen normalerweise mit __ (zwei Unterstrichen) und erfordern keine expliziten Aufrufe, sondern werden durch bestimmte Bedingungen ausgelöst.

Bevor Sie beginnen

Bevor wir die magischen Methoden von PHP zusammenfassen, definieren wir zwei Klassen zur Verwendung in späteren Beispielen:

Der Code lautet wie folgt:

<?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;
    }
}
?>


Die Device-Klasse verfügt über vier Mitgliedseigenschaften und zwei Mitgliedsmethoden. Die Battery-Klasse verfügt über eine Membereigenschaft und eine Membermethode.

Konstruktor und Destruktor

Konstruktor und Destruktor werden aufgerufen, wenn das Objekt erstellt bzw. zerstört wird. Wenn ein Objekt „zerstört“ wird, bedeutet dies, dass es keinen Verweis auf das Objekt gibt. Wenn beispielsweise die Variable, die auf das Objekt verweist, gelöscht (nicht gesetzt) ​​wird oder die Skriptausführung endet, wird der Destruktor aufgerufen.

__construct()

__construct() Der Konstruktor ist mit Abstand die am häufigsten verwendete Funktion. Beim Erstellen eines Objekts können Sie im Konstruktor einige Initialisierungsarbeiten durchführen. Sie können für den Konstruktor beliebig viele Parameter definieren, sofern bei der Instanziierung die entsprechende Anzahl Parameter übergeben wird. Jede im Konstruktor auftretende Ausnahme verhindert, dass das Objekt erstellt wird.

Der Code lautet wie folgt:

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

Im obigen Beispielcode weist der Konstruktor der Device-Klasse den Mitgliedseigenschaften Werte zu und ruft die connect()-Methode auf.

Die Deklaration des Konstruktors als private Methode verhindert, dass Objekte außerhalb der Klasse erstellt werden, was häufig im Simplex-Muster verwendet wird.

__dectruct()

Der Destruktor wird normalerweise aufgerufen, wenn das Objekt zerstört wird. Der Destruktor erhält keine Parameter. Im Destruktor werden häufig einige Aufräumarbeiten durchgeführt, z. B. das Schließen der Datenbankverbindung usw.

Eigenschaftsüberladung

Eine Sache ist, dass „Überladung“ in PHP nicht dasselbe ist wie Überladung in den meisten anderen Sprachen, obwohl sie alle die gleiche Funktion implementieren .
Die beiden magischen Methoden beim Überladen von Eigenschaften werden hauptsächlich zur Handhabung des Eigenschaftszugriffs verwendet und definieren, was passiert, wenn wir versuchen, auf eine nicht vorhandene (oder unzugängliche) Eigenschaft zuzugreifen.

__get()

Die magische Methode __get() wird aufgerufen, wenn wir versuchen, auf eine nicht vorhandene Eigenschaft zuzugreifen. Es empfängt einen Parameter, der den Namen des Attributs darstellt, auf das zugegriffen wird, und gibt den Wert des Attributs zurück. In der Geräteklasse oben gibt es ein Datenattribut, das hier eine Rolle spielt, wie zum Beispiel den folgenden Code:

Der Code lautet wie folgt:

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

Der dafür am häufigsten verwendete Ort Die Zugriffskontrolle der magischen Methode wird durch die Erstellung eines „schreibgeschützten“ Attributs erweitert. In der oben genannten Battery-Klasse gibt es ein privates Attribut $charge. Wir können dieses Attribut über die magische Methode __get() erweitern, damit es außerhalb der Klasse lesbar, aber nicht änderbar ist. Der Code lautet wie folgt:

Der Code lautet wie folgt:

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

__set()

__set() Die magische Methode wird ausgeführt, wenn wir es versuchen So ändern Sie eine unzugängliche Eigenschaft: Beim Aufruf werden zwei Parameter empfangen, von denen einer den Namen des Attributs und der andere den Wert des Attributs darstellt. Der Beispielcode lautet wie folgt:

Der Code lautet wie folgt:

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

__isset()

__isset() Magic Method Calls isset(( ) auf eine unzugängliche Eigenschaft )-Methode aufgerufen wird, erhält sie einen Parameter, der den Namen des Attributs angibt. Es sollte einen booleschen Wert zurückgeben, der angibt, ob die Eigenschaft vorhanden ist. Der Code lautet wie folgt:

Der Code lautet wie folgt:

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

__unset()

Die magische Methode __unset() ruft die unset() auf Funktion zum Zerstören einer nicht zugänglichen Funktion. Sie wird aufgerufen, wenn eine Eigenschaft aufgerufen wird, und erhält einen Parameter, der den Namen der Eigenschaft darstellt.

Objekt in String konvertieren

Manchmal müssen wir das Objekt in Form eines Strings ausdrücken. Wenn wir ein Objekt direkt drucken, gibt das Programm eine Fehlermeldung aus: PHP Catchable fatal error: Object of class Device konnte nicht in string konvertiert werden

__toString()

__toString() wird aufgerufen, wenn wir das Objekt als String verwenden. Es erhält keine Parameter. Mit dieser Methode können wir die Darstellung des Objekts definieren. Der Code lautet wie folgt:

Der Code lautet wie folgt:

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)

Statische magische Methode __set_state() , wo wir die Funktion var_export () verwenden, ruft diese Methode auf, wenn das Objekt ausgegeben wird. Die Funktion var_export() wird zum Konvertieren von PHP-Variablen in PHP-Code verwendet. Sie erhält ein assoziatives Array, das Objektattributwerte als Parameter enthält. Der Beispielcode lautet wie folgt:

Der Code lautet wie folgt:

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

Objekt klonen

默认的,对象都是按引用传值的。因此,在将一个对象赋值给另一个变量时,只是创建了指向该对象的一个引用,并没有复制该对象。为了实现真正得复制一个对象,我们需要使用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请求的三种常见用法

Das obige ist der detaillierte Inhalt vonBeschreiben Sie kurz die in PHP bereitgestellten magischen Methoden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn