2017-10-29 11 views
1

PHPの匿名関数については本当に混乱しています。匿名関数が主に味やコーディングスタイルの問題として使用されているかどうかを知りたいです。PHPの匿名関数の使用

私は、コールバック関数と少ないコードなしで同じ結果を得ることができるので、これを求めています。

$output = 10; 
$people = (new People(new John)); 

//VERSION 1 ANONYMOUS FUNCTION 
$people->run(function ($value) use(&$output){ 
    $output = $output + $value; 
}); 

var_dump($output); //RESULT => 20 

//VERSION 2 WITHOUT ANONYMOUS FUNCTION 
var_dump($people->run() + $output); //RESULT => 30 

あなたがここに完全なコードを実行して見ることができます:だからここ

は、いくつかのテストコードがある https://www.tehplayground.com/IhWJJU0jbNnzuird

<?php 

interface HumanInterface 
{ 
    public function hello(); 
} 

class People 
{ 
    protected $person; 
    protected $value; 

    public function __construct(HumanInterface $person) 
    { 
     $this->person = $person; 
     return $this; 
    } 

    public function run(callable $callback = null, $name = null) 
    { 
     $this->value = 10; 
     if(is_callable($callback)) { 
      return call_user_func($callback, $this->value); 
     } 

     return $this->value; 
    } 
} 

class John implements HumanInterface 
{ 
    public function hello() 
    { 
     return 'hi i am john'; 
    } 
} 
$output = 10; 
$people = (new People(new John)); 
$people->run(function ($value) use(&$output){ 
    $output = $output + $value; 
}); 

var_dump($output); 
var_dump($people->run() + $output); 

をだから私の質問は:なぜ使用無名関数ですか?それは 個人的な選択の問題ですか?

答えて

1

ワンタイムコールバックとして使用する場合、匿名関数または「クロージャ」は非常に便利です。たとえば、PHPのusort-methodを使用する場合。 2番目のパラメータはClosureです。したがって、一度使用された名前付き関数を作成する代わりに、Closureを使用することはありません。 IMHOこれはクローズをコールバックとして使用する唯一の方法です。

1

匿名関数は、後で実行するために、または他のコード受け入れ関数に渡すのに便利です。それらを使用すると、コードを大幅に減らすことができます。

下に汎用コレクションを使用するUserCollectionオブジェクトがあるとします。特定の国のユーザーだけにUserCollectionを減らしたいとします。だから、UserCollection上の方法findByCountry()を追加することができます。

public function findByCountry($country) : UserCollection { 
    $subset = new UserCollection; 
    foreach ($this->users as $user) { 
     if ($user->country === $country) { 
      $subset->add($user); 
     } 
    } 
    return $subset; 
} 

これは、すべての罰金ですが、追加の検索メソッドは、すべて同じことをするでしょう:反復処理し、唯一の基準が異なっているとのサブセットに集めます。だから、定型的なコードがたくさんあります。

あなたは簡単にこのように、基本となるコレクションに方法find(callable $callback)を追加することにより、基準から定型を分離することができます:

public function find(callable $criteria) : Collection { 
    $subset = new Collection; 
    foreach ($this->users as $user) { 
     if ($criteria($user)) { 
      $subset->add($user); 
     } 
    } 
    return $subset; 
} 

これは、一般的なファインダーです。今UserCollectionでコードが唯一の実際の基準が含まれます:定型から基準を分離することにより

public function findByCountry($country): UserCollection { 
    return $this->subset(function(User $user) { 
     return $user->country === $country; 
    }); 
} 

private function subset($criteria): UserCollection { 
    return new UserCollection($this->allUsers->find($criteria)); 
} 

を、それはあなたが国によってユーザーを検索しようとしていることを把握するためにはるかに簡単です。実際の基準から逸脱する反復コードはありません。それで、理解するのが簡単になり、書くのに手間が減ります。また、他の場所で定義されているので、誤って反復を混乱させることはありません。

このような匿名関数を使用する場合は、戦略パターンまたはFilterIteratorと非常によく似ています。注目すべき違いは、それらをオンザフライで作成していることです。

differentiate between Lambdas and Closuresに注意してください。私は故意にこの答えの違いを無視しました。