PHP wird Schließungen in 5.3 nativ unterstützen. Ein Verschluss ist gut, wenn Sie eine lokale Funktion wünschen, die nur für einen kleinen, spezifischen Zweck verwendet wird. Der RFC für Verschlüsse gibt ein gutes Beispiel:
function replace_spaces ($text) {
$replacement = function ($matches) {
return str_replace ($matches[1], ' ', ' ').' ';
};
return preg_replace_callback ('/( +) /', $replacement, $text);
}
Auf diese Weise können Sie die replacement
Funktion lokal innerhalb definieren replace_spaces()
, sodass dies nicht der Fall ist :
1) Überladen des globalen Namespace
2 ) Lassen Sie die Leute drei Jahre später fragen, warum eine global definierte Funktion nur innerhalb einer anderen Funktion verwendet wird
Es hält die Dinge organisiert. Beachten Sie, dass die Funktion selbst keinen Namen hat, sondern lediglich als Referenz definiert und zugewiesen wird $replacement
.
Aber denken Sie daran, Sie müssen auf PHP 5.3 warten :)
Sie können auch mit dem Schlüsselwort auf Variablen außerhalb des Gültigkeitsbereichs zugreifen use
. Betrachten Sie dieses Beispiel.
$multiplier = 3;
$numbers = array(1,2,3,4);
array_walk($numbers, function($number) use($multiplier){
echo $number * $multiplier;
});
Eine ausgezeichnete Erklärung wird hier gegeben. Was sind PHP-Lambdas und Verschlüsse?
Wenn Sie in Zukunft eine Funktion benötigen, die eine Aufgabe ausführt, für die Sie sich jetzt entschieden haben.
Wenn Sie beispielsweise eine Konfigurationsdatei lesen und einer der Parameter angibt, dass dies
hash_method
für Ihren Algorithmusmultiply
nicht dersquare
Fall ist , können Sie einen Abschluss erstellen, der überall dort verwendet wird, wo Sie etwas hashen müssen.Der Verschluss kann in (zum Beispiel) erstellt werden
config_parser()
; Es wird eine Funktion erstellt, die unterdo_hash_method()
Verwendung von Variablen local toconfig_parser()
(aus der Konfigurationsdatei) aufgerufen wird . Immer wenndo_hash_method()
es aufgerufen wird, hat es Zugriff auf Variablen im lokalen Bereich vonconfig_parser()
, obwohl es in diesem Bereich nicht aufgerufen wird.Ein hoffentlich gutes hypothetisches Beispiel:
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) }
quelle
Neben den technischen Details sind Verschlüsse eine Grundvoraussetzung für einen Programmierstil, der als funktionsorientierte Programmierung bezeichnet wird. Ein Abschluss wird ungefähr für das verwendet, wofür Sie ein Objekt in der objektorientierten Programmierung verwenden. Es bindet Daten (Variablen) mit einem Code (einer Funktion) zusammen, den Sie dann an eine andere Stelle weitergeben können. Als solche wirken sie sich auf die Art und Weise aus, wie Sie Programme schreiben, oder - wenn Sie die Art und Weise, wie Sie Ihre Programme schreiben, nicht ändern - haben sie überhaupt keine Auswirkungen.
Im Kontext von PHP sind sie etwas seltsam, da PHP bereits das klassenbasierte, objektorientierte Paradigma sowie das ältere prozedurale Paradigma stark beansprucht. Normalerweise haben Sprachen mit Verschlüssen den vollen lexikalischen Geltungsbereich. Um die Abwärtskompatibilität aufrechtzuerhalten, wird PHP dies nicht erhalten, was bedeutet, dass die Schließungen hier etwas anders sein werden als in anderen Sprachen. Ich denke, wir müssen noch genau sehen, wie sie verwendet werden.
quelle
Ich mag den Kontext, den Troelskns Post bietet. Wenn ich so etwas wie Dan Udeys Beispiel in PHP machen möchte, verwende ich das OO-Strategiemuster. Meiner Meinung nach ist dies viel besser als die Einführung einer neuen globalen Funktion, deren Verhalten zur Laufzeit bestimmt wird.
http://en.wikipedia.org/wiki/Strategy_pattern
Sie können Funktionen und Methoden auch mit einer Variablen aufrufen, die den Methodennamen in PHP enthält. Eine andere Einstellung zu Dans Beispiel wäre also ungefähr so:
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
Wenn Sie möchten, dass es überall verfügbar ist, können Sie natürlich einfach alles statisch machen ...
quelle
Ein Abschluss ist im Grunde eine Funktion, für die Sie die Definition in einem Kontext schreiben, aber in einem anderen Kontext ausführen. Javascript hat mir sehr geholfen, diese zu verstehen, da sie überall in JavaScript verwendet werden.
In PHP sind sie weniger effektiv als in JavaScript, da sich der Umfang und die Zugänglichkeit von "globalen" (oder "externen") Variablen innerhalb von Funktionen unterscheiden. Ab PHP 5.4 können Closures jedoch auf das $ this-Objekt zugreifen, wenn sie in einem Objekt ausgeführt werden. Dies macht sie wesentlich effektiver.
Darum geht es bei Schließungen, und es sollte ausreichen, um zu verstehen, was oben geschrieben steht.
Dies bedeutet, dass es möglich sein sollte, irgendwo eine Funktionsdefinition zu schreiben und die Variable $ this in der Funktionsdefinition zu verwenden, dann die Funktionsdefinition einer Variablen zuzuweisen (andere haben Beispiele für die Syntax angegeben) und diese Variable dann an ein Objekt zu übergeben Wenn Sie es im Objektkontext aufrufen, kann die Funktion dann über $ this auf das Objekt zugreifen und es bearbeiten, als wäre es nur eine andere Methode, obwohl es nicht in der Klassendefinition dieses Objekts definiert ist, sondern an einer anderen Stelle.
Wenn es nicht sehr klar ist, machen Sie sich keine Sorgen, es wird klar, sobald Sie sie verwenden.
quelle
Grundsätzlich sind Closure die inneren Funktionen, die Zugriff auf die äußeren Variablen haben und als Rückruffunktion für eine anonyme Funktion (Funktionen, die keinen Namen haben) verwendet werden.
<?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;
quelle
$param='captain'
in funcsayhello()
ist eine lokale Variable zu funcsayhello()
.$param='ironman'
obensayhello()
ist globale Variable. Wenn Sie nur eine $ param Variable in Ihrem Skript machen möchten , sollten Sie anrufen:global $param;
innerhalbsayhello()
funcHier sind Beispiele für Verschlüsse in 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);
Ausgabe:
0 -> a 1 -> b 2 -> c 3 -> d 4 -> e 5 -> f A B C D E F c
quelle