phpDaemon and runkit: a new level
Today I will tell you about new delicious phpDaemon goodies, including those provided by the runkit PHP module.
I am glad to report that the code style in phpDaemon is adapted to the preferences of most terrestrial programmers, and not just harsh aliens. Thanks for this silentroach . Also, comments on the style and readability of the code are now adequately perceived.
PECL / runkit is a very remarkable PHP module, the story of which was laid by the female programmer Sara Golemon back in August 2005. Its purpose is to allow in the process of script execution to change constants, redefine functions and classes, and perform other manipulations in PHP akin to black magic ...
However, the project was very crude, it took a long time to fix bugs and maintain compatibility with new versions of PHP. And Sara lost interest in developing the project, for reasons we can only guess. But she did the main thing - showed that all this is possible - a matter of technology. After that, pajoye, johannes, sfox, sebastian, mlively, and others made changes. However, for example, for the whole of 2007 there were only 4 commits, and the module continued to be severely buggy and lag behind the main PHP branch. There were several fork attempts by third-party developers, but only one in my opinion was successful.
Our compatriot Dmitry Zenovich ( dzenovich ) gave him a new life, at github.com/zenovich/runkit : The runkit that works!
Previously, when you included the --auto-reload = 5s option in phpDaemon, the daemon checked the modification dates of all connected PHP files every 5 seconds, and when changing them, it went into a smooth restart. Now, just turn on --auto-reimport and instead of a smooth restart, the modified file will be imported directly into the live process. This greatly simplifies life, I must say. Thanks for this to Dmitry Zenovich! (and a little to me for fumbling).
In addition to manipulating classes, constants, and functions, runkit allows you to create a sandbox. It looks like this:
At the same time, the code executed in the sandbox cannot affect the genitive context, and Fatal error / Parse error will not cause the main script to crash. You can also set any ini options for the sandbox.
Runkit allows you to redefine not only user-defined, but also native PHP functions. Currently phpDaemon is overloading header () and register_shutdown_function () and directing calls to the corresponding methods of the current request.
There is a separate story with the create_function () function. Maybe someone does not know the background of this function, but in reality it is this:
That is, it creates the most ordinary and ordinary function and returns its name as a string. Of course, there is no question of any removal of unnecessary lambda functions, they live until the death of the script. I myself did not pay attention to this problem since I haven’t been using create_function for a long time, but Ilya Kantor ( algo ) in his article (True FastCGI for PHP - migration and tests) drew attention to this and suggested remembering the names of all lambda functions created during the execution of the request and clearing it at the end. This solution is suitable for its task, but in general for phpDaemon it is unacceptable for obvious reasons.
Therefore, I came up with another solution, in my opinion more elegant and universal. My create_function () returns a DestructableLambda object, in the destructor of which the lambda function is deleted via runkit. In addition, there is an LRU cache that stores the most commonly compiled lambda functions, which reduces compilation costs. Source code .
If you have any ideas what other features can be improved, we will be glad to hear.
Well, perhaps that's all. Thank you all for your attention.
Github: kakserpom / phpdaemon
Homepage: http://phpdaemon.net
Group: groups.google.com/group/phpdaemon
I am glad to report that the code style in phpDaemon is adapted to the preferences of most terrestrial programmers, and not just harsh aliens. Thanks for this silentroach . Also, comments on the style and readability of the code are now adequately perceived.
Runkit story
PECL / runkit is a very remarkable PHP module, the story of which was laid by the female programmer Sara Golemon back in August 2005. Its purpose is to allow in the process of script execution to change constants, redefine functions and classes, and perform other manipulations in PHP akin to black magic ...
However, the project was very crude, it took a long time to fix bugs and maintain compatibility with new versions of PHP. And Sara lost interest in developing the project, for reasons we can only guess. But she did the main thing - showed that all this is possible - a matter of technology. After that, pajoye, johannes, sfox, sebastian, mlively, and others made changes. However, for example, for the whole of 2007 there were only 4 commits, and the module continued to be severely buggy and lag behind the main PHP branch. There were several fork attempts by third-party developers, but only one in my opinion was successful.
Our compatriot Dmitry Zenovich ( dzenovich ) gave him a new life, at github.com/zenovich/runkit : The runkit that works!
Update code on the fly
Previously, when you included the --auto-reload = 5s option in phpDaemon, the daemon checked the modification dates of all connected PHP files every 5 seconds, and when changing them, it went into a smooth restart. Now, just turn on --auto-reimport and instead of a smooth restart, the modified file will be imported directly into the live process. This greatly simplifies life, I must say. Thanks for this to Dmitry Zenovich! (and a little to me for fumbling).
Runkit_sandbox
In addition to manipulating classes, constants, and functions, runkit allows you to create a sandbox. It looks like this:
$sandbox = new Runkit_Sandbox(array(
'safe_mode' => TRUE,
....
'output_handler' => array($this,'out')
));
$sandbox->call_user_func(function() {
echo "Hello World!";
});
At the same time, the code executed in the sandbox cannot affect the genitive context, and Fatal error / Parse error will not cause the main script to crash. You can also set any ini options for the sandbox.
Overriding Native PHP Functions
Runkit allows you to redefine not only user-defined, but also native PHP functions. Currently phpDaemon is overloading header () and register_shutdown_function () and directing calls to the corresponding methods of the current request.
There is a separate story with the create_function () function. Maybe someone does not know the background of this function, but in reality it is this:
function create_function($args,$code)
{
static $c = 0;
$name = "\x00lambda_".$c++;
eval('function '.$name.'('.$args.') {'.$code.'}');
return $name;
}
That is, it creates the most ordinary and ordinary function and returns its name as a string. Of course, there is no question of any removal of unnecessary lambda functions, they live until the death of the script. I myself did not pay attention to this problem since I haven’t been using create_function for a long time, but Ilya Kantor ( algo ) in his article (True FastCGI for PHP - migration and tests) drew attention to this and suggested remembering the names of all lambda functions created during the execution of the request and clearing it at the end. This solution is suitable for its task, but in general for phpDaemon it is unacceptable for obvious reasons.
Therefore, I came up with another solution, in my opinion more elegant and universal. My create_function () returns a DestructableLambda object, in the destructor of which the lambda function is deleted via runkit. In addition, there is an LRU cache that stores the most commonly compiled lambda functions, which reduces compilation costs. Source code .
If you have any ideas what other features can be improved, we will be glad to hear.
The end
Well, perhaps that's all. Thank you all for your attention.
Github: kakserpom / phpdaemon
Homepage: http://phpdaemon.net
Group: groups.google.com/group/phpdaemon