измените метод/функцию во времени выполнения

Я смотрел на php отражательные методы, что я хочу сделать, вводят некоторый код после того, как метод открыт и перед любым возвращаемым значением, например, я хочу измениться:

function foo($bar)
{
    $foo = $bar ;
    return $foo ;
}

И введите некоторый код в него как:

function foo($bar)
{
    //some code here
    $foo = $bar ;
    //some code here
    return $foo ;
}

возможный?

8
задан mononym 28 May 2010 в 18:56
поделиться

5 ответов

Изучите анонимные функции . Если вы можете запустить PHP 5.3, это может быть больше похоже на то, что вы пытаетесь сделать.

2
ответ дан 5 December 2019 в 17:35
поделиться

Это невозможно, по крайней мере, не так, как вам нужно. Как следует из комментария, отражение предназначено для получения информации о классах / функциях, а не для их изменения.

Существует расширение PHP под названием Runkit, которое, как мне кажется, обеспечивает такую ​​функциональность - http://www.php.net/manual/en/book.runkit.php , однако это не будет установлен по умолчанию на подавляющем большинстве хостов.

Но может быть и другой способ сделать это. Возможно, если бы вы могли дать дополнительную информацию о том, что вы пытаетесь сделать, и почему вы не можете изменить рассматриваемую функцию, мы могли бы предоставить некоторые указатели. Например. это функция, которую вы хотите изменить, как базовую функцию PHP, или код в сторонней библиотеке, которую вы не хотите редактировать?

2
ответ дан 5 December 2019 в 17:35
поделиться

Просто идея:

function foo($bar, $preprocess, $postprocess){

    //IF CONDITION($preprocess)
    include('/mylogic/'.$preprocess.".php"); //do some preprocessing here?
    $foo = $bar ;
    //IF CONDITION($postprocess)
    include('/mylogic/'.$postprocess.".php"); //process $foo here?
    //FINALLY return
    return $foo;

}
0
ответ дан 5 December 2019 в 17:35
поделиться

Ну, один из способов - сделать все вызовы методов "виртуальными":

class Foo {
    protected $overrides = array();

    public function __call($func, $args) {
        $func = strtolower($func);
        if (isset($this->overrides[$func])) {
            // We have a override for this method, call it instead!
            array_unshift($args, $this); //Add the object to the argument list as the first
            return call_user_func_array($this->overrides[$func], $args);
        } elseif (is_callable(array($this, '_' . $func))) {
            // Call an "internal" version
            return call_user_func_array(array($this, '_' . $func), $args);
        } else {
            throw new BadMethodCallException('Method '.$func.' Does Not Exist');
        }
    }

    public function addOverride($name, $callback) { 
        $this->overrides[strtolower($name)] = $callback;
    }

    public function _doSomething($foo) {
        echo "Foo: ". $foo;
    }
}

$foo = new Foo();

$foo->doSomething('test'); // Foo: test

PHP 5.2:

$f = create_function('$obj, $str', 'echo "Bar: " . $obj->_doSomething($str) . " Baz";');

PHP 5.3:

$f = function($obj, $str) {
    echo "Bar: " . $obj->_doSomething($str) . " Baz";
}

All PHP:

$foo->addOverride('doSomething', $f);

$foo->doSomething('test'); // Bar: Foo: test Baz

В качестве первого метода в "переопределение" передается экземпляр объекта. Примечание: Этот "переопределенный" метод не будет иметь доступа ни к каким защищенным членам класса. Поэтому используйте геттеры (__get, __set). Он БУДЕТ иметь доступ к защищенным методам, поскольку фактический вызов происходит из __call()...

Примечание: Вам нужно будет изменить все ваши методы по умолчанию, чтобы они имели префикс '_', чтобы это работало... (или вы можете выбрать другой вариант префикса, или вы можете просто сделать их все защищенными)...

6
ответ дан 5 December 2019 в 17:35
поделиться

Может быть, я что-то упускаю, но вы действительно хотите «ввести» код, как вы говорите? Чего вы пытаетесь достичь? Если вы просто хотите выполнить один блок кода, когда происходит A, и другой, когда происходит B, тогда все, что вам нужно, это простая логика программирования, например, оператор if ().

Вы действительно пытаетесь изменить функцию во время выполнения? Или это просто логическая проблема?

Будьте более конкретны в том, что вам нужно делать.

-1
ответ дан 5 December 2019 в 17:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: