为啥以及如何在 PHP 中使用匿名函数?

Posted

技术标签:

【中文标题】为啥以及如何在 PHP 中使用匿名函数?【英文标题】:Why and how do you use anonymous functions in PHP?为什么以及如何在 PHP 中使用匿名函数? 【发布时间】:2011-01-25 14:52:13 【问题描述】:

php 5.3 开始提供匿名函数。 我应该使用它们还是避免它们?如果有,怎么做?

已编辑;刚刚发现了一些 php 匿名函数的好技巧...

$container           = new DependencyInjectionContainer();
$container->mail     = function($container) ;
$conteiner->db       = function($container) ;
$container->memcache = function($container) ;

【问题讨论】:

伙计,我根本不明白 DependencyInjection 的用法。 @Tchalvak,为什么?对我来说,它真的很容易实现和使用。有陷阱吗? @Kirzilla $container = new DependencyInjectionContainer(); 与匿名函数无关 【参考方案1】:

Anonymous functions 在使用需要 callback function 的函数时很有用,例如 array_filterarray_map 这样做:

$arr = range(0, 10);
$arr_even = array_filter($arr, function($val)  return $val % 2 == 0; );
$arr_square = array_map(function($val)  return $val * $val; , $arr);

否则你需要定义一个你可能只使用一次的函数:

function isEven($val)  return $val % 2 == 0; 
$arr_even = array_filter($arr, 'isEven');
function square($val)  return $val * $val; 
$arr_square = array_map('square', $arr);

【讨论】:

这似乎是我找到的关于匿名函数用途的最完整的答案。它强调了这样一个事实,即对于大多数一次性/一次性解决方案,匿名函数允许您在使用代码的地方保持正确的代码,而无需在一个地方定义它并在另一个地方调用。如果您在一个项目中拥有数百或数千个这样的一次性功能,这将变得非常有用。【参考方案2】:

从 PHP 5.3 开始提供匿名函数。

匿名函数在 PHP 中已经存在很长时间了:create_function 自 PHP 4.0.1 以来就已经存在。但是,您说得对,从 PHP 5.3 开始有一个新的概念和语法可用。

我应该使用它们还是避免它们?如果有,怎么做?

如果您以前曾经使用过create_function,那么新语法可以直接滑入您使用它的位置。正如其他答案所提到的,一个常见的情况是“一次性”功能,它们只能使用一次(或至少在一个地方)。通常以array_map/reduce/filter、preg_replace_callback、usort 等回调的形式出现。

使用匿名函数计算字母出现在单词中的次数的示例(这可以通过多种其他方式完成,这只是一个示例):

$array = array('apple', 'banana', 'cherry', 'damson');

// For each item in the array, count the letters in the word
$array = array_map(function($value)
    $letters = str_split($value);
    $counts  = array_count_values($letters);
    return $counts;
, $array);

// Sum the counts for each letter
$array = array_reduce($array, function($reduced, $value) 
    foreach ($value as $letter => $count) 
        if ( ! isset($reduced[$letter])) 
            $reduced[$letter] = 0;
        
        $reduced[$letter] += $count;
    
    return $reduced;
);

// Sort counts in descending order, no anonymous function here :-)
arsort($array);

print_r($array);

给出(为简洁起见):

Array
(
    [a] => 5
    [n] => 3
    [e] => 2
    ... more ...
    [y] => 1
)

【讨论】:

@salathe 所以.. 除了使用回调函数,匿名函数没用吗?我只是不明白炒作是关于什么的【参考方案3】:

也许您可以在Anonymous Functions 上阅读 PHP 的文章。其实还不错。

【讨论】:

嗯,对于php文档,确实是一篇好文章。 是的,确实很好解释【参考方案4】:

匿名函数在将函数创建到 DI 容器中也非常有用,例如“bootstrap.php”:

//add sessions
$di->add("session",function() return new Session(); );
//add cache
$di->add("cache",function() return new Cache(); );
//add class which will be used in any request
$di->add("anyTimeCalledClass", new SomeClass());

使用参数和下一个变量的示例

$di->add("myName",function($params) use($application)
      $application->myMethod($params);
);

所以在这里你可以看到如何使用匿名函数来节省内存和服务器负载。您可以在di 容器中定义所有重要的插件、类,但只会在您需要时创建实例。

【讨论】:

你好@brasofilo,你能解释一下吗?我无法理解其中的区别。 @San 区别以注册时为例: $di->add('service', new Object());对象的实例存储在 di 容器中。当你创建 $di->add('service', function() return new Object(); );对象的实例是根据“请求”创建的,因此不同之处在于您可以在 di 中注册所有服务,并且注册的服务不会占用内存,因为尚未创建实例。在许多情况下,开发人员会向 di 注册服务,但在每个请求上都会创建服务,并且此过程会减慢执行速度。当您拥有匿名函数时,不会创建任何内容。【参考方案5】:

匿名函数的典型用途是回调函数。例如,您可以将它们用于来自排序算法的回调,例如函数uksort (http://lv.php.net/uksort) 或替换算法,例如preg_replace_callback (http://lv.php.net/manual/en/function.preg-replace-callback.php)。 自己没有在 PHP 中尝试过,所以这只是一个猜测。

【讨论】:

【参考方案6】:

这是在 PHP 中使用匿名函数的示例

$suppliers=['add1'=>'nodia','add2'=>'delhi', 'add3'=>'UP'];
 $getAddress = function($suppliers) $address=[];
 for($i=1;$i<5;$i++)
  if(array_key_exists('add'.$i, $suppliers))
    $address[]=$suppliers['add'.$i];
  
 return $address;;
 print_r($getAddress($suppliers));

在上面的示例中,我们编写了匿名函数来检查输入数组中是否存在键。如果它存在,那么它将把它放入输出数组。

【讨论】:

以上是关于为啥以及如何在 PHP 中使用匿名函数?的主要内容,如果未能解决你的问题,请参考以下文章

为啥需要在同一行调用匿名函数?

PHP回调函数及匿名函数概念与用法详解

PHP回调函数及匿名函数概念与用法详解

python之匿名函数以及在内置函数中的使用

php 如何对简单过滤器使用匿名函数

揭秘PHP匿名函数