Dieses Mal bringen wir Ihnen eine lustige Erweiterung. Wir wissen, dass wir bei der Ausführung von PHP, also nach Abschluss der Bereitstellung, weder die Werte der Konstanten noch die Implementierung im Methodenkörper ändern können. Mit anderen Worten: Nachdem wir die Codierung abgeschlossen haben, laden wir den Code auf den Server hoch. Zu diesem Zeitpunkt können wir den Wert einer Konstante nicht ändern, ohne den Code zu ändern. Die Konstante selbst kann nicht geändert werden. Die Runkit-Erweiterung kann uns jedoch dabei helfen, diese Funktion zu erfüllen.
Dynamische Änderung von Konstanten
define('A', 'TestA'); runkit_constant_redefine('A', 'NewTestA'); echo A; // NewTestA
Ist das nicht erstaunlich? Diese Runkit-Erweiterung ist eine funktionale Erweiterung, die es uns ermöglicht, einige Konstanten, Methodenkörper und Klassen zur Laufzeit dynamisch zu ändern. Aus Sicht der Systemsicherheit ist diese Erweiterung natürlich nicht unbedingt zu empfehlen. Da die Bedeutung einer Konstante eine unveränderliche Größe ist, sollte sie nicht geändert werden. Ebenso kann sich die dynamische Änderung des Inhalts eines Funktionskörpers oder einer Klassendefinition zur Laufzeit auf anderen Code auswirken, der diese Funktionen oder Klassen aufruft. Daher ist diese Erweiterung eine gefährliche Erweiterung.
Neben der dynamischen Änderung von Konstanten können wir auch die Funktionen runkit_constant_add() und runkit_constant_remove() verwenden, um Konstanten dynamisch hinzuzufügen oder zu löschen.
Installation
Um die Runkit-Erweiterung zu installieren, müssen Sie sie von Github herunterladen und die Erweiterung dann normal kompilieren. Der PECL-Download ist veraltet.
PHP5: http://github.com/zenovich/runkit
PHP7: https://github.com/runkit7/runkit7.git
Clone Nach Erfolg befolgen Sie einfach die normalen Schritte zur Kompilierung und Installation der Erweiterung.
phpize ./configure make make install
Verschiedene PHP-Versionen müssen unterschiedliche Versionen von Erweiterungen installieren. Gleichzeitig befindet sich runkit7 noch in der Entwicklung und einige Funktionen werden noch nicht unterstützt, wie zum Beispiel:
runkit_class_adopt
runkit_class_emancipate
Runkit_import kit_Sandbox
R unkit_Sandbox_Parent
Beim Schreiben des Testcodes für diesen Artikel werden die oben genannten Funktionen oder Klassen verwendet werden nicht unterstützt. Mithilfe der PHP5-Umgebung können Sie testen, ob die Originalerweiterungen normal genutzt werden können.
- Superglobale Variablenschlüssel anzeigen
print_r(runkit_superglobals()); //Array //( // [0] => GLOBALS // [1] => _GET // [2] => _POST // [3] => _COOKIE // [4] => _SERVER // [5] => _ENV // [6] => _REQUEST // [7] => _FILES // [8] => _SESSION //)
Nach dem Login kopierenDiese Funktion überprüft tatsächlich alle superglobalen Variablenschlüsselnamen in der aktuell ausgeführten Umgebung. Dies sind einige unserer häufig verwendeten superglobalen Variablen, daher werde ich sie nicht einzeln erklären. - Methodenbezogene Operationen
Methodenoperationen sind die gleichen wie konstante Operationen. Wir können verschiedene Methoden dynamisch hinzufügen, ändern, löschen und umbenennen. Schauen wir uns zunächst an, was uns am meisten beschäftigt, wenn wir den Logikcode im Methodenkörper während der dynamischen Laufzeit ändern.
function testme() { echo "Original Testme Implementation\n"; } testme(); // Original Testme Implementation runkit_function_redefine('testme','','echo "New Testme Implementation\n";'); testme(); // New Testme Implementation
Nach dem Login kopieren definiert eine testme()-Methode und ändert dann deren Implementierung über runkit_function_redefine(). Wenn testme() schließlich erneut aufgerufen wird, ist die Ausgabe die neu geänderte Implementierung. Können wir also die mit PHP gelieferten Methoden ändern? // php.ini runkit.internal_override=1 runkit_function_redefine('str_replace', '', 'echo "str_replace changed!\n";'); str_replace(); // str_replace changed! runkit_function_rename ('implode', 'joinArr' ); var_dump(joinArr(",", ['a', 'b', 'c'])); // string(5) "a,b,c" array_map(function($v){ echo $v,PHP_EOL; },[1,2,3]); // 1 // 2 // 3 runkit_function_remove ('array_map'); // array_map(function($v){ // echo $v; // },[1,2,3]); // PHP Fatal error: Uncaught Error: Call to undefined function array_map()
Nach dem Login kopierenDie Kommentare im Code machen es sehr deutlich. Wir müssen nur runkit.internal_override=1 in php.ini setzen, um die mit PHP gelieferten Methoden und Funktionen dynamisch zu ändern. Im ersten Absatz haben wir beispielsweise die Methode str_replace() so geändert, dass sie einen Textabsatz direkt ausgeben kann. Dann benennen wir „implode()“ in „joinArr()“ um, damit wir dieses „joinArr()“ genau wie „implode()“ verwenden können. Schließlich haben wir die Methode array_map() entfernt. Wenn diese Methode erneut aufgerufen wird, wird ein Fehler gemeldet.
Der Betrieb der internen Methodenfunktion der Klasse ähnelt dem Betrieb der Variablenmethode oben, wir können jedoch die mit PHP gelieferten Klassen nicht ändern. Sie können es selbst ausprobieren. //runkit_method_add('PDO', 'testAddPdo', '', 'echo "This is PDO new Func!\n";');
//PDO::testAddPdo();
// PHP Warning: runkit_method_add(): class PDO is not a user-defined class
Nach dem Login kopierenWie aus der Fehlermeldung hervorgeht, handelt es sich bei der PDO-Klasse nicht um eine benutzerdefinierte Klasse, sodass die Runkit-Funktion nicht für verwandte Vorgänge verwendet werden kann. Schauen wir uns dann an, wie unsere benutzerdefinierten Klassen Runkit verwenden, um dynamische Vorgänge auszuführen.
//runkit_method_add('PDO', 'testAddPdo', '', 'echo "This is PDO new Func!\n";'); //PDO::testAddPdo(); // PHP Warning: runkit_method_add(): class PDO is not a user-defined class
class Example{ } runkit_method_add('Example', 'func1', '', 'echo "This is Func1!\n";'); runkit_method_add('Example', 'func2', function(){ echo "This is Func2!\n"; }); $e = new Example; $e->func1(); // This is Func1! $e->func2(); // This is Func2! runkit_method_redefine('Example', 'func1', function(){ echo "New Func1!\n"; }); $e->func1(); // New Func1! runkit_method_rename('Example', 'func2', 'func22'); $e->func22(); // This is Func2! runkit_method_remove('Example', 'func1'); //$e->func1(); // PHP Fatal error: Uncaught Error: Call to undefined method Example::func1()
Wir haben eine leere Klasse definiert, ihr dann dynamisch zwei Methoden hinzugefügt, dann Methode 1 geändert, Methode 2 umbenannt und schließlich Methode 1 gelöscht. Die Operationsreihe ist tatsächlich dieselbe wie bei den oben genannten gewöhnlichen Methoden.
Zusammenfassung
Wie oben erwähnt, ist diese Erweiterung eine relativ gefährliche Erweiterung, insbesondere wenn runkit.internal_override aktiviert ist, können wir auch die nativen Funktionen von PHP ändern. Aber wenn Sie es unbedingt benutzen müssen, dann sind seine Funktionen sehr nützlich. Genau wie beim Besuchermuster: „Meistens braucht man das Besuchermuster nicht, aber wenn man das Besuchermuster braucht, braucht man es wirklich.“ Das Gleiche gilt für diesen Satz von Runkit-Erweiterungen.
推荐学习:php视频教程
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202006/source/%E4%B8%80%E8%B5%B7%E5%AD%A6%E4%B9%A0PHP%E7%9A%84runkit%E6%89%A9%E5%B1%95%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8.php