目次
PHP Clouse (クロージャ クラス) 簡単な分析
ホームページ バックエンド開発 PHPチュートリアル PHP クロージャと Clouse クラス メソッドの機能を分析する

PHP クロージャと Clouse クラス メソッドの機能を分析する

Feb 05, 2022 am 04:00 AM
php

PHP Clouse (クロージャ クラス) 簡単な分析

0x00 はじめに

クロージャとは、作成時に周囲の状態をカプセル化する関数を指します。クロージャが配置されている環境が存在しなくなっても、クロージャにカプセル化された状態は依然として存在します。

PHP のすべてのクロージャは、Clouse クラスによってインスタンス化されたオブジェクトです。つまり、クロージャは他の PHP オブジェクトと何ら変わりません。オブジェクトにはそのメソッドとプロパティが必要です。この記事では、PHP におけるクロージャの基本的な使用法と Clouse クラス メソッドの役割を要約します。 [推奨: PHP ビデオ チュートリアル ]

0x01 クロージャの基本的な使用法

クロージャの最も基本的な使用法を見てみましょう:

<?php
$hello = function ($word) {
    return &#39;hello &#39; . $word;
};
echo $hello(&#39;world&#39;);
// 输出 hello world
ログイン後にコピー

ねえ、このコードの最も直感的な感じは、関数を $hello 変数に割り当て、それを $hello 経由で直接呼び出すことです。ただし、このクロージャは親スコープから変数を継承しません (つまり、周囲の状態をカプセル化します) use キーワードを通じてクロージャの親スコープから変数を継承できます。例は次のとおりです。

<?php
$name = &#39;panda&#39;;
$hello = function () use ($name) {
    return &#39;hello &#39; . $name;
};
echo $hello();
// 输出 hello panda
ログイン後にコピー

PHP 7.1 以降、スーパーグローバル、$this、またはパラメーターと同じ名前を持つ変数を渡すことはできません。

さらに、 use キーワードを使用すると、親スコープの変数が値によってクロージャに渡されます。つまり、クロージャが作成されると、外部変数が変更されたとしても、クロージャに渡される値には影響しません(つまり、クロージャが配置されている環境が存在しなくても、カプセル化された状態は影響を受けません)。閉鎖はまだ存在します)。例は次のとおりです:

<?php
$name = &#39;panda&#39;;
$hello = function () use ($name) {
    return &#39;hello &#39; . $name;
};
$name = &#39;cat&#39;;
echo $hello();
// 输出 hello panda
ログイン後にコピー

変数への参照を渡すと、クロージャが外部変数の値を変更できるようになります。例は次のとおりです:

<?php
$name = &#39;panda&#39;;
$changeName = function () use (&$name) {
    $name = &#39;cat&#39;;
};
$changeName();
echo $name;
// 输出 cat
ログイン後にコピー

注: オブジェクトを渡すときPHP では、デフォルトでは参照によって渡されるため、クロージャ内でパッケージ内で使用によって渡されたオブジェクトを操作する場合には特別な注意を払う必要があります。例は次のとおりです。

<?php
class Dog {
    public $name = &#39;Wang Cai&#39;;
}
$dog = new Dog();
$changeName = function () use ($dog) {
    $dog->name = &#39;Lai Fu&#39;;
};
$changeName();
echo $dog->name;
// 输出 Lai Fu
ログイン後にコピー

0x02 Closure class

クロージャが単なる Closure クラス オブジェクトであることを証明します

<?php
$clourse = function () {
    echo &#39;hello clourse&#39;;
};
if (is_object($clourse)) {
    echo get_class($clourse);
}
// 输出 Closure
ログイン後にコピー

上記のコードは出力します。 Closure。クロージャが単なる通常の Closure クラス オブジェクトであることを証明します。

Clourse クラスの概要

クロージャ クラスの関連情報は、PHP 公式マニュアルで確認できます。 PhpStorm のローカル ドキュメント。

