所以我正在以一种不错的,最新的,面向对象的方式编程.我经常使用PHP实现的OOP的各个方面,但我想知道何时需要使用闭包.那里的任何专家都可以阐明何时实现闭包有用?
dir*_*ide 77
PHP将在5.3中原生支持闭包.当你想要一个仅用于某些小的特定目的的本地函数时,闭包是很好的.闭包的RFC给出了一个很好的例子:
function replace_spaces ($text) {
$replacement = function ($matches) {
return str_replace ($matches[1], ' ', ' ').' ';
};
return preg_replace_callback ('/( +) /', $replacement, $text);
}
Run Code Online (Sandbox Code Playgroud)
这允许你在replacement
本地内部定义函数replace_spaces()
,因此它不是:
1)使全局命名空间混乱
2)让人们三年下线,想知道为什么全局定义的函数只用在另一个函数中
它保持井井有条.注意函数本身没有名称,它只是被定义并指定为引用$replacement
.
但请记住,你必须等待PHP 5.3 :)
您还可以使用关键字将其范围外的变量访问到闭包中use
.考虑这个例子.
// Set a multiplier
$multiplier = 3;
// Create a list of numbers
$numbers = array(1,2,3,4);
// Use array_walk to iterate
// through the list and multiply
array_walk($numbers, function($number) use($multiplier){
echo $number * $multiplier;
});
Run Code Online (Sandbox Code Playgroud)
这里给出了一个很好的解释什么是php lambdas和closures
Dan*_*dey 16
如果您将来需要一个执行您现在已决定的任务的功能.
例如,如果您读取配置文件并且其中一个参数告诉hash_method
您算法multiply
而不是square
,则可以创建一个闭包,可以在需要散列内容的地方使用.
封闭可以在(例如)中创建config_parser()
; 它创建了一个do_hash_method()
使用变量本地的函数config_parser()
(来自配置文件).无论什么时候do_hash_method()
被调用,它都可以访问本地范围内的变量,config_parser()
即使它没有在该范围内被调用.
一个有希望的好假设的例子:
function config_parser()
{
// Do some code here
// $hash_method is in config_parser() local scope
$hash_method = 'multiply';
if ($hashing_enabled)
{
function do_hash_method($var)
{
// $hash_method is from the parent's local scope
if ($hash_method == 'multiply')
return $var * $var;
else
return $var ^ $var;
}
}
}
function hashme($val)
{
// do_hash_method still knows about $hash_method
// even though it's not in the local scope anymore
$val = do_hash_method($val)
}
Run Code Online (Sandbox Code Playgroud)
tro*_*skn 15
除了技术细节之外,闭包是编程风格(称为功能导向编程)的基本先决条件.闭包大致用于在面向对象编程中使用对象时的相同内容; 它将数据(变量)与某些代码(函数)绑定在一起,然后您可以将其传递到其他位置.因此,它们会影响您编写程序的方式,或者 - 如果您不改变编写程序的方式 - 它们根本没有任何影响.
在PHP的上下文中,它们有点奇怪,因为PHP已经在基于类,面向对象的范例以及较旧的程序范例上沉重.通常,具有闭包的语言具有完整的词法范围.为了保持向后兼容性,PHP不会得到这个,所以这意味着闭包在这里会比在其他语言中有所不同.我想我们还没有看到它们将如何被使用.
gro*_*gel 10
我喜欢troelskn的帖子提供的上下文.当我想在Dan中使用Dan Udey的例子时,我会使用OO策略模式.在我看来,这比引入一个新的全局函数要好得多,该函数的行为是在运行时确定的.
http://en.wikipedia.org/wiki/Strategy_pattern
您还可以使用在PHP中保存方法名称的变量来调用函数和方法,这很棒.所以对丹的例子的另一种看法是这样的:
class ConfigurableEncoder{
private $algorithm = 'multiply'; //default is multiply
public function encode($x){
return call_user_func(array($this,$this->algorithm),$x);
}
public function multiply($x){
return $x * 5;
}
public function add($x){
return $x + 5;
}
public function setAlgorithm($algName){
switch(strtolower($algName)){
case 'add':
$this->algorithm = 'add';
break;
case 'multiply': //fall through
default: //default is multiply
$this->algorithm = 'multiply';
break;
}
}
}
$raw = 5;
$encoder = new ConfigurableEncoder(); // set to multiply
echo "raw: $raw\n"; // 5
echo "multiply: " . $encoder->encode($raw) . "\n"; // 25
$encoder->setAlgorithm('add');
echo "add: " . $encoder->encode($raw) . "\n"; // 10
Run Code Online (Sandbox Code Playgroud)
当然,如果你想让它随处可用,你可以让一切都变得静止......