2009-02-10 6 views

Odpowiedz

11

Jest to końcówka bit późno, ale chcę tylko zwrócić uwagę, że od PHP 5.3, możliwe jest nadpisanie funkcji wewnętrznych bez użycia rozszerzenia PHP.

Sztuką jest to, że możesz ponownie zdefiniować wewnętrzną funkcję PHP wewnątrz przestrzeni nazw. Opiera się na sposobie, w jaki PHP wykonuje rozpoznawanie nazw dla funkcji:

Wewnętrzna przestrzeń nazw (np. A \ B), połączenia z niewykwalifikowanymi funkcjami są rozwiązywane w czasie wykonywania. Oto, jak rozwiązywane jest wywołanie funkcji foo():

  1. Szuka funkcji z bieżącego obszaru nazw: A \ B \ foo().
  2. Próbuje odnaleźć i wywołać globalną funkcję foo()
+0

Dobrze, dlaczego ta odpowiedź nie jest akceptowana? – Pacerier

+1

Najprawdopodobniej dlatego, że został wysłany prawie cztery lata po pytaniu, a zaakceptowana odpowiedź była prawdopodobnie najbardziej odpowiednia w danym momencie. –

+0

Nadal jestem na ... Zaakceptowany! –

9

Nie, to nie jest możliwe, aby to zrobić, jak można się było spodziewać.

Z manual:

PHP nie obsługuje przeciążania funkcji, ani nie jest możliwe definiowanie lub przedefiniowanie wcześniej zadeklarowanych funkcji.

Można jednak użyć runkit_function_redefine i jego kuzynów, ale to na pewno nie jest bardzo elegancki ...

Można również użyć create_function zrobić coś takiego:

<?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 
?> 

jak w przypadku Runkit, nie jest zbyt elegancki, ale daje zachowanie, którego szukasz.

+0

Powiedziałeś to dwa razy, ale dlaczego jest "niezbyt elegancka"? – Pacerier

+0

@Pacerier: Cóż, na początek, jest to trochę zakodowany zapach, który chciałby to zrobić na samym początku, i zdecydowanie odrzuci każdego, kto przyjdzie za tobą, aby spojrzeć na twój kod, ale jeśli przejdziesz do przeszłości że w obu przypadkach musisz wpisać kod funkcji jako argument łańcuchowy, co jest brzydkie w przypadku innych niż najkrótszych funkcji. –

+0

Z pewnością jesteśmy przynajmniej na PHP 5.3, nikt już nie obsługuje Stringa, kod funkcji może być dostarczony jako funkcja anonimowa. – Pacerier

5

Zdaję sobie sprawę, że to pytanie jest trochę stare, ale Patchwork to niedawno wydany projekt PHP 5.3, który obsługuje redefinicję funkcji zdefiniowanych przez użytkownika. Chociaż, jak wspomina autor, będziesz musiał odwołać się do runkit lub php-test-helpers do funkcji rdzeniowych/bibliotecznych z małpowaniem.

+2

Bardzo ładna mała biblioteka. Dziękuję za udostępnienie :) –

1

Jak wspomniano jmikola, Patchwork jest dobrym rozwiązaniem, jeśli chcesz dodać kod do funkcji.

Oto artykuł o tym, jak to działa: http://phpmyweb.net/2012/04/26/write-an-awesome-plugin-system-in-php/

Chodzi o jakiś przykładowy kod. Wydaje mi się, że wersja phpmyweb używa nieco lepszego kodu, ponieważ nie używa kodu eval() d, w przeciwieństwie do patchworku. Możesz używać podręcznych kodów podczas używania eval().

+0

dlaczego musisz martwić się pamięcią podręczną o kodach, gdy testujesz jednostkę? Albo co ... używasz łatania małp dla czegoś innego niż testowanie? w takim przypadku masz większe problemy niż "eval()", aby się martwić. – Spudley

+1

@Spudley Oczywiście napisany przeze mnie artykuł nie jest skierowany na testowanie jednostek (stąd tytuł "Napisz niesamowity system wtyczek"). Pokazuje tylko inny sposób tworzenia architektury wtyczek. Mówi też, że chce pokazać inny sposób tworzenia takiej architektury. Oczywiście, to jest do dyskusji, jeśli jest to dobry sposób. Chociaż nie widzę z tym żadnych problemów. --- Na czym polegają "problemy"? Tak jak powiedział autor, buforowanie kodu nie powinno stanowić problemu, ponieważ eval() nie jest w ogóle używany (w przeciwieństwie do patchworku). – Vivendi

+0

@Vivendi, czy patchwork używa wewnętrznie funkcji runkit? – Pacerier