1

このようなもの (javascript 風のインライン関数) が PHP で機能するとは思いもしませんでした。javascript/jquery の作成に多くの時間を費やしている者として、「これが機能するかどうか疑問に思う」という試みが実際に機能したとき、私はかなり唖然としました。

usort($inbox_messages, function($a, $b){
    return strtotime($b["date"]) - strtotime($a["date"]);
});

さて、そのような実装について知っておくべきことはありますか? パフォーマンスの問題、下位互換性、スコープなど。

これは一般的な慣行ですか、それとも悪いコードですか?

4

2 に答える 2

2

さまざまな環境で実行するためにコードを配布する必要がある場合は、後方互換性が問題になる可能性があります。PHP 5.3より前では、匿名関数はサポートされていません。古いホスティングプラットフォームとエンタープライズサーバーのインストールは、ベンダーがサポートするLinuxディストリビューションなどを使用して5.2.xでスタックしていることがよくあります。

これは過去1年間で急速に変化していますが、これらの古いインストールのサポートサイクルが期限切れになるため、数年間は検討すべき問題が残ります。

変数スコープとuseキーワードに関連する問題については、無名関数に関するリンクされたドキュメントを参照してください。

于 2012-09-29T14:30:14.763 に答える
2

この機能は無名関数と呼ばれ、PHP 5.3 以降で利用できるようになりました。

クロージャとも呼ばれる匿名関数を使用すると、名前が指定されていない関数を作成できます。これらはコールバック パラメータの値として最も便利ですが、他にも多くの用途があります。

それらには、スコープの解像度にも(わずかな)違いがあります。

クロージャーは、親スコープから変数を継承する場合もあります。このような変数は、関数ヘッダーで宣言する必要があります。親スコープから変数を継承することは、グローバル変数を使用することと同じではありません。

したがって、この例では:

$total = 0.00;
$callback = function ($quantity, $product) use ($tax, &$total)
{
    $pricePerItem = constant(__CLASS__ . "::PRICE_" . strtoupper($product));
    $total += ($pricePerItem * $quantity) * ($tax + 1.0);
};
array_walk($this->products, $callback);

...そのドキュメントページから、キーワードを使用せずに ($callback) スコープに効果的$tax$total挿入されます。closureglobal

無名関数は、実際にはClosureクラスのオブジェクトです。そして、これは単なる実装機能ではありません: (PHP 5.4 以降) これらの関数は$thisオブジェクト (JavaScript のコンテキスト オブジェクトと同様) を使用できるため、このコンテキストを変更できる便利なメソッドがいくつかあります ( Closure::bindClosure::bindTo -これらをFunction.bindと比較してください)。

より具体的に言えば、コレクションをmap/するときに匿名関数を使用することは、実際には良い習慣です。これらの関数はグローバル スコープに入らないからです。filterしかしもちろん、コードを PHP 5.2 で動作させる必要がある場合、これは解決策ではありません。

于 2012-09-29T14:36:42.083 に答える