Подтвердить что ты не робот

Можно ли заменить функции (monkeypatch) PHP?

Вы можете сделать это в Python, но возможно ли это в PHP?

>>> def a(): print 1
... 
>>> def a(): print 2
... 
>>> a()
2

например:.

<? function var_dump() {} ?>
Fatal error: Cannot redeclare var_dump() in /tmp/- on line 1
4b9b3361

Ответ 1

Это немного поздно, но я просто хочу отметить, что с PHP 5.3 можно фактически переопределить внутренние функции без использования расширения PHP.

Фокус в том, что вы можете переопределить внутреннюю функцию PHP внутри пространства имен. Он основан на способе определения имени PHP для функций:

Внутри пространства имен (например, A\B) вызовы для неквалифицированных функций разрешаются во время выполнения. Вот как разрешен вызов функции foo():

  • Он ищет функцию из текущего пространства имен: A\B\foo().
  • Он пытается найти и вызвать глобальную функцию foo()

Ответ 2

Нет, это невозможно сделать, как вы могли ожидать.

Из manual:

PHP не поддерживает перегрузку функций, равно как и невозможно определить или переопределить ранее объявленные функции.

ОДНАКО, вы можете использовать runkit_function_redefine и его кузены, но это определенно не очень элегантно...

Вы также можете использовать create_function, чтобы сделать что-то вроде этого:

<?php
$func = create_function('$a,$b','return $a + $b;');
echo $func(3,5); // 8
$func = create_function('$a,$b','return $a * $b;');
echo $func(3,5); // 15
?>

Как и в runkit, он не очень изящный, но дает поведение, которое вы ищете.

Ответ 3

Я понимаю, что этот вопрос немного устарел, но Patchwork - недавно выпущенный проект PHP 5.3 который поддерживает переопределение пользовательских функций. Хотя, как отмечает автор, вам нужно будет прибегнуть к runkit или php-test-helpers в функции ядра/библиотеки обезьяны-паттерна.

Ответ 5

Как упоминал jmikola, Patchwork является хорошим решением, если вы хотите добавить код в функцию.

Вот статья о том, как это работает: http://phpmyweb.net/2012/04/26/write-an-awesome-plugin-system-in-php/

Он поставляется с некоторым примером кода. Я думаю, что версия phpmyweb использует немного лучший код, потому что он не использует код eval() 'd, в отличие от лоскутной игры. Вы можете кэшировать коды операций при использовании eval().

Ответ 6

Принятый ответ превосходный!!! Я просто добавлю, что вы можете поместить свои коды в скобки пространства имен, а затем по умолчанию выполняется GLOBAL-SPACE.

несколько других способов:

1) rename_function ($ old_name, $new_name)

2) override_function ($ old_name, $parameters, $new_func)

и редко используется:

3) runkit_function_rename (...)

4) runkit_function_redefine (...)