Sep 20, 2008

PHP: redefining, deleting, adding functions on the fly

Allthough this is not possible with just pure PHP - quote from the manual "...nor is it possible to undefine or redefine previously-declared functions.". The only thing PHP CAN do is to create function anonymously with create_function(), which is a runkit equivalent to runkit_function_add(); Redefining and undefining is still possible with runkit functions. This requires an additional software install - it is a PHP addon (PECL extension), a brief howto is explained here: http://si2.php.net/manual/en/runkit.installation.php. If you're using FreeBSD, installation from ports is fairly simple, you just
cd /usr/ports/devel/pecl-runkit
make install clean
Afther that, the runkit functions run brilliantly and you can use tools like
runkit_function_add('testme','$a,$b','echo "The value of a is $a\n"; echo "The value of b is $b\n";');
runkit_function_redefine('testme','','echo "New Testme Implementation\n";');
runkit_function_copy('original','duplicate');
runkit_function_rename('duplicate','dupl1c4t3');
runkit_function_remove('original');
These are mostly examples from PHP.net, but you get the idea. There are not a lot of examples there, nor comments (which I find rather strange), so from this point on, you're on your own to explore further. I haven't used these functions yet, but I have an idea for when and where they could be useful - for example: My Online Briscola server runs on an endless PHP loop, so for any change I make, I need to restart the server, which is a bad option if there are users on the server. With runkit, I could put all updatable functions in a seperate include file and use runkit to refresh the include functions every few minutes. But remember, all paramaters in runkit are strings which can be quite confusing the first time you use it, but you'll get the hang of it.

1 comment:

Anonymous said...

re: strings, i just did something like:

require(PATH_EXT."asc/func.build_sql_query".EXT); runkit_method_redefine('Weblog','build_sql_query','$qstring=""',$build_sql_query_new);

where the required file contains the code for the redefined function build_sql_query, storing it in $build_sql_query_new by means of buffering,

<\? ob_start(); \?>
... code here ...
<\?
$build_sql_query_new = ob_get_contents();
ob_end_clean();
\?>