PHP Closure類の詳細

6335 ワード

PHP Closureクラスは匿名関数を表すクラスであり、匿名関数(PHP 5.3に導入されている)はこのタイプのオブジェクトを生成し、Closureクラスの要約は以下の通りである.
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::bindとClosure::bindToについて説明します.
Closure::bindはClosure::bindToの静的バージョンで、次のように説明されています.
public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ])

closureは、バインドする必要がある閉パッケージオブジェクトを表します.新hisは、閉パッケージオブジェクトにバインドする必要があるオブジェクト、またはNULLがバインドされていない閉パッケージを作成する必要があることを示します.Newscopeは、閉パッケージにバインドしたいクラス役割ドメインを表し、クラス名またはクラスの例を入力できます.デフォルト値は'static'で、変更しないことを示します.
メソッドが成功すると新しいClosureオブジェクトが返され、失敗するとFALSEが返されます.
例:
dog;
};

/* 
 *   Animal        
 */
$pig = function() {
    return $this->pig;
};

$bindCat = Closure::bind($cat, null, new Animal());//       Animal      ,       $this  
$bindDog = Closure::bind($dog, new Animal(), 'Animal');//       Animal     ,   Animal      $this       
$bindPig = Closure::bind($pig, new Animal());//  Animal      $this       ,         
echo $bindCat(),'
';// , Animal echo $bindDog(),'
';// , $this (Animal ) Animal echo $bindPig(),'
';// , $this Animal ?>

出力:
cat dog pig
Closure::bindTo-現在の閉パッケージオブジェクトをコピーし、指定した$thisオブジェクトとクラスの役割ドメインをバインドします.説明は次のとおりです.
public Closure Closure::bindTo (object $newthis [, mixed $newscope = 'static' ])
newthsは、閉パッケージオブジェクトにバインドされたオブジェクト、またはNULLがバインドを解除することを示す.
Newscopeは、閉パッケージオブジェクトに関連付けられたクラス役割ドメインを表し、クラス名またはクラスの例を入力できます.デフォルト値は'static'で、変更しないことを示します.
このメソッドは、現在のオブジェクトと同じ変数をバインドしているが、異なるオブジェクトをバインドしたり、新しいクラスの役割ドメインをバインドしたりする閉パッケージオブジェクトを作成して返します.バインドされたオブジェクトは、返される閉パケットオブジェクトの$thisの値を決定し、クラスの役割ドメインは、返される閉パケットオブジェクトがどのメソッドを呼び出すことができるかを決定します.すなわち、このとき$thisが呼び出すことができるメソッドは、newscopeクラスの役割ドメインと同じです.
例1:
render(new Article, 'tpl.php');
?>

Template.phpテンプレートクラス
bindTo($context, $context);
        $closure($tpl);
    }

}

Article.php情報クラス

tpl.phpテンプレートファイル


    
        
    
    
        

title;?>

content;?>

実行時に、上記のファイルが兄弟ディレクトリにあることを確認します.
出力:
これは文章のタイトルです.
これは文章の内容です.
例2:
$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 = 'dog';
}

$animal = new Animal;

//                       $dog
$animal->getdog = function() {
    return $this->dog;
};

echo $animal->getdog();

?>
出力:
dog
例3:
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('butter', 10);
$my_cart->add('milk', 3);
$my_cart->add('eggs', 12);

//       ,    5%     .
echo $my_cart->getTotal(0.05);

?>
出力:
132.88補足:パッケージを閉じるには、USEキーを使用して外部変数を接続できます.
まとめ:閉包を合理的に使用することで、コードをより簡潔に精製することができます.