简体   繁体   中英

Can I Extend a Built-In PHP Function?

Long story short I'm working with a legacy codebase that makes heavy use of PHP's built-in call_user_func_array function. I'm trying to get it to work with PHP 5.3 (upgrading from 5.2), but have run into the issue described here (in the "Passing non-arrays" section):

http://sixohthree.com/1486/migrating-to-php-5-3-call_user_func_array

In a nutshell, the problem is that between PHP versions 5.2 and 5.3 the bevavior of this function was changed so that it basically does nothing and returns NULL if the second parameter is not a proper array/object/associative array. 5.2 did not do this, and as such the codebase I'm working with makes no effort to ensure that it passes a parameter of the correct type. This causes problems.

To fix it I could follow the instructions in the blog post and hunt down every single call_user_func_array call in the codebase and patch them up, but that would be extremely tedious. Alternately, I noticed that PHP has a built-in override_function API call that can be used to override the built-in functions. That's handy, but what I want to do is more like extending the built-in function.

Ideally what I'd like is to be able to replace the implementation of call_user_func_array with something roughly like:

function call_user_func_array($method, $params) {
    $params = is_array($params) ? $params : array($params);
    return old_call_user_func_array($method, $params);
}

...where old_call_user_func_array is the built-in call_user_func_array function.

Is this possible, and if so, how?

You can use rename_function which is also in the APD extension so you should already have it if you have override_function installed:

rename_function('call_user_func_array', 'old_user_func_array');

function call_user_func_array($method, $params) {
    $params = is_array($params) ? $params : array($params);
    old_call_user_func_array($method, $params);
}

Hi your question is actually answered in the third or fourth comment posting in the online PHP documentation. There is often very useful information and examples in the comments section (mind you there is also somtimes stuff that is patently incorrect!) I've copied the relevant portion here for your convenience:

... if you use rename_function to rename the original function to a third name, then call the third name in the OVERRIDING function, you will get the desired effect:

rename_function('strlen', 'new_strlen');

override_function('strlen', '$string', 'return override_strlen($string);');

function override_strlen($string){ return new_strlen($string);}

or you can put your code in a namespace:

namespace Phpoverride
{
    function call_user_func_array($method, $params) {
        return \call_user_func_array($method, $params);
    }
}

http://php.net/namespaces

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM