質問

PHP関数を別の関数でラップできるようにしたいのですが、元の名前/パラメーターリストはそのままにしておきます。

たとえば:

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

出力:

Calling A()
inside A()
Finished calling A()
役に立ちましたか?

解決

どうやら runkit ヘルプ

また、これは常にオブジェクト指向の方法で行うことができます。元の楽しみをクラスに入れ、デコレータを拡張クラスに入れます。インスタンス化して実行します。

他のヒント

これは、PHPでPythonのデコレータを模倣する私の方法です。

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

出力:

Before testing
testing 1234
After testing

この実装では、匿名関数を使用して次のようなこともできます。

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

出力:

Before testing
Hello!
After testing

そして最後に、あなたがそんなに傾いているなら、このようなことさえすることができます。

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

出力:

Hello World!

上記のこの構成により、必要に応じて変数を内部関数またはラッパーに渡すことができます。匿名の内部関数を使用した実装は次のとおりです。

$test_val = 'I am accessible!';

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

匿名関数がなくてもまったく同じように動作します:

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

$test_var = 'Hello again!';

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

最後に、ラッパーまたはラップパイ内の変数を変更する必要がある場合は、参照によって変数を渡すだけです。

参照なし:

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

出力:

testing this

参照あり:

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

出力:

I changed!

これで今のところすべてです。多くの場合非常に便利です。必要に応じて複数回ラップすることもできます。

call_user_func_array を探している可能性があります:

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

PHP 5.3以降では、次のように言うこともできます。

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

質問を編集した後、いいえ、これは不可能ですが、いくつかの方法があります。この質問を参照してください: PHPでデコレータを実装する方法は?

PHPの関数を使用してこれを行うことはできません。 PerlやRubyなどの他の動的言語では、以前に定義した関数を再定義できますが、PHPで再定義しようとすると致命的なエラーがスローされます。

5.3では、匿名関数を作成して保存できます変数でそれ:

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

別の方法として、従来のデコレータパターンやファクトリを使用して、代わりにクラスを操作することもできます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top