検索

PHP学習 - PHPクロージャ

PHPクロージャ(Closure)は、PHP5.3で導入された匿名関数です。

クロージャの構文は非常に単純で、注意が必要なキーワードはクロージャと外部変数を接続することです。

<span style="color: #800080;">$a</span> = <span style="color: #0000ff;">function</span>() <span style="color: #0000ff;">use</span>(<span style="color: #800080;">$b</span>) {}

簡単な例は次のとおりです:

<span style="color: #0000ff;">function</span> <span style="color: #0000ff;">callback</span>(<span style="color: #800080;">$fun</span><span style="color: #000000;">) {</span><span style="color: #800080;">$fun</span><span style="color: #000000;">();}</span><span style="color: #800080;">$msg</span> = "Hello, everyone"<span style="color: #000000;">;</span><span style="color: #800080;">$fun</span> = <span style="color: #0000ff;">function</span> () <span style="color: #0000ff;">use</span>(<span style="color: #800080;">$msg</span><span style="color: #000000;">) {</span><span style="color: #0000ff;">print</span> "This is a closure use string value, msg is: <span style="color: #800080;">$msg</span>. <br>/n"<span style="color: #000000;">;};</span><span style="color: #800080;">$msg</span> = "Hello, everybody"<span style="color: #000000;">;</span><span style="color: #0000ff;">callback</span>(<span style="color: #800080;">$fun</span>);

結果は次のようになります: これはクロージャを使用する文字列ですvalue、msg は次のとおりです。皆さん、こんにちは。
/n

PHP の新しく開かれたクロージャ構文では、クロージャの外側で定義された変数を使用するために use を使用します。 ここでは外部変数 $msg を使用します。定義後、その値はクロージャーの実行後に変更され、元の値が出力されます。 基本型 パラメータは値によって渡され、クロージャの使用値はクロージャの作成時に決定されます。

小さなアプリケーションは次のとおりです:

<span style="color: #008000;">/*</span><span style="color: #008000;">*  * 一个利用闭包的计数器产生器  * 这里其实借鉴的是python中介绍闭包时的例子...  * 我们可以这样考虑:  *      1. counter函数每次调用, 创建一个局部变量$counter, 初始化为1.  *      2. 然后创建一个闭包, 闭包产生了对局部变量$counter的引用.  *      3. 函数counter返回创建的闭包, 并销毁局部变量, 但此时有闭包对$counter的引用,   *          它并不会被回收, 因此, 我们可以这样理解, 被函数counter返回的闭包, 携带了一个游离态的  *          变量.  *      4. 由于每次调用counter都会创建独立的$counter和闭包, 因此返回的闭包相互之间是独立的.  *      5. 执行被返回的闭包, 对其携带的游离态变量自增并返回, 得到的就是一个计数器.  * 结论: 此函数可以用来生成相互独立的计数器.  </span><span style="color: #008000;">*/</span>  <span style="color: #0000ff;">function</span><span style="color: #000000;"> counter() {      </span><span style="color: #800080;">$counter</span> = 1<span style="color: #000000;">;      </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">function</span>() <span style="color: #0000ff;">use</span>(&<span style="color: #800080;">$counter</span>) {<span style="color: #0000ff;">return</span> <span style="color: #800080;">$counter</span> ++<span style="color: #000000;">;};  }  </span><span style="color: #800080;">$counter1</span> =<span style="color: #000000;"> counter();  </span><span style="color: #800080;">$counter2</span> =<span style="color: #000000;"> counter();  </span><span style="color: #0000ff;">echo</span> "counter1: " . <span style="color: #800080;">$counter1</span>() . "<br>/n"<span style="color: #000000;">;  </span><span style="color: #0000ff;">echo</span> "counter1: " . <span style="color: #800080;">$counter1</span>() . "<br>/n"<span style="color: #000000;">;  </span><span style="color: #0000ff;">echo</span> "counter1: " . <span style="color: #800080;">$counter1</span>() . "<br>/n"<span style="color: #000000;">;  </span><span style="color: #0000ff;">echo</span> "counter1: " . <span style="color: #800080;">$counter1</span>() . "<br>/n"<span style="color: #000000;">;  </span><span style="color: #0000ff;">echo</span> "counter2: " . <span style="color: #800080;">$counter2</span>() . "<br>/n"<span style="color: #000000;">;  </span><span style="color: #0000ff;">echo</span> "counter2: " . <span style="color: #800080;">$counter2</span>() . "<br>/n"<span style="color: #000000;">;  </span><span style="color: #0000ff;">echo</span> "counter2: " . <span style="color: #800080;">$counter2</span>() . "<br>/n"<span style="color: #000000;">;  </span><span style="color: #0000ff;">echo</span> "counter2: " . <span style="color: #800080;">$counter2</span>() . "<br>/n"<span style="color: #000000;">;  </span>?>

クロージャーの役​​割

1. foreach ループのコードを削減します

たとえば、Cart

<span style="color: #000000;">php</span><span style="color: #008000;">//</span><span style="color: #008000;"> 一个基本的购物车,包括一些已经添加的商品和每种商品的数量。// 其中有一个方法用来计算购物车中所有商品的总价格。该方法使用了一个closure作为回调函数。</span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Cart{    </span><span style="color: #0000ff;">const</span> PRICE_BUTTER  = 1.00<span style="color: #000000;">;    </span><span style="color: #0000ff;">const</span> PRICE_MILK    = 3.00<span style="color: #000000;">;    </span><span style="color: #0000ff;">const</span> PRICE_EGGS    = 6.95<span style="color: #000000;">;     </span><span style="color: #0000ff;">protected</span>   <span style="color: #800080;">$products</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">();         </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> add(<span style="color: #800080;">$product</span>, <span style="color: #800080;">$quantity</span><span style="color: #000000;">)    {        </span><span style="color: #800080;">$this</span>->products[<span style="color: #800080;">$product</span>] = <span style="color: #800080;">$quantity</span><span style="color: #000000;">;    }         </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getQuantity(<span style="color: #800080;">$product</span><span style="color: #000000;">)    {        </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->products[<span style="color: #800080;">$product</span>]) ? <span style="color: #800080;">$this</span>->products[<span style="color: #800080;">$product</span>] :               <span style="color: #0000ff;">FALSE</span><span style="color: #000000;">;    }         </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getTotal(<span style="color: #800080;">$tax</span><span style="color: #000000;">)    {        </span><span style="color: #800080;">$total</span> = 0.00<span style="color: #000000;">;                 </span><span style="color: #800080;">$callback</span> =            <span style="color: #0000ff;">function</span> (<span style="color: #800080;">$quantity</span>, <span style="color: #800080;">$product</span>) <span style="color: #0000ff;">use</span> (<span style="color: #800080;">$tax</span>, &<span style="color: #800080;">$total</span><span style="color: #000000;">)            {                </span><span style="color: #800080;">$pricePerItem</span> = <span style="color: #008080;">constant</span>(<span style="color: #ff00ff;">__CLASS__</span> . "::PRICE_" .                    <span style="color: #008080;">strtoupper</span>(<span style="color: #800080;">$product</span><span style="color: #000000;">));                </span><span style="color: #800080;">$total</span> += (<span style="color: #800080;">$pricePerItem</span> * <span style="color: #800080;">$quantity</span>) * (<span style="color: #800080;">$tax</span> + 1.0<span style="color: #000000;">);            };        </span><span style="color: #008000;">//</span><span style="color: #008000;">使用用户自定义函数对数组中的每个元素做回调处理</span>        <span style="color: #008080;">array_walk</span>(<span style="color: #800080;">$this</span>->products, <span style="color: #800080;">$callback</span><span style="color: #000000;">);        </span><span style="color: #0000ff;">return</span> <span style="color: #008080;">round</span>(<span style="color: #800080;">$total</span>, 2<span style="color: #000000;">);;    }} </span><span style="color: #800080;">$my_cart</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Cart; </span><span style="color: #008000;">//</span><span style="color: #008000;"> 往购物车里添加条目</span><span style="color: #800080;">$my_cart</span>->add('butter', 1<span style="color: #000000;">);</span><span style="color: #800080;">$my_cart</span>->add('milk', 3<span style="color: #000000;">);</span><span style="color: #800080;">$my_cart</span>->add('eggs', 6<span style="color: #000000;">); </span><span style="color: #008000;">//</span><span style="color: #008000;"> 打出出总价格,其中有 5% 的销售税.</span><span style="color: #0000ff;">print</span> <span style="color: #800080;">$my_cart</span>->getTotal(0.05) . "\n"<span style="color: #000000;">;</span><span style="color: #008000;">//</span><span style="color: #008000;"> The result is 54.29</span>?>
を変形すると、 getTotal 関数は foreach を使用する必要があります。

2. 関数のパラメータを減らす

<span style="color: #0000ff;">function</span> html(<span style="color: #800080;">$code</span> , <span style="color: #800080;">$id</span>="", <span style="color: #800080;">$class</span>=""<span style="color: #000000;">){</span><span style="color: #0000ff;">if</span> (<span style="color: #800080;">$id</span> !== "") <span style="color: #800080;">$id</span> = " id = \"<span style="color: #800080;">$id</span>\""<span style="color: #000000;"> ;</span><span style="color: #800080;">$class</span> = (<span style="color: #800080;">$class</span> !== "")? " class =\"<span style="color: #800080;">$class</span>\">":">"<span style="color: #000000;">;</span><span style="color: #800080;">$open</span> = "$code$id$class"<span style="color: #000000;">;</span><span style="color: #800080;">$close</span> = "<span style="color: #800080;">$code</span>>"<span style="color: #000000;">;</span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">function</span> (<span style="color: #800080;">$inner</span> = "") <span style="color: #0000ff;">use</span> (<span style="color: #800080;">$open</span>, <span style="color: #800080;">$close</span><span style="color: #000000;">){</span><span style="color: #0000ff;">return</span> "<span style="color: #800080;">$open$inner$close</span>"<span style="color: #000000;">;    };}</span>
通常の方法を使用する場合、html 関数のパラメータに inner を入れます。コードの読み取り クロージャを使用するよりもクロージャを使用する方が良いでしょう。

3. 再帰関数のロックを解除します

<span style="color: #000000;">php</span><span style="color: #800080;">$fib</span> = <span style="color: #0000ff;">function</span>(<span style="color: #800080;">$n</span>) <span style="color: #0000ff;">use</span>(&<span style="color: #800080;">$fib</span><span style="color: #000000;">) {    </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$n</span> == 0 || <span style="color: #800080;">$n</span> == 1) <span style="color: #0000ff;">return</span> 1<span style="color: #000000;">;    </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$fib</span>(<span style="color: #800080;">$n</span> - 1) + <span style="color: #800080;">$fib</span>(<span style="color: #800080;">$n</span> - 2<span style="color: #000000;">);}; </span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">$fib</span>(2) . "\n"; <span style="color: #008000;">//</span><span style="color: #008000;"> 2</span><span style="color: #800080;">$lie</span> = <span style="color: #800080;">$fib</span><span style="color: #000000;">;</span><span style="color: #800080;">$fib</span> = <span style="color: #0000ff;">function</span>(){<span style="color: #0000ff;">die</span>('error');};<span style="color: #008000;">//</span><span style="color: #008000;">rewrite $fib variable </span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">$lie</span>(5); <span style="color: #008000;">//</span><span style="color: #008000;"> error   because $fib is referenced by closure</span>
ここで & が使用されていない場合、エラーが発生することに注意してください。 >

fib(n-1) が見つかりませんfunction ( fib のタイプは以前に定義されていませんでした) したがって、ループ関数をキャンセルするためにクロージャーを使用したい場合は、

<span style="color: #000000;">php</span><span style="color: #800080;">$recursive</span> = <span style="color: #0000ff;">function</span> () <span style="color: #0000ff;">use</span> (&<span style="color: #800080;">$recursive</span><span style="color: #000000;">){</span><span style="color: #008000;">//</span><span style="color: #008000;"> The function is now available as $recursive</span>}
4. バインディングの遅延

使用中の変数のバインドを遅らせる必要がある場合は、参照を使用する必要があります。そうしないと、定義時にコピーが作成されて使用されます

参照を使用するかどうかは、
<span style="color: #000000;">php</span><span style="color: #800080;">$result</span> = 0<span style="color: #000000;">; </span><span style="color: #800080;">$one</span> = <span style="color: #0000ff;">function</span><span style="color: #000000;">(){    </span><span style="color: #008080;">var_dump</span>(<span style="color: #800080;">$result</span><span style="color: #000000;">);}; </span><span style="color: #800080;">$two</span> = <span style="color: #0000ff;">function</span>() <span style="color: #0000ff;">use</span> (<span style="color: #800080;">$result</span><span style="color: #000000;">){    </span><span style="color: #008080;">var_dump</span>(<span style="color: #800080;">$result</span><span style="color: #000000;">);}; </span><span style="color: #800080;">$three</span> = <span style="color: #0000ff;">function</span>() <span style="color: #0000ff;">use</span> (&<span style="color: #800080;">$result</span><span style="color: #000000;">){    </span><span style="color: #008080;">var_dump</span>(<span style="color: #800080;">$result</span><span style="color: #000000;">);}; </span><span style="color: #800080;">$result</span>++<span style="color: #000000;">; </span><span style="color: #800080;">$one</span>();    <span style="color: #008000;">//</span><span style="color: #008000;"> outputs NULL: $result is not in scope</span><span style="color: #800080;">$two</span>();    <span style="color: #008000;">//</span><span style="color: #008000;"> outputs int(0): $result was copied</span><span style="color: #800080;">$three</span>();    <span style="color: #008000;">//</span><span style="color: #008000;"> outputs int(1)</span>

の呼び出し時に値を代入するか、宣言時に値を代入するかを意味します。
声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
PHPセッションがすでに開始されているかどうかを確認するにはどうすればよいですか?PHPセッションがすでに開始されているかどうかを確認するにはどうすればよいですか?Apr 30, 2025 am 12:20 AM

PHPでは、session_status()またはsession_id()を使用して、セッションが開始されたかどうかを確認できます。 1)session_status()関数を使用します。 php_session_activeが返された場合、セッションが開始されました。 2)SESSION_ID()関数を使用します。空の文字列が返された場合、セッションが開始されます。どちらの方法でもセッション状態を効果的に確認でき、使用する方法を選択することは、PHPバージョンと個人的な好みに依存します。

Webアプリケーションでセッションを使用することが不可欠なシナリオを説明してください。Webアプリケーションでセッションを使用することが不可欠なシナリオを説明してください。Apr 30, 2025 am 12:16 AM

Sessionsionsionsarevitalinwebapplications、特にコマースプラットフォームの前。

PHPでの同時セッションアクセスをどのように管理できますか?PHPでの同時セッションアクセスをどのように管理できますか?Apr 30, 2025 am 12:11 AM

PHPでの同時セッションアクセスの管理は、次の方法で実行できます。1。データベースを使用してセッションデータを保存します。これらの方法は、データの一貫性を確保し、並行性のパフォーマンスを向上させるのに役立ちます。

PHPセッションを使用することの制限は何ですか?PHPセッションを使用することの制限は何ですか?Apr 30, 2025 am 12:04 AM

phpsessionshaveverallimitations:1)storagecconstraintscanleadtoperformanceissues; 2)securityvulnerablesliasitylikessessionfixationAttacksicexist;

