PHP は Lisp のような関数型プログラミング言語ではありません。さらに重要なのは、PHP は C スタイルでコードを記述するのに適しています。 PHP にはそのような種類の「関数」はありません。つまり、変数を使用して関数を直接渡すことはできません。たとえば、次のコード:
リーリーこれは、PHP が上記のコードを解析する方法です。
リーリーこれは、PHP の関数名が呼び出されないとき (括弧なし) に文字列として扱われることを示しています。
そして、たまたま PHP には、文字列名を通じて関数を動的に呼び出すメソッドがあります:
リーリーC 言語では、高度な FP を実装するために、関数へのポインターを介して関数をパラメーターとして渡すことができますが、PHP では、関数名は文字列として渡され、$fname() を通じて呼び出されます。 ($fname は関数名を値とする文字列型変数です)、または call_user_func を通じて呼び出されます。ここまでくると、PHP での関数の実装によって生じる不都合に気づくことになります。関数は文字列を介して渡され、呼び出されるため、同じ関数名を持つ 2 つの異なる関数が存在してはなりません。つまり、PHP のすべての関数 (ここで言及する「関数」にはメソッドは含まれません) はグローバル関数であり、実行時に再定義することはできません。なぜなら、関数 (おなじみの JavaScript など) を繰り返し定義できる場合、次のコードはエラーを引き起こします:
リーリーPHP の関数はすべてグローバル関数であるため、関数宣言をネストして書くことはできません (クロージャーを参照)。PHP のクロージャーと Lambda について説明する前に、PHP のメソッドについて説明します (つまり、オブジェクトまたはオブジェクトの指定された関数に既にバインドされています)。クラス)。まず単純なクラスを作成し、その静的メソッドを直接出力して内容を確認します。
リーリーそれでは、クラス (またはインスタンス) のメソッドを動的に呼び出したい場合はどうすればよいでしょうか? 実際の例、非常に単純なコントローラーから始めましょう (もちろん、実際のコントローラーはこれほど単純ではありません)
リーリーPHPの可変変数メカニズムを使用することに加えて、以前のcall_user_func関数を使用することもできます。
リーリーインスタンスのメソッドを呼び出す必要がある場合は、
リーリー上記のコードからわかるように、PHP のクラスは文字列名としても渡されます。以下のコードのように:
リーリーPHP 5.2.3 では、PHP でクラスの静的メソッドを呼び出すための別の構文があります。
リーリーPHP 5.3 以降、PHP には名前空間の概念が導入されたため、上記の呼び出しは次のようになります
リーリー上記のコードを見ると、クラスの静的メソッドは、名前空間プレフィックスが追加された単なる関数であると実際に推測できます。
PHP 5.3 より前は、PHP で Lambda を実装するための構文は非常に扱いにくく、構築のために関数内のコードを文字列として create_function メソッドに渡す必要がありました。
リーリーこの種の Lambda サポートは実際には役に立たず、使用すると実際に効率が低下します。
コードを文字列に記述する場合、このスタイルのラムダ作成は非常に短い関数式にのみ適しています。次に、上記の $lambda 変数に格納されている内容を見てください。
リーリー実際、create_function で作成されたものは依然としてグローバル関数ですが、このグローバル関数の名前は推測されません。
おそらく次のような名前の関数を作成してみます:
リーリー実際、create_function で生成される関数名は、NULL 文字と "lambda_" に数値識別子を加えたものであり、関数の宣言時にこの文字を使用することはできないため、上記のコードは競合しません。 . は、次のコードでテストできます。
リーリーcreate_function を使用して記述するのが面倒なだけでなく、create_function メソッドは一般的な一時関数しか作成できません。
クロージャを実装できません(ただし、いくつかのスカラーを読み取るだけであれば、次のように別の方法で実装できます)
リーリーPHP 5.3 では、PHP は実際のクロージャをサポートし始め、ラムダはさらに優れており、JavaScript に近くなります。
リーリーPHP クロージャーの変数参照に問題があります。次のコードは期待どおりに機能しません。
リーリーPHP のクロージャーは元の変数の値をコピーするだけであるため、つまり、使用中にリストされている変数は、実行時のクロージャー関数内のローカル変数であり、関数の外部の変数ではありません。
リーリー想像上の状態を実現したい場合は、変数の前に参照渡しフラグを追加するだけです。
れーれー