Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erklärung der Closure-Klasse in PHP

Detaillierte Erklärung der Closure-Klasse in PHP

小云云
小云云Original
2018-03-22 09:48:462569Durchsuche

Dieser Artikel gibt Ihnen hauptsächlich eine detaillierte Erklärung der Closure-Klasse in PHP. Die PHP-Closure-Klasse ist eine Klasse, die zur Darstellung anonymer Funktionen (eingeführt in PHP 5.3) verwendet wird Die Klasse „Closure“ lautet wie folgt:

Closure {
    __construct ( void )
    public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ])
    public Closure bindTo (object $newthis [, mixed $newscope = 'static' ])
}

Methodenbeschreibung:

Closure::__construct – Konstruktor zum Verhindern der Instanziierung
Closure::bind – Kopieren Sie einen Abschluss und binden Sie den angegebenen $dieser Objekt- und Klassenbereich.
Closure::bindTo – Kopieren Sie das aktuelle Abschlussobjekt und binden Sie das angegebene $this-Objekt und den angegebenen Klassenbereich.

Zusätzlich zu den hier aufgeführten Methoden gibt es auch eine __invoke-Methode. Dies dient der Konsistenz mit anderen Objekten, die die magische Methode __invoke() implementieren, aber der Prozess des Aufrufs des Abschlussobjekts hat damit nichts zu tun.

Im Folgenden werden Closure::bind und Closure::bindTo vorgestellt.

Closure::bind ist die statische Version von Closure::bindTo und ihre Beschreibung lautet wie folgt:

public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ])

closure stellt das Abschlussobjekt dar, das benötigt wird gebunden sein.
newthis stellt das Objekt dar, das an das Abschlussobjekt gebunden werden muss, oder NULL, um einen ungebundenen Abschluss zu erstellen.
newscope stellt den Klassenbereich dar, den Sie an den Abschluss binden möchten. Sie können den Klassennamen oder das Klassenbeispiel übergeben. Der Standardwert ist „statisch“, was bedeutet, dass keine Änderung erfolgt.

Diese Methode gibt bei Erfolg ein neues Schließungsobjekt und bei Fehlschlag FALSE zurück.

Beispiel:

<?php
/** 
 * 复制一个闭包,绑定指定的$this对象和类作用域。 
 * 
 * @author 疯狂老司机 
 */
class Animal {
    private static $cat = "cat";
    private $dog = "dog";
    public $pig = "pig";
}

/* 
 * 获取Animal类静态私有成员属性
 */
$cat = static function() {
    return Animal::$cat;
};

/* 
 * 获取Animal实例私有成员属性
 */
$dog = function() {
    return $this->dog;
};

/* 
 * 获取Animal实例公有成员属性
 */
$pig = function() {
    return $this->pig;
};

