Home  >  Article  >  Backend Development  >  Let's take a look at how to use the runkit extension in PHP

Let's take a look at how to use the runkit extension in PHP

青灯夜游
青灯夜游forward
2021-06-09 18:42:153133browse

This article will talk about how to use the runkit extension in PHP. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.

Let's take a look at how to use the runkit extension in PHP

This time we bring you a fun expansion. We know that when PHP is running, that is, after deployment is completed, we cannot modify the values ​​of constants, nor can we modify the implementation inside the method body. In other words, after we complete the coding, we upload the code to the server. At this time, we cannot modify the value of a constant without modifying the code. The constant itself cannot be modified. However, the runkit extension can help us accomplish this function.

Dynamic modification of constants

define('A', 'TestA');

runkit_constant_redefine('A', 'NewTestA');

echo A; // NewTestA

Isn’t it amazing? This runkit extension is a functional extension that allows us to dynamically modify some constants, method bodies, and classes at runtime. Of course, from a system security perspective, this extension is not highly recommended. Because the meaning of a constant is an unchanging quantity, it should not be modified. In the same way, dynamically changing the content of a function body or class definition at runtime may affect other code that calls these functions or classes. Therefore, this extension is a dangerous extension.

In addition to dynamically modifying constants, we can also use the runkit_constant_add() and runkit_constant_remove() functions to dynamically add or delete constants.

Installation

To install the runkit extension, you need to download it from github and then compile the extension normally. The one downloaded from pecl is outdated.

PHP5: http://github.com/zenovich/runkit

PHP7: https://github.com/runkit7/runkit7.git

clone after success Just follow the normal extension compilation and installation steps.

phpize
./configure
make
make install

Different PHP versions need to install different versions of extensions. At the same time, runkit7 is still under development, and some functions are not yet supported, such as:

  • runkit_class_adopt
  • runkit_class_emancipate
  • runkit_import
  • runkit_lint_file
  • runkit_lint
  • runkit_sandbox_output_handler
  • runkit_return_value_used
  • Runkit_Sandbox
  • Runkit_Sandbox_Parent

When writing the test code for this article, the above functions or classes were not supported. You can use the PHP5 environment to test whether the original extensions can be used normally.

View super global variable keys

print_r(runkit_superglobals());
//Array
//(
//    [0] => GLOBALS
//    [1] => _GET
//    [2] => _POST
//    [3] => _COOKIE
//    [4] => _SERVER
//    [5] => _ENV
//    [6] => _REQUEST
//    [7] => _FILES
//    [8] => _SESSION
//)

This function actually checks all super global variable key names in the current running environment. These are some of our commonly used superglobal variables, so I won’t explain them one by one.

Method related operations

Method operations are the same as constant operations. We can dynamically add, modify, delete and rename various methods. First, let’s take a look at what we are most concerned about when modifying the logic code in the method body during dynamic runtime.

function testme() {
  echo "Original Testme Implementation\n";
}
testme(); // Original Testme Implementation
runkit_function_redefine('testme','','echo "New Testme Implementation\n";');
testme(); // New Testme Implementation

Define a testme() method, and then modify its implementation through runkit_function_redefine(). Finally, when testme() is called again, the output will be the newly modified implementation. So, can we modify the methods that come with PHP?

// 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()

The comments in the code make it very clear. We only need to set runkit.internal_override=1 in php.ini to dynamically modify the methods and functions that come with PHP. For example, in the first paragraph, we modified the str_replace() method so that it can directly output a paragraph of text. Then we rename implode() to joinArr() so that we can use this joinArr() just like implode(). Finally, we removed the array_map() method. If this method is called again, an error will be reported.

Class method related operations

The operation of the internal method function of the class is similar to the operation of the variable method above, but we cannot modify the classes that come with PHP. operation. You can try this yourself.

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

It can be seen from the error message that the PDO class is not a user-defined class, so the runkit function cannot be used for related operations. Then let's take a look at how our custom classes use runkit to perform dynamic operations.

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()

We defined an empty class, then dynamically added two methods to it, then modified method 1, renamed method 2, and finally deleted method 1. The series of operations are actually the same as above The operation of the ordinary method is basically the same.

Summary

As mentioned above, this extension is a relatively dangerous extension, especially if runkit.internal_override is turned on, we can also modify it PHP native functions. But if you must use it, then its functions are very useful. Just like the visitor pattern, "most of the time you don't need the visitor pattern, but when you need the visitor pattern, you really need it." The same is true for this set of runkit extensions.

Test code:

github.com/zhangyue050…

Recommended learning: "PHP Video Tutorial"

The above is the detailed content of Let's take a look at how to use the runkit extension in PHP. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete