2009-02-10 6 views

Antwort

11

Dies ist ein Bit spät, aber ich möchte nur darauf hinweisen, dass seit PHP 5.3 ist es tatsächlich möglich, interne Funktionen ohne eine PHP-Erweiterung zu überschreiben.

Der Trick ist, dass Sie eine interne PHP-Funktion in einem Namespace neu definieren können. Es basiert auf der Art und Weise, wie PHP die Namensauflösung für Funktionen ausführt:

Innerhalb des Namespace (zB A \ B) werden Aufrufe von nicht qualifizierten Funktionen zur Laufzeit aufgelöst. Hier ist, wie ein Aufruf der Funktion foo() gelöst wird:

  1. Es sucht nach einer Funktion aus dem aktuellen Namespace: A \ B \ foo().
  2. Es wird versucht, die globale Funktion foo()
+0

Schön, warum wird diese Antwort nicht akzeptiert? – Pacerier

+1

Am wahrscheinlichsten, weil es fast vier Jahre nach der Frage veröffentlicht wurde, und die angenommene Antwort war zu der Zeit wahrscheinlich die relevanteste. –

+0

Ich bin immer noch auf SO ... Akzeptiert! –

9

Nein, es ist nicht möglich, dies zu tun, wie man erwarten könnte.

Vom manual:

PHP arbeitet nicht Überlastung unterstützen, noch ist es möglich, zuvor deklarierte Funktionen zu definieren oder neu definieren.

Sie können jedoch runkit_function_redefine und seine Vettern verwenden, aber es ist auf jeden Fall nicht sehr elegant ...

Sie auch create_function verwenden können, um so etwas zu tun:

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

Wie bei Runkit, es ist nicht sehr elegant, aber es gibt das Verhalten, das Sie suchen.

+0

Du hast es zweimal gesagt, aber warum ist es "nicht sehr elegant"? – Pacerier

+0

@Pacierer: Nun, für den Anfang ist es ein bisschen ein Code-Geruch zu wollen, um dies zu tun, um zu beginnen, und es wird definitiv jeden hinter Ihnen zurückwerfen, um Ihren Code zu sehen, aber wenn Sie vorbeikommen dass Sie in beiden Fällen den Funktionscode als Zeichenfolgenargument eingeben müssen, was für alles außer den kürzesten Funktionen unschön ist. –

+0

Sicherlich sind wir zumindest auf PHP 5.3, niemand macht String mehr, der Funktionscode kann als anonyme Funktion geliefert werden. – Pacerier

5

Ich weiß, dass diese Frage ein bisschen alt ist, aber Patchwork ist ein kürzlich veröffentlichtes PHP 5.3-Projekt, das die Neudefinition von benutzerdefinierten Funktionen unterstützt. Allerdings, wie der Autor erwähnt, müssen Sie auf runkit oder php-test-helpers zu affe-patch Kern/Bibliothek Funktionen zurückgreifen.

+2

Sehr nette kleine Lib. Danke für das Teilen :) –

1

Wie Jmikola erwähnt, Patchwork ist eine gute Lösung, wenn Sie Code zu einer Funktion hinzufügen möchten.

Hier ist ein Artikel darüber, wie es funktioniert: http://phpmyweb.net/2012/04/26/write-an-awesome-plugin-system-in-php/

Es kommt mit einigen Beispielcode. Ich denke, die phpmyweb-Version verwendet einen etwas besseren Code, weil er im Gegensatz zu Patchwork nicht den eval() 'd-Code verwendet. Sie können Opcodes bei der Verwendung von eval() zwischenspeichern.

+0

Warum müssen Sie sich über Opcode-Caches Gedanken machen, wenn Sie Unit-Tests durchführen? Oder was ... du benutzt Affepatch für etwas anderes als Testen? In diesem Fall haben Sie größere Probleme als 'eval()', um die Sie sich kümmern müssen. – Spudley

+1

@Spudley Offensichtlich ist der Artikel, den ich gepostet habe, nicht auf Unit Testing ausgerichtet (daher der Titel "Schreibe ein tolles Plugin-System"). Er zeigt nur eine andere Möglichkeit, eine Plugin-Architektur zu erstellen. Und er sagt auch, dass er nur einen anderen Weg zeigen will, eine solche Architektur zu schaffen. Natürlich steht es zur Diskussion, ob es ein guter Weg ist. Obwohl ich keine Probleme damit sehe. --- Über welche "Probleme" sprichst du? Wie der Autor sagte, sollte Opcode-Caching kein Problem sein, da eval() überhaupt nicht verwendet wird (im Gegensatz zu Patchwork). – Vivendi

+0

@Vivendi, Verwendet Patchwork intern die Runkit-Funktionen? – Pacerier