所以,我正在編程一個不錯的,最新的,面向對象的時尚。我經常使用PHP實現的OOP的各個方面,但我想知道什麼時候需要使用閉包。那裏的任何專家都可以闡明什麼時候實施封鎖有用?PHP中的閉包...究竟是什麼,他們什麼時候需要使用它們?
回答
PHP將會原生支持在封5.3。當你想要一個本地函數只用於一些小的,特定的目的時,閉包是很好的。該RFC for closures給出一個很好的例子:
function replace_spaces ($text) {
$replacement = function ($matches) {
return str_replace ($matches[1], ' ', ' ').' ';
};
return preg_replace_callback ('/(+) /', $replacement, $text);
}
這可以讓你在本地定義replacement
函數內部replace_spaces()
,所以它不是:
1)弄亂全局命名空間
2)製作人3多年來一直困惑爲什麼有一個全球定義的功能只用於一個其他功能
它使事情有條不紊。注意函數本身沒有名字,它只是被定義和分配爲$replacement
的引用。
但是要記住,你必須等待PHP 5.3 :)
當您將來需要一個執行您現在已經決定的任務的功能時。例如,如果您閱讀了一個配置文件,並且其中一個參數告訴您算法的hash_method
是multiply
而不是square
,那麼您可以創建一個閉包,在需要散列的地方使用該閉包。
閉包可以在(例如)config_parser()
;它使用config_parser()
(從配置文件中)的本地變量創建一個名爲do_hash_method()
的函數。每當調用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)
}
除此之外,閉包是一個基本的前提條件被稱爲面向功能的編程的編程風格。閉包大致用於與在面向對象編程中使用對象相同的東西;它將數據(變量)與一些代碼(一個函數)綁定在一起,然後可以傳遞到其他地方。因此,它們會影響您編寫程序的方式,或者 - 如果您不改變編寫程序的方式 - 它們根本沒有任何影響。
在PHP的上下文中,它們有點奇怪,因爲PHP已經在基於類的面向對象的範例以及早期的過程化範例中佔據重要位置。通常,具有閉包的語言具有完整的詞法範圍。爲了保持向後兼容性,PHP不會得到這個,所以這意味着閉包在這裏會有點不同於其他語言。我想我們還沒有看到他們將如何使用。
我喜歡troelskn的帖子提供的上下文。當我想在PHP中使用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
當然
,如果你希望它是隨處可見,你可以只讓一切都靜...
閉包基本上是爲你寫的定義在一個範圍內,但在另一個環境中運行的功能。 Javascript幫助我理解了這些,因爲它們在JavaScript中被廣泛使用。
在PHP中,由於函數內部的「全局」(或「外部」)變量的範圍和可訪問性不同,所以它們的效率低於JavaScript。然而,從PHP 5.4開始,閉包在對象中運行時可以訪問$ this對象,這使得它們更有效。
這是關閉的關鍵,它應該足以理解上面寫的內容。
這意味着應該可以在某處編寫函數定義,並在函數定義中使用$ this變量,然後將函數定義分配給變量(其他人已經給出了語法的示例),然後傳遞此變量到一個對象並在對象上下文中調用它,然後該函數可以通過$ this訪問和操作對象,就好像它只是它的另一個方法,事實上它並沒有在該對象的類定義中定義,但是別的地方。
如果不是很清楚,那麼不要擔心,一旦開始使用它們就會變得清晰。
這裏是在PHP閉包的例子
// Author: [email protected]
// 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
- 1. Maven快照究竟是什麼,爲什麼我們需要它?
- 2. 什麼是http標題,什麼時候需要指定它們
- 3. Ruby中的CSV對象。他們究竟是什麼?
- 4. divs什麼時候填滿水平空間,他們什麼時候不需要?
- 5. 什麼是C++中的「set」?他們什麼時候有用?
- 6. 裝配需要什麼?爲什麼我們使用它們?
- 7. 什麼是BigInteger,我們什麼時候可以使用它?
- 8. 什麼是仿函數,爲什麼我們需要它們?
- 9. 什麼是EJB回調,爲什麼我們需要它們?
- 10. 關於SQL目錄的問題 - 它們究竟是什麼?
- 11. 什麼是序列(數據庫)?我們什麼時候需要它?
- 12. 我們什麼時候需要使用posix_memalign而不是malloc?
- 13. 究竟是什麼ObjectFactory是什麼,它用於什麼?
- 14. CourseCompletions是什麼?它們是什麼時候創建的?
- 15. Ruby可枚舉類 - 它們究竟是什麼?
- 16. GridViewRow構造函數參數,它們究竟是什麼?
- 17. Android中的上下文究竟是什麼?爲什麼它需要?
- 18. 什麼是JavaScript對象,它們什麼時候有用?
- 19. 我們什麼時候需要關閉MongoConnection
- 20. 什麼是R中的因子,爲什麼我們需要它
- 21. 我們什麼時候需要在codeIgniter中使用base_url()函數?
- 22. 模型中有什麼?爲什麼我們需要使用它
- 23. 當我們使用ajax時究竟發生了什麼
- 24. 什麼是SWC,什麼時候/我們在Flash中使用SWC
- 25. PHP中的PATH_INFO究竟是什麼?
- 26. PHP中的$ _REQUEST [$ K]究竟是什麼?
- 27. 什麼是分配器,何時需要它們的使用?
- 28. 什麼是Scala中的清單,什麼時候需要它?
- 29. IfModule:我們什麼時候需要指定它?
- 30. 線程名稱 - 你什麼時候需要了解它們?
我不能簡單地複製粘貼此示例並運行它。首選一個我可以簡單運行的例子。對於不起作用的代碼,爲 – 2013-03-21 08:59:22
-1。 – deceze 2013-05-22 16:41:21
這個答案很糟糕。這是一個毫無意義的陳述:「當你將來需要一個執行你現在決定的任務的功能時。」 – Puzbie 2014-09-11 13:16:29