負荷分散がセッション管理にどのように影響し、それに対処するかを説明します。負荷分散がセッション管理にどのように影響し、それに対処するかを説明します。Apr 29, 2025 am 12:42 AM

負荷分散はセッション管理に影響しますが、セッションの複製、セッションの粘着性、集中セッションストレージで解決できます。 1。セッションレプリケーションサーバー間のセッションデータをコピーします。 2。セッションスティンネスは、ユーザーリクエストを同じサーバーに指示します。 3.集中セッションストレージは、Redisなどの独立したサーバーを使用してセッションデータを保存してデータ共有を確保します。

セッションロックの概念を説明します。セッションロックの概念を説明します。Apr 29, 2025 am 12:39 AM

SESSIONLOCKINGISATECHNIQUESTOESUREAUSER'SSESSIONREMAINSEXCLUSIVETOONEUSATIME.ITISCRUCIALFORPREVENTINGDATACORTIONANDSECURITYBREACHESINMULTI-USERAPPLICATIONS.SESSIONLOCKINGISISIMPLEMENTEDUSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGSINGROCKINGSMECHANISMなど

PHPセッションの選択肢はありますか?PHPセッションの選択肢はありますか?Apr 29, 2025 am 12:36 AM

PHPセッションの代替品には、Cookie、トークンベースの認証、データベースベースのセッション、Redis/Memcachedが含まれます。 1.Cookiesは、クライアントにデータを保存することによりセッションを管理します。 2.トークンベースの認証はトークンを使用してユーザーを検証します。これは非常に安全ですが、追加のロジックが必要です。 3.Databaseベースのセッションは、データベースにデータを保存します。これは、スケーラビリティが良好ですが、パフォーマンスに影響を与える可能性があります。 4. Redis/Memcachedは分散キャッシュを使用してパフォーマンスとスケーラビリティを向上させますが、追加のマッチングが必要です

PHPのコンテキストで「セッションハイジャック」という用語を定義します。PHPのコンテキストで「セッションハイジャック」という用語を定義します。Apr 29, 2025 am 12:33 AM

SessionHijackingとは、ユーザーのSessionIDを取得してユーザーになりすましている攻撃者を指します。予防方法には、次のものが含まれます。1)HTTPSを使用した通信の暗号化。 2)SessionIDのソースの検証。 3)安全なSessionID生成アルゴリズムの使用。 4)SessionIDを定期的に更新します。

See all articles

ホット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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

SublimeText3 Mac版

SublimeText3 Mac版

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

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境