ホームページ  >  記事  >  バックエンド開発  >  PHP Closure クラスとその使用法についての簡単な説明

PHP Closure クラスとその使用法についての簡単な説明

青灯夜游
青灯夜游転載
2021-03-05 17:58:414909ブラウズ

この記事では、PHP Closure クラスと、Closure を使用して匿名関数を作成する方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。

PHP Closure クラスとその使用法についての簡単な説明

推奨学習: 「PHP ビデオ チュートリアル

クロージャ クラス

使用匿名関数を表すクラスの場合。

匿名関数 (PHP 5.3 で導入) は、このタイプのオブジェクトを生成します。以前は、このクラスは実装の詳細とみなされていましたが、現在はこのクラスに依存して何かを行うことができます。 PHP 5.4 以降、
このクラスには、作成後の匿名関数をより詳細に制御できるメソッドが付属しています。

このクラスはインスタンス化できません。このクラスには 2 つの主要なメソッドがあり、どちらもクロージャをコピーするために使用されます。1 つは静的メソッド、もう 1 つは動的メソッドです。これらの 2 つの理解しにくいメソッドについて詳しく説明します。下に。

Closure::bind

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

参数说明:
closure
需要绑定的匿名函数。

newthis
需要绑定到匿名函数的对象,或者 NULL 创建未绑定的闭包。

newscope
想要绑定给闭包的类作用域,或者 'static' 表示不改变。如果传入一个对象,则使用这个对象的类型名。 类作用域用来决定在闭包中 $this 对象的 
私有、保护方法 的可见性。 The class scope to which associate the closure is to be associated, or 'static' to keep the 
current one. If an object is given, the type of the object will be used instead. This determines the visibility of 
protected and private methods of the bound object.

上記はこのメソッドの定義です。最初のパラメータは理解しやすく、クロージャ関数です。2 番目のパラメータは次のとおりです。理解するのは簡単です。コピーされるクロージャに $this が含まれている場合、このオブジェクトはこの
$this を表します。クロージャ関数でのこのオブジェクトの変更は、次の時点で終了します。呼び出しの終了。たとえば、属性が変更された場合など、将来も一貫性が保たれます。3 番目のパラメータは理解するのが難しく、公式の指示も不明瞭です。
デフォルトのパラメータを使用して、 を呼び出します。 $this-&gt ;object $newthis の属性関数にアクセスする場合、制限があり、public 属性を持つ関数のみにアクセスできます。 protected/privateAttribute,
は、対応するクラス名/クラス インスタンスに設定する必要があり、そのクラスの protected/private 属性関数には、クラス内と同様にアクセスする必要があります。

<?php
class T {
    private function show()
    {
        echo "我是T里面的私有函数:show\n";
    }

    protected  function who()
    {
        echo "我是T里面的保护函数:who\n";
    }

    public function name()
    {
        echo "我是T里面的公共函数:name\n";
    }
}

$test = new T();

$func = Closure::bind(function(){
    $this->who();
    $this->name();
    $this->show();
}, $test);

$func();

上記のコードはエラーを報告します致命的エラー: キャッチされないエラー: コンテキスト 'Closure から保護されたメソッド T::who() を呼び出します###。 bind の 3 番目のパラメータを t::class または new T() に追加すると、それぞれの結果が正常に出力されます。

我是T里面的保护函数:who
我是T里面的公共函数:name
我是T里面的私有函数:show
もちろん、クロージャはパラメータを渡すこともできます

$test = new StdClass();
var_dump($test);

$func = Closure::bind(function($obj){
    $obj->name = "燕睿涛";
}, null);

$func($test);
var_dump($test);
上記のプログラムは匿名関数と同じであり、どのオブジェクトにも依存しません。上記のプログラムは出力します:

object(stdClass)#1 (0) {
}
object(stdClass)#1 (1) {
  ["name"]=>
  string(9) "燕睿涛"
}
説明が必要な特別な例もあります

<?php
class T {
    private function show()
    {
        echo "我是T里面的私有函数:show\n";
    }

    protected  function who()
    {
        echo "我是T里面的保护函数:who\n";
    }

    public function name()
    {
        echo "我是T里面的公共函数:name\n";
    }
}

$func = Closure::bind(function ($obj) {
    $obj->show();
}, null);

$test = new T();

$func($test);
上記の状況では何が出力されますか? はい、プライベート属性にアクセスできないことを示すエラーが報告されます

