Closures in PHP … was genau sind sie und wann müssten Sie sie verwenden?

Lesezeit: 8 Minuten

Benutzer-Avatar
rg88

Also programmiere ich auf eine nette, aktuelle, objektorientierte Art und Weise. Ich verwende regelmäßig die verschiedenen Aspekte von OOP, die PHP implementiert, aber ich frage mich, wann ich Closures verwenden muss. Gibt es Experten da draußen, die Aufschluss darüber geben können, wann es sinnvoll wäre, Schließungen einzuführen?

Benutzer-Avatar
Schmutzseite

PHP wird Closures in 5.3 nativ unterstützen. Eine Closure ist gut, wenn Sie eine lokale Funktion wünschen, die nur für einen kleinen, spezifischen Zweck verwendet wird. Das RFC für Schließungen gibt ein gutes Beispiel:

function replace_spaces ($text) {
    $replacement = function ($matches) {
        return str_replace ($matches[1], ' ', ' ').' ';
    };
    return preg_replace_callback ('/( +) /', $replacement, $text);
}

Damit definieren Sie die replacement Funktion lokal im Inneren replace_spaces()damit es nicht ist:
1) den globalen Namensraum unübersichtlich zu machen
2) Das bringt die Leute drei Jahre später dazu, sich zu fragen, warum es eine global definierte Funktion gibt, die nur innerhalb einer anderen Funktion verwendet wird

Es hält die Dinge organisiert. Beachten Sie, dass die Funktion selbst keinen Namen hat, sie wird einfach als Referenz definiert und zugewiesen $replacement.

Aber denken Sie daran, Sie müssen auf PHP 5.3 warten 🙂

  • Das ist eine tolle Erklärung. +1

    – David J Eddy

    21. März 2013 um 13:22 Uhr

  • Ich genoss die Erklärung von warum Sie würden Verschlüsse verwenden. Die meisten Menschen begreifen das nicht wirklich. +1

    – Carrie Kendall

    22. Mai 2013 um 15:57 Uhr


  • Dies ist eine Erklärung anonymer Funktionen, keine Erklärung von Closures. Anonyme Funktionen sind, wie Sie sagen, genau wie benannte Funktionen, außer dass sie nicht global sind. Closures hingegen sind Funktionen, die freie Variablen mit lexikalischem Gültigkeitsbereich enthalten (mit »use« deklariert); dh. Sie können Werte aus dem Geltungsbereich, in dem sie deklariert sind, kopieren und darauf verweisen, selbst nachdem alles andere bereinigt wurde.

    – Warbo

    28. Juni 2014 um 2:37 Uhr

  • @Warbo Das ist wahr; Damals habe ich den Unterschied zwischen einer anonymen Funktion und einer Schließung nicht wirklich verstanden. Closures machen wirklich nur Sinn, wenn man anonyme Funktionen grok hat, aber bis heute Ich finde immer noch “Erklärungen” darüber, was eine Schließung ist (wie meine vor 7 Jahren 😉 ), die den Aspekt des Umfangs nicht erklären.

    – Schmutzseite

    3. Oktober 2015 um 4:16 Uhr

  • Deshalb habe ich gesagt, sehen Sie sich JavaScript an, wo Closures stark verwendet werden – aber denken Sie daran, dass die Regeln für den variablen Bereich in PHP anders sind.

    – Rolf

    27. September 2017 um 17:37 Uhr


Wenn Sie in Zukunft eine Funktion benötigen, die eine Aufgabe erfüllt, für die Sie sich jetzt entschieden haben.

Wenn Sie beispielsweise eine Konfigurationsdatei lesen und einer der Parameter Ihnen mitteilt, dass die hash_method für Ihren Algorithmus ist multiply statt squarekönnen Sie einen Abschluss erstellen, der überall dort verwendet wird, wo Sie etwas hashen müssen.

Der Abschluss kann erstellt werden in (zum Beispiel) config_parser(); Es erstellt eine Funktion namens do_hash_method() Verwenden von lokalen Variablen config_parser() (aus der Konfigurationsdatei). Wann auch immer do_hash_method() aufgerufen wird, hat es Zugriff auf Variablen im lokalen Geltungsbereich vonconfig_parser() obwohl es nicht in diesem Bereich 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)
}

  • Ich kann dieses Beispiel nicht einfach kopieren, einfügen und ausführen. Bevorzuge ein Beispiel, das ich einfach ausführen kann.

    – Kim Stacks

    21. März 2013 um 8:59 Uhr

  • Diese Antwort ist schlecht. Dies ist eine bedeutungslose Aussage: “Wenn Sie in Zukunft eine Funktion benötigen, die eine Aufgabe erfüllt, für die Sie sich jetzt entschieden haben.”

    – Entspannen in Zypern

    11. September 2014 um 13:16 Uhr

