Frage

Ich möchte in der Lage, eine PHP-Funktion durch eine andere Funktion zu wickeln, aber seinen ursprünglichen Namen / Parameterliste intakt bleibt.

Zum Beispiel:

function A() {
    print "inside A()\n";
}

function Wrap_A() {
    print "Calling A()\n";
    A();
    print "Finished calling A()\n";
}

// <--- Do some magic here (effectively "A = Wrap_A")

A();

Ausgabe:

Calling A()
inside A()
Finished calling A()
War es hilfreich?

Lösung

runkit könnte helfen Sie .

Sie können aber auch immer tun dies die OO Weg. Die Original-Spaß in einer Klasse, und der Dekorateur in einer erweiterten Klasse. Instanziieren und gehen.

Andere Tipps

Hier ist meine Methode der Dekorateure aus Python in PHP nachgeahmt wird.

function call_decorator ($decorator, $function, $args, $kwargs) {

    // Call the decorator and pass the function to it
    $decorator($function, $args, $kwargs);
}

function testing ($args, $kwargs) {
    echo PHP_EOL . 'test 1234' . PHP_EOL;
}

function wrap_testing ($func, $args, $kwargs) {

    // Before call on passed function
    echo 'Before testing';

    // Call the passed function
    $func($args, $kwargs);

    // After call on passed function
    echo 'After testing';
}

// Run test
call_decorator('wrap_testing', 'testing');

Ausgabe:

Before testing
testing 1234
After testing

Mit dieser Implementierung können Sie auch mit einer anonymen Funktion so etwas tun:

// Run new test
call_decorator('wrap_testing', function($args, $kwargs) {
    echo PHP_EOL . 'Hello!' . PHP_EOL;
});

Ausgabe:

Before testing
Hello!
After testing

Und schließlich kann man auch etwas tun, wenn Sie so geneigt sind.

// Run test
call_decorator(function ($func, $args, $kwargs) {
    echo 'Hello ';
    $func($args, $kwargs);
}, function($args, $kwargs) {
    echo 'World!';
});

Ausgabe:

Hello World!

Mit dieser Konstruktion oben können Sie Variablen auf die innere Funktion oder Wrapper passieren, wenn es sein muss. Hier ist, dass die Umsetzung mit einer anonymen inneren Funktion:

$test_val = 'I am accessible!';

call_decorator('wrap_testing', function($args, $kwargs){
    echo $args[0];
}, array($test_val));

Es funktioniert genau das gleiche, ohne eine anonyme Funktion:

function test ($args, $kwargs) {
    echo $kwargs['test'];
}

$test_var = 'Hello again!';

call_decorator('wrap_testing', 'test', array(), array('test' => $test_var));

Schließlich, wenn Sie die Variable innerhalb entweder der Umhüllung oder der wrappie ändern müssen, müssen Sie nur die Variable durch Verweis übergeben.

Ohne Referenz:

$test_var = 'testing this';
call_decorator(function($func, $args, $kwargs) {
    $func($args, $kwargs);
}, function($args, $kwargs) {
    $args[0] = 'I changed!';
}, array($test_var));

Ausgabe:

testing this

Mit Bezug:

$test_var = 'testing this';
call_decorator(function($func, $args, $kwargs) {
    $func($args, $kwargs);
}, function($args, $kwargs) {
    $args[0] = 'I changed!';

// Reference the variable here
}, array(&$test_var));

Ausgabe:

I changed!

Das ist alles, was ich jetzt habe, ist es ein ziemlich in vielen Fällen nützlich, und man kann sie mehrmals selbst wickeln, wenn Sie wollen.

vielleicht Sie suchen call_user_func_array :

function wrapA() {
  $args = func_get_args();
  return call_user_func_array('A', $args);
}

Seit PHP 5.3 Man könnte sogar sagen:

return call_user_func_array('A', func_get_args());

, nachdem Sie Ihre Frage bearbeitet haben, ich würde sagen, nein, das ist nicht möglich, aber es gibt einige Möglichkeiten, sieht diese Frage: wie ein Dekorateur in PHP implementieren?

Sie können dies nicht mit Funktionen in PHP. In anderen dynamischen Sprachen wie Perl und Ruby, können Sie vorher definierten Funktionen neu zu definieren, aber PHP wirft einen fatalen Fehler, wenn Sie dies versuchen.

5.3 können Sie eine anonyme Funktion und Speicher erstellen es in einer variablen:

<?php
    $my_function = function($args, ...) { ... };
    $copy_of_my_function = $my_function;
    $my_function = function($arg, ...) { /* Do something with the copy */ };
?>

Alternativ können Sie das traditionelle Decorator-Muster und / oder eine Fabrik und die Arbeit mit Klassen statt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top