/**
 * Class used to represent anonymous functions.
 * <p>Anonymous functions, implemented in PHP 5.3, yield objects of this type.
 * This fact used to be considered an implementation detail, but it can now be relied upon.
 * Starting with PHP 5.4, this class has methods that allow further control of the anonymous function after it has been created.
 * <p>Besides the methods listed here, this class also has an __invoke method.
 * This is for consistency with other classes that implement calling magic, as this method is not used for calling the function.
 * @link http://www.php.net/manual/en/class.closure.php
 */
final class Closure {
    /**
     * This method exists only to disallow instantiation of the Closure class.
     * Objects of this class are created in the fashion described on the anonymous functions page.
     * @link http://www.php.net/manual/en/closure.construct.php
     */
    private function __construct() { }
    /**
     * This is for consistency with other classes that implement calling magic,
     * as this method is not used for calling the function.
     * @param mixed $_ [optional]
     * @return mixed
     * @link http://www.php.net/manual/en/class.closure.php
     */
    public function __invoke(...$_) { }
    /**
     * Duplicates the closure with a new bound object and class scope
     * @link http://www.php.net/manual/en/closure.bindto.php
     * @param object $newthis The object to which the given anonymous function should be bound, or NULL for the closure to be unbound.
     * @param mixed $newscope The class scope to which associate the closure is to be associated, or &#39;static&#39; 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.
     * @return Closure Returns the newly created Closure object or FALSE on failure
     */
    function bindTo($newthis, $newscope = &#39;static&#39;) { }
    /**
     * This method is a static version of Closure::bindTo().
     * See the documentation of that method for more information.
     * @static
     * @link http://www.php.net/manual/en/closure.bind.php
     * @param Closure $closure The anonymous functions to bind.
     * @param object $newthis The object to which the given anonymous function should be bound, or NULL for the closure to be unbound.
     * @param mixed $newscope The class scope to which associate the closure is to be associated, or &#39;static&#39; 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.
     * @return Closure Returns the newly created Closure object or FALSE on failure
     */
    static function bind(Closure $closure, $newthis, $newscope = &#39;static&#39;) { }
    /**
     * Temporarily binds the closure to newthis, and calls it with any given parameters.
     * @link http://php.net/manual/en/closure.call.php
     * @param object $newThis The object to bind the closure to for the duration of the call.
     * @param mixed $parameters [optional] Zero or more parameters, which will be given as parameters to the closure.
     * @return mixed
     * @since 7.0
     */
    function call ($newThis, ...$parameters) {}
    
    /**
     * @param callable $callable
     * @return Closure
     * @since 7.1
     */
    public static function fromCallable (callable $callable) {}
}
ログイン後にコピー

まず第一に、Clouse クラスは最終クラスであるため、継承できません。次に、そのコンストラクター __construct が private に設定されているため、new キーワードを使用してクロージャー オブジェクトをインスタンス化できません。これら 2 つの保証は、クロージャが構文関数 (...) use(...) {...} を通じてのみインスタンス化できることを保証します。

クロージャはなぜ関数として実行できるのでしょうか?

上記のクラス概要から、Clouse クラスが __invoke メソッドを実装していることがわかります。このメソッドは、PHP 公式マニュアルで次のように説明されています。 function オブジェクトが呼び出されるとき、__invoke() メソッドが自動的に呼び出されます。

これが、クロージャを関数として実行できる理由です。

指定された $this オブジェクトとクラス スコープをバインドします

クロージャ ルーティングの使用を許可するフレームワーク (Slim など) では、次のような記述が見られます。

$app->get(&#39;/test&#39;, function () {
    echo $this->request->getMethod();
});
ログイン後にコピー

$this をクロージャで使用できますか?この $this はどのオブジェクトを指しているのでしょうか?

$this とクラス スコープをバインドする機能は、bindTo メソッドとバインド メソッドを通じて実現できます。例は次のとおりです:

<?php
class Pandas {
    public $num = 1;
}
$pandas = new Pandas();
$add = function () {
    echo ++$this->num . PHP_EOL;
};
$newAdd1 = $add->bindTo($pandas);
$newAdd1();
// 输出 2
$newAdd2 = Closure::bind($add, $pandas);
$newAdd2();
// 输出 3
ログイン後にコピー

上記の例は、指定されたオブジェクトをクロージャ $ this としてバインドします。ですが、クラススコープを指定しませんでした。そのため、Pandas クラスの $num プロパティを protected または private に書き換えると、致命的なエラーがスローされます。

Fatal error: Uncaught Error: Cannot access protected property Pandas::$num
ログイン後にコピー

バインドされたオブジェクトの非パブリック プロパティまたはメソッドにアクセスする必要がある場合、クラス スコープを指定する必要があります。例は次のとおりです:

<?php
class Pandas {
    protected $num = 1;
}
$pandas = new Pandas();
$add = function () {
    echo ++$this->num . PHP_EOL;
};
$newAdd1 = $add->bindTo($pandas, $pandas);
$newAdd1();
// 输出 2
$newAdd2 = Closure::bind($add, $pandas, &#39;Pandas&#39;);
$newAdd2();
// 输出 3
ログイン後にコピー

ここでは、両方のbindTo メソッドとバインド メソッドでは、$newscope.パラメータを指定します。$newscope パラメータのデフォルトは static であり、クラス スコープは変更されません。 $newscope パラメータはクラス名またはオブジェクトを受け入れ、クロージャのクラス スコープを指定されたクラス スコープに変更します。このとき、クロージャは Pandas クラスの $num プロパティにアクセスできます。

$this オブジェクトとクラス スコープを 1 回バインドして実行する (PHP7)

新しいオブジェクトとクラス スコープが指定されるたびに、bindTo メソッドと binding メソッドが実行されます。元のクロージャをコピーしてから新しいクロージャを返すと、バインドされたオブジェクトを何度も変更する必要があると面倒になるため、PHP7 ではクロージャをオブジェクトに一時的にバインドできる新しいメソッド呼び出しが提供されます (クラス スコープも変更されます)。オブジェクトが属するクラスに追加) して実行されます。例は次のとおりです。

<?php
class Pandas {
    protected $num = 1;
}
$pandas = new Pandas();
$add = function ($num) {
    $this->num += $num;
    echo $this->num . PHP_EOL;
};
$add->call($pandas, 5);
// 输出 6
ログイン後にコピー

Callable to Closure (PHP7.1)

PHP7.1 では、Closure クラスに呼び出し可能な型を変換できる fromCallable メソッドがあります。

<?php
class Foo
{
    protected $num = 1;
    public static function hello(string $bar)
    {
        echo &#39;hello &#39; . $bar;
    }
}
$hello = Closure::fromCallable([&#39;Foo&#39;, &#39;hello&#39;]);
$hello(&#39;world&#39;);
ログイン後にコピー

この記述方法は非常にクールです。結局のところ、call_user_func 関数で呼び出すよりも、クロージャーを介して呼び出す方がはるかに楽しいです^_^。

0x03 概要

詳細については、PHP 公式マニュアルの Closure クラスの中国語版がまだ公開されていないため、Closure クラスと無名関数を参照してください。更新されていますが、call メソッドと fromCallable メソッドはありません。内容については、英語版を読むことをお勧めします (ㄒoㄒ)

以上がPHP クロージャと Clouse クラス メソッドの機能を分析するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

今まで知らなかったことを後悔している 7 つの PHP 関数 今まで知らなかったことを後悔している 7 つの PHP 関数 Nov 13, 2024 am 09:42 AM

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

PHPでHTML/XMLを解析および処理するにはどうすればよいですか? PHPでHTML/XMLを解析および処理するにはどうすればよいですか? Feb 07, 2025 am 11:57 AM

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

母音を文字列にカウントするPHPプログラム 母音を文字列にカウントするPHPプログラム Feb 07, 2025 pm 12:12 PM

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

PHPでの後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? Apr 03, 2025 am 12:03 AM

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。

See all articles