파이썬에서는이 작업을 수행 할 수 있지만 PHP에서는 가능합니까?(monkeypatch) 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
파이썬에서는이 작업을 수행 할 수 있지만 PHP에서는 가능합니까?(monkeypatch) 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
이것은 비트입니다.하지만 PHP 5.3부터는 PHP 확장을 사용하지 않고 내부 함수를 재정의 할 수 있습니다.
트릭은 네임 스페이스 내에 내부 PHP 함수를 재정의 할 수 있다는 것입니다. PHP가 함수의 이름 해석을하는 방식을 기반으로합니다 :
내부 네임 스페이스 (예 : A \ B)는 정규화되지 않은 함수를 호출 할 때 런타임에 해석됩니다. 다음은 함수 foo()에 대한 호출이 어떻게 처리되는지를 보여줍니다.
예상대로 아니,이 작업을 수행 할 수 없습니다. manual
가입일
:
PHP 함수 오버로딩을 지원하지 않으며, 해제하거나 미리 선언 기능을 재정의 할 수있다. 와 마찬가지로
<?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 ?>
: 이런 식으로 뭔가를 할
또한
create_function
을 사용할 수 있습니다 ...
그러나 runkit_function_redefine
와 그 사촌을 사용할 수 있지만, 그것은 확실히 매우 우아하지 않습니다 runkit, 매우 우아하지는 않지만, 당신이 찾고있는 행동을 제공합니다.
종류입니다. http://dev.kafol.net/2008/09/php-redefining-deleting-adding.html을 참조하십시오.
나는이 질문이 다소 오래되었다는 것을 알고 있지만, Patchwork은 최근에 출시 된 PHP 5.3 프로젝트로서 사용자 정의 함수의 재정의를 지원합니다. 저자가 언급했듯이 monkey-patch 코어/라이브러리 함수에는 runkit 또는 php-test-helpers을 사용해야합니다.
아주 멋진 작은 lib. 공유 해 주셔서 감사합니다. –
jmikola가 언급했듯이 패치 워크는 함수에 코드를 추가하려는 경우 좋은 솔루션입니다. http://phpmyweb.net/2012/04/26/write-an-awesome-plugin-system-in-php/
그것은 몇 가지 샘플 코드와 함께 제공 :
여기 그것이 작동하는 방법에 대한 기사입니다. 필자는 phpmyweb 버전이 패치 워크와 달리 eval() 코드를 사용하지 않기 때문에 조금 더 나은 코드를 사용한다고 생각합니다. eval()을 사용할 때 opcode를 캐시 할 수 있습니다.
단위 테스트를 할 때 opcode 캐시에 대해 걱정할 필요가있는 이유는 무엇입니까? 또는 ... 테스트 이외의 다른 것에 원숭이 패치를 사용하고 있습니까? 이 경우에는'eval()'보다 더 큰 문제가있다. – Spudley
@ Spudley 분명히 내가 게시 한 기사는 단위 테스트 (따라서 제목 "멋진 플러그인 시스템 작성")을 목표로하지 않습니다. 그는 단지 플러그인 아키텍처를 만드는 다른 방법을 보여줍니다. 또한 그는 그러한 아키텍처를 만드는 또 다른 방법을 보여주기를 원한다고 말합니다. Ofcourse, 그것은 좋은 방법이라면 토론을위한 것입니다. 나는 그것에 문제가 보이지 않지만. --- 무슨 문제가 있습니까? 저자가 말했듯이, eval()은 패치 워크와 달리 전혀 사용되지 않기 때문에 opcode 캐싱은 문제가되지 않습니다. – Vivendi
@Vivendi, 패치 워크는 내부적으로 런킷 기능을 사용합니까? – Pacerier
허용 대답이 우수 글로벌 함수 foo()를 찾아 호출하려고! 코드를 Namespace brackets에 넣은 다음 기본 GLOBAL-SPACE가 다시 설정된다는 것을 추가합니다.
1) rename_function($old_name,$new_name)
2) override_function($old_name, $parameters, $new_func)
와 거의 사용되지 않는 :
좋은 답변은 왜 받아 들여지지 않습니까? – Pacerier
질문 이후 거의 4 년 후에 게시 되었기 때문에 가능성이 가장 높았으며 아마도 수용된 대답은 당시 가장 관련있는 답변이었을 것입니다. –
나는 아직도 ... 받아 들여지고있다! –