因此,我以一种不错的,最新的,面向对象的方式进行编程。我经常利用PHP实现的OOP的各个方面,但是我想知道何时需要使用闭包。是否有任何专家可以揭示何时实施闭包有用?
Answers:
PHP将在5.3中原生支持闭包。当您想要只用于某些特定目的的局部函数时,闭包是很好的选择。该闭包RFC给出一个很好的例子:
function replace_spaces ($text) {
$replacement = function ($matches) {
return str_replace ($matches[1], ' ', ' ').' ';
};
return preg_replace_callback ('/( +) /', $replacement, $text);
}
这样一来,您就可以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;
});
这里给出了一个很好的解释什么是php lambda和闭包
将来何时需要执行您现在确定的任务的功能。
例如,如果您读取一个配置文件,并且其中一个参数告诉您hash_method
for的算法是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)
}
我喜欢troelskn的帖子提供的上下文。当我想在PHP中执行Dan Udey的示例时,我使用OO策略模式。在我看来,这比引入一个新的全局函数要好得多,后者的行为是在运行时确定的。
http://en.wikipedia.org/wiki/Strategy_pattern
您还可以使用保存PHP中方法名称的变量来调用函数和方法,这很棒。因此,Dan的示例的另一种观点是这样的:
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
当然,如果您希望它随处可见,则可以将所有内容设为静态...
基本上,闭包是一种函数,您可以在一个上下文中编写定义但在另一个上下文中运行。Javascript帮助我理解了这些知识,因为JavaScript到处都在使用它们。
在PHP中,由于函数中“全局”(或“外部”)变量的范围和可访问性方面的差异,它们的效果不如JavaScript。但是,从PHP 5.4开始,闭包可以在对象内部运行时访问$ this对象,这使它们更有效。
这就是闭包的含义,足以理解上面的内容。
这意味着应该可以在某个地方编写函数定义,并在函数定义内使用$ this变量,然后将函数定义分配给变量(其他人已经给出了语法示例),然后将此变量传递给对象并在对象上下文中调用它,然后该函数可以通过$ this访问和操作该对象,就好像它只是它的另一个方法一样,而实际上它不是在该对象的类定义中定义的,而是在其他地方。
如果不是很清楚,那就不用担心,一旦开始使用它们就会变得很清楚。
基本上,闭包是内部函数tat可以访问外部变量,并且用作匿名函数(没有任何名称的函数)的回调函数。
<?php
$param='ironman';
function sayhello(){
$param='captain';
$func=function () use ($param){
$param='spiderman';
};
$func();
echo $param;
}
sayhello();
?>
//output captain
//and if we pass variable as a reference as(&$param) then output would be spider man;
$param='captain'
在func中sayhello()
是func的局部变量sayhello()
。$param='ironman'
以上sayhello()
是全局变量。如果您只想在脚本中创建一个$ param变量,则应调用:函数global $param;
内sayhello()
这是php中关闭的示例
// Author: HishamDalal@gamil.com
// Publish on: 2017-08-28
class users
{
private $users = null;
private $i = 5;
function __construct(){
// Get users from database
$this->users = array('a', 'b', 'c', 'd', 'e', 'f');
}
function displayUsers($callback){
for($n=0; $n<=$this->i; $n++){
echo $callback($this->users[$n], $n);
}
}
function showUsers($callback){
return $callback($this->users);
}
function getUserByID($id, $callback){
$user = isset($this->users[$id]) ? $this->users[$id] : null;
return $callback($user);
}
}
$u = new users();
$u->displayUsers(function($username, $userID){
echo "$userID -> $username<br>";
});
$u->showUsers(function($users){
foreach($users as $user){
echo strtoupper($user).' ';
}
});
$x = $u->getUserByID(2, function($user){
return "<h1>$user</h1>";
});
echo ($x);
输出:
0 -> a
1 -> b
2 -> c
3 -> d
4 -> e
5 -> f
A B C D E F
c