Можно ли заменить функции (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 

Solutions Collecting From Web of "Можно ли заменить функции (monkeypatch) PHP?"

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

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

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

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

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

Из 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, он не очень изящный, но он дает поведение, которое вы ищете.

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

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

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

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

Принятый ответ превосходный !!! Я просто добавлю, что вы можете поместить свои коды в скобки пространства имен, а затем по умолчанию выполняется 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 (…)