show . このとき、3 番目のパラメータを追加します パラメータは 1 つだけで十分です。3 番目のパラメータが $this のスコープに影響を与えるだけでなく、 がパラメータのスコープにも影響を与える可能性があることがわかります。

Closure::bindTo

bindTo には bind と同様の関数があります。ここでは別の形式を示します。両方とも現在のクロージャ オブジェクトをコピーし、指定された $this オブジェクトとクラス スコープをバインドします。 、最初のパラメータは bind より小さい、最後の 2 つは同じです。もちろん、
bindTo は静的メソッドではなく、存在するという別の違いがあります。プロパティメソッドのクロージャーのためだけです。

<?php
class T {
    private function show()
    {
        echo "我是T里面的私有函数:show\n";
    }

    protected  function who()
    {
        echo "我是T里面的保护函数:who\n";
    }

    public function name()
    {
        echo "我是T里面的公共函数:name\n";
    }
}

$func = function () {
    $this->show();
    $this->who();
    $this->name();
};

$funcNew = $func->bindTo(new T(), T::class);

$funcNew();

上記の関数の出力は、

bind

我是T里面的私有函数:show
我是T里面的保护函数:who
我是T里面的公共函数:name

トリック##に似ています。 #この関数は、composer によって生成された自動読み込みソース コードを調べているときに見つかりました。これは、composer で非常に特別に使用されます。以下は、composer のコードの一部のインターセプトです。

// 文件autoload_real.php
call_user_func(\Composer\Autoload\ComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer($loader));

// 文件autoload_static.php
public static function getInitializer(ClassLoader $loader)
{
    return \Closure::bind(function () use ($loader) {
        $loader->prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4;
        $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4;
        $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0;
        $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap;

    }, null, ClassLoader::class);
}

上記のコードはかなり奇妙です。

call_user_func

では、第一印象は間違ったパラメータが渡されているように見えますが、そうではありません。ここで関数が呼び出され、この関数は を返します。 Closure オブジェクト、匿名関数である 、渡される最後のパラメータは依然として callable
型です。返されたクロージャをもう一度見てください。その中で use が使用されています。これはクロージャと外部変数を接続するブリッジです。 なぜここで通常のパラメータを渡すことができるかというと、php5ではオブジェクトの仮パラメータと実パラメータが同じオブジェクトを指しており、関数内でオブジェクトを変更するとオブジェクトの外にも反映されるからです。
だから、上記のようにすれば大丈夫です、別の方法もあります

call_user_func(\Composer\Autoload\ComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer(), $loader);

public static function getInitializer()
{
    return \Closure::bind(function ($loader) {
        $loader->prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4;
        $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4;
        $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0;
        $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap;

    }, null, ClassLoader::class);
}

まとめ

長い間ブログを書いていませんでした時々興奮しすぎて落ち着かないこともあるし、書きたいことが見つからないこともあります。それでも落ち着いて、すべてをうまくやり、物事が起こっても動揺せず、広い心を保ち、すべてを冷静に処理する必要があります。

書き終えたところで、突然思い出したのですが、私が高校生のとき、ちょうど 5.12 汶川地震の時でした。私たちは西安にいました。地震の後、まだ余震がありました。すぐにわずかな余震でもあったので、皆はパニックになって群がり、急いで降りてきました。私の記憶が正しければ、あるとき物理の先生が授業に来るまで、私たちは 5 階にいたのです。この先生は年上で、大学の特別教師でした。街中(それもそのはず)で、たまたま余震に遭遇して、みんなが狂ってまた逃げようとしていたとき、先生が言った言葉が忘れられない。命は私の骨に宿っている。 「そんな余震は無理に押し込む必要はない。どんなに生活が苦しくても、大丈夫だよ。」
確かに、こんな小さな余震に押しつぶされると、事故が起きやすくなるかもしれません。それはむしろ、穏やかな心の状態、
大きな心、そして冷静かつ決断力のある熟考です。これが私が学びたいことです。 現れるべきものは必ず現れ、現れてはいけないものは決して現れない、やみくもに高みを目指しすぎると、不安になりやすいです。もちろん、自分を卑下する必要はありません。一言で言えば、冷静に、大らかに、思いやりを持ちなさい 損得を気にせず、何事も地に足の着いたやり方でうまくやってください 頑張れば頑張るほど幸運になります 幸運であればあるほど困難になりますあなたは働いています。

プログラミング関連の知識について詳しくは、

プログラミング ビデオ
をご覧ください。 !

以上がPHP Closure クラスとその使用法についての簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。