Pergunta

Eu quero ser capaz de envolver uma função PHP por outra função, mas deixando seu nome original / lista de parâmetro intacta.

Por exemplo:

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();

Output:

Calling A()
inside A()
Finished calling A()
Foi útil?

Solução

runkit poder Aparentemente ajuda você .

Além disso, você sempre pode fazer desta forma a OO. Coloque a diversão original em uma classe, e o decorador em uma classe estendida. Instantiate e ir.

Outras dicas

Aqui é o meu método de imitar decoradores de python em php.

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');

Output:

Before testing
testing 1234
After testing

Com esta aplicação, você também pode fazer algo assim com uma função anônima:

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

Output:

Before testing
Hello!
After testing

E por último você mesmo pode fazer algo como isso, se você é tão inclinado.

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

Output:

Hello World!

Com esta construção acima, você pode passar variáveis ??para a função interior ou invólucro, se for necessário. Aqui é que a implementação com uma função interna anônima:

$test_val = 'I am accessible!';

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

Ele irá funcionar exatamente o mesmo sem uma função anônima:

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

$test_var = 'Hello again!';

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

Por último, se você precisar modificar o interior variável ou o invólucro ou a wrappie, você só precisa passar a variável por referência.

Sem referência:

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

Output:

testing this

Com referência:

$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));

Output:

I changed!

Isso é tudo que tenho por agora, é uma bastante útil em muitos casos, e você pode até envolvê-los várias vezes, se você quiser.

talvez você está procurando call_user_func_array :

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

desde o PHP 5.3 você mesmo poderia dizer:

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

depois de ter editado a sua pergunta eu diria, não, isso não é possível, mas existem algumas maneiras, consulte esta pergunta: como implementar um decorador em PHP?

Você não pode fazer isso com funções em PHP. Em outras linguagens dinâmicas, como Perl e Ruby, você pode redefinir anteriormente funções definidas, mas PHP lança um erro fatal ao tentar fazê-lo.

No 5.3, você pode criar um função anônima e armazenar -lo em uma variável:

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

Como alternativa, você pode usar o padrão tradicional decorador e / ou uma fábrica e trabalhar com aulas em seu lugar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top