$bindCat = Closure::bind($cat, null, new Animal());// 给闭包绑定了Animal实例的作用域,但未给闭包绑定$this对象
$bindDog = Closure::bind($dog, new Animal(), &#39;Animal&#39;);// 给闭包绑定了Animal类的作用域,同时将Animal实例对象作为$this对象绑定给闭包
$bindPig = Closure::bind($pig, new Animal());// 将Animal实例对象作为$this对象绑定给闭包,保留闭包原有作用域
echo $bindCat(),&#39;<br>&#39;;// 根据绑定规则,允许闭包通过作用域限定操作符获取Animal类静态私有成员属性
echo $bindDog(),&#39;<br>&#39;;// 根据绑定规则,允许闭包通过绑定的$this对象(Animal实例对象)获取Animal实例私有成员属性
echo $bindPig(),&#39;<br>&#39;;// 根据绑定规则,允许闭包通过绑定的$this对象获取Animal实例公有成员属性
?>

Ausgabe:

Katze
Hund
Schwein

Closure::bindTo – Kopieren Sie das aktuelle Abschlussobjekt und binden Sie das angegebene $this-Objekt und den angegebenen Klassenbereich:

public Closure Closure::bindTo (object $newthis [, mixed $newscope = &#39;static&#39; ])

newthis stellt ein an das Abschlussobjekt gebundenes Objekt dar, oder NULL, um die Bindung abzubrechen .
newscope stellt den Klassenbereich dar, der dem Abschlussobjekt zugeordnet ist. Sie können den Klassennamen oder das Klassenbeispiel übergeben. Der Standardwert ist „statisch“, was bedeutet, dass keine Änderung erfolgt.

Diese Methode erstellt ein Abschlussobjekt und gibt es zurück, das dieselben Variablen wie das aktuelle Objekt bindet, aber verschiedene Objekte oder einen neuen Klassenbereich binden kann. Das gebundene Objekt bestimmt den Wert von $this im zurückgegebenen Abschlussobjekt und der Klassenbereich bestimmt, welche Methoden das zurückgegebene Abschlussobjekt aufrufen kann. Mit anderen Worten, die Methoden, die $this zu diesem Zeitpunkt aufrufen kann, funktionieren mit der newscope-Klasse Domäne ist die gleiche.

Beispiel 1:

<?php
function __autoload($class) {
    require_once "$class.php";
}

$template = new Template;
$template->render(new Article, &#39;tpl.php&#39;);
?>

Template.php-Vorlagenklasse

<?php
/** 
 * 模板类,用于渲染输出 
 * 
 * @author 疯狂老司机 
 */
class Template{
    /**
     * 渲染方法
     *
     * @access public 
     * @param obj 信息类
     * @param string 模板文件名
     */
    public function render($context, $tpl){
        $closure = function($tpl){
            ob_start();
            include $tpl;
            return ob_end_flush();
        };
        $closure = $closure->bindTo($context, $context);
        $closure($tpl);
    }

}

Article.php-Informationsklasse

<?php
/** 
 * 文章信息类 
 * 
 * @author 疯狂老司机 
 */
class Article{
    private $title = "这是文章标题";
    private $content = "这是文章内容";
}

tpl Stellen Sie beim Ausführen der .php-Vorlagendatei

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    </head>
    <body>
        <h1><?php echo $this->title;?></h1>
        <p><?php echo $this->content;?></p>
    </body>
</html>

sicher, dass sich die oben genannten Dateien im selben Verzeichnis befinden.

Ausgabe:

Dies ist der Artikeltitel

Dies ist der Artikelinhalt

Beispiel 2:

<?php
/** 
 * 给类动态添加新方法
 * 
 * @author 疯狂老司机
 */
trait DynamicTrait {

    /**
     * 自动调用类中存在的方法
     */
    public function __call($name, $args) {
        if(is_callable($this->$name)){
            return call_user_func($this->$name, $args);
        }else{
            throw new \RuntimeException("Method {$name} does not exist");
        }
    }
    /**
     * 添加方法
     */
    public function __set($name, $value) {
        $this->$name = is_callable($value)? 
            $value->bindTo($this, $this): 
            $value;
    }
}

/** 
 * 只带属性不带方法动物类
 * 
 * @author 疯狂老司机
 */
class Animal {
    use DynamicTrait;
    private $dog = &#39;dog&#39;;
}

$animal = new Animal;

// 往动物类实例中添加一个方法获取实例的私有属性$dog
$animal->getdog = function() {
    return $this->dog;
};

echo $animal->getdog();

?>

Ausgabe:

Hund

Beispiel 3:

<?php
/** 
 * 一个基本的购物车,包括一些已经添加的商品和每种商品的数量
 * 
 * @author 疯狂老司机
 */
class Cart {
    // 定义商品价格
    const PRICE_BUTTER  = 1.00;
    const PRICE_MILK    = 3.33;
    const PRICE_EGGS    = 8.88;
 
    protected   $products = array();

    /**
     * 添加商品和数量
     *
     * @access public 
     * @param string 商品名称
     * @param string 商品数量
     */
    public function add($item, $quantity) {
        $this->products[$item] = $quantity;
    }

    /**
     * 获取单项商品数量
     *
     * @access public 
     * @param string 商品名称
     */
    public function getQuantity($item) {
        return isset($this->products[$item]) ? $this->products[$item] : FALSE;
    }

    /**
     * 获取总价
     *
     * @access public 
     * @param string 税率
     */
    public function getTotal($tax) {
        $total = 0.00;

        $callback = function ($quantity, $item) use ($tax, &$total) {
            $pricePerItem = constant(__CLASS__ . "::PRICE_" . strtoupper($item));
            $total += ($pricePerItem * $quantity) * ($tax + 1.0);
        };
         
        array_walk($this->products, $callback);
        return round($total, 2);;
    }
}

$my_cart = new Cart;

// 往购物车里添加商品及对应数量
$my_cart->add(&#39;butter&#39;, 10);
$my_cart->add(&#39;milk&#39;, 3);
$my_cart->add(&#39;eggs&#39;, 12);

// 打出出总价格,其中有 5% 的销售税.
echo $my_cart->getTotal(0.05);

?>

Ausgabe:

132,88

Zusätzlicher Hinweis: Schließungen können mit der USE-Taste durchgeführt werden Externe Variablen verbinden.

Zusammenfassung: Durch die richtige Verwendung von Abschlüssen kann der Code prägnanter und verfeinert werden.
Verwandte Empfehlungen:

Einführung in Beispiele für die Verwendung von Schließungen in PHP

Detaillierte Erläuterung von Beispielen für die Verwendung von Schließungen in PHP

Einführung in den Abschluss in PHP

Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung der Closure-Klasse in PHP. 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