>  기사  >  백엔드 개발  >  PHP의 Closure 클래스에 대한 자세한 설명

PHP의 Closure 클래스에 대한 자세한 설명

小云云
小云云원래의
2018-03-22 09:48:462630검색

이 기사에서는 주로 PHP의 Closure 클래스에 대한 자세한 설명을 공유합니다. PHP Closure 클래스는 익명 함수(PHP 5.3에 도입됨)를 생성하는 데 사용되는 클래스입니다. 클래스는 다음과 같습니다:

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

메서드 설명:

Closure::__construct — 인스턴스화를 금지하는 데 사용되는 생성자
Closure::bind — 클로저를 복사하고 지정된 $this 개체와 클래스 범위를 바인딩합니다.
Closure::bindTo — 현재 클로저 객체를 복사하고 지정된 $this 객체와 클래스 범위를 바인딩합니다.

여기에 나열된 메서드 외에도 __invoke 메서드도 있습니다. 이는 __invoke() 매직 메서드를 구현하는 다른 객체와의 일관성을 위한 것이지만 클로저 객체를 호출하는 프로세스는 이와 아무 관련이 없습니다.

다음에서는 Closure::bindClosure::bindTo를 소개합니다.

Closure::bind는 Closure::bindTo의 정적 버전이며 설명은 다음과 같습니다.

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

closure는 바인딩해야 하는 클로저 개체를 나타냅니다.
newthis는 클로저 객체에 바인딩되어야 하는 객체를 나타내거나 바인딩되지 않은 클로저를 생성하려면 NULL을 나타냅니다.
newscope는 클로저에 바인딩하려는 클래스 범위를 나타냅니다. 클래스 이름이나 클래스 예제를 전달할 수 있습니다. 기본값은 변경이 없음을 의미하는 'static'입니다.

이 메서드는 성공하면 새 Closure 객체를 반환하고, 실패하면 FALSE를 반환합니다.

예제 설명:

<?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实例公有成员属性
?>

출력:

cat
dog
pig

Closure::bindTo — 현재 클로저 객체를 복사하고 지정된 $this 객체와 클래스 범위를 바인딩합니다.

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

newthis는 클로저 개체에 바인딩된 개체 또는 바인딩 해제를 위한 NULL을 나타냅니다.
newscope는 클로저 객체와 연관된 클래스 범위를 나타냅니다. 클래스 이름이나 클래스 예제를 전달할 수 있습니다. 기본값은 변경되지 않음을 의미하는 '정적'입니다.

이 메서드는 현재 개체와 동일한 변수를 바인딩하는 클로저 개체를 생성하고 반환하지만 다른 개체나 새 클래스 범위를 바인딩할 수 있습니다. 바인딩된 개체는 반환된 클로저 개체에서 $this의 값을 결정하고, 클래스 범위는 반환된 클로저 개체가 호출할 수 있는 메서드를 결정합니다. 즉, 이때 $this가 호출할 수 있는 메서드는 newscope 클래스와 함께 작동합니다. 도메인은 동일합니다.

예제 1:

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

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

Template.php 템플릿 클래스

<?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 정보 클래스

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

tpl.php 템플릿 파일

<!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>

실행 시 위 파일들이 동일한 레벨 디렉터리에 있는지 확인하세요.

출력:

기사 제목입니다

기사 내용입니다

예 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();

?>

출력:

dog

예 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);

?>

출력:

132.88

추가 설명: 클로저 USE 키를 사용하여 외부 변수를 연결할 수 있습니다.

요약: 클로저를 적절하게 사용하면 코드를 더욱 간결하고 세련되게 만들 수 있습니다.
관련 권장 사항:

php의 클로저 사용 예 소개

php의 클로저 사용 예에 ​​대한 자세한 설명

php의 클로저 소개

위 내용은 PHP의 Closure 클래스에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.