Abgesehen von den technischen Details sind Closures eine grundlegende Voraussetzung für einen Programmierstil, der als funktionsorientierte Programmierung bezeichnet wird. Eine Closure wird ungefähr für dasselbe verwendet wie ein Objekt in der objektorientierten Programmierung. Es bindet Daten (Variablen) mit etwas Code (einer Funktion) zusammen, die 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 keinen Einfluss.

Im Kontext von PHP sind sie etwas seltsam, da PHP bereits stark auf dem klassenbasierten, objektorientierten Paradigma sowie dem älteren prozeduralen Paradigma basiert. Normalerweise haben Sprachen mit Schließungen den vollen lexikalischen Umfang. Um die Abwärtskompatibilität aufrechtzuerhalten, wird PHP dies nicht erhalten, was bedeutet, dass die Closures hier etwas anders sein werden als in anderen Sprachen. Ich denke, wir müssen noch genau sehen, wie sie verwendet werden.

Ich mag den Kontext, der durch troelskns Beitrag bereitgestellt wird. Wenn ich etwas wie das Beispiel von Dan Udey in PHP machen möchte, verwende ich das OO-Strategiemuster. Meiner Meinung nach ist dies viel besser, als eine neue globale Funktion einzuführen, deren Verhalten zur Laufzeit bestimmt wird.

http://en.wikipedia.org/wiki/Strategy_pattern

Sie können auch Funktionen und Methoden aufrufen, indem Sie eine Variable verwenden, die den Methodennamen in PHP enthält, was großartig ist. Eine andere Variante von Dans Beispiel wäre also etwa 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 alles statisch machen …

Eine Closure 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 aufgrund von Unterschieden im Umfang und der Zugänglichkeit von „globalen“ (oder „externen“) Variablen innerhalb von Funktionen weniger effektiv als in JavaScript. Ab PHP 5.4 können Closures jedoch auf das $this-Objekt zugreifen, wenn sie innerhalb eines Objekts ausgeführt werden, was sie viel effektiver macht.

Darum geht es bei Closures, und es sollte ausreichen, das oben Geschriebene zu verstehen.

Das bedeutet, dass es möglich sein sollte, irgendwo eine Funktionsdefinition zu schreiben und die Variable $this innerhalb 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 und es im Objektkontext aufrufen, kann die Funktion dann über $this auf das Objekt zugreifen und es manipulieren, als wäre es nur eine seiner Methoden, obwohl es tatsächlich nicht in der Klassendefinition dieses Objekts definiert ist, sondern woanders.

Wenn es nicht sehr klar ist, dann machen Sie sich keine Sorgen, es wird klar, sobald Sie anfangen, sie zu verwenden.

  • Ehrlich gesagt ist mir das überhaupt nicht klar, auch für mich, den Autor. Grundsätzlich sage ich: Um zu erfahren, was Closures sind, überprüfen Sie sie in JavaScript, aber denken Sie daran, dass der Gültigkeitsbereich von Variablen zwischen JavaScript und PHP unterschiedlich ist.

    – Rolf

    27. September 2017 um 17:34 Uhr

Hier sind Beispiele für Closures 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

  • Ehrlich gesagt ist mir das überhaupt nicht klar, auch für mich, den Autor. Grundsätzlich sage ich: Um zu erfahren, was Closures sind, überprüfen Sie sie in JavaScript, aber denken Sie daran, dass der Gültigkeitsbereich von Variablen zwischen JavaScript und PHP unterschiedlich ist.

    – Rolf

    27. September 2017 um 17:34 Uhr

Benutzer-Avatar
Rauer Gehlot

Grundsätzlich sind Closure die inneren Funktionen, die Zugriff auf die äußeren Variablen haben und als Callback-Funktion für anonyme Funktionen (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;

  • $param='captain' in Funktion sayhello() ist lokale Variable zu func sayhello(). $param='ironman' Oben sayhello() ist eine globale Variable. Wenn Sie nur eine $param-Variable in Ihrem Skript erstellen möchten, sollten Sie Folgendes aufrufen: global $param; innerhalb sayhello() Funk

    – Wlakow

    23. April 2019 um 8:42 Uhr

1353050cookie-checkClosures in PHP … was genau sind sie und wann müssten Sie sie verwenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy