Can I replace a (PHP) built-in?

How fast is PHP's str_starts_with() function? Let's pretend it's excruciatingly slow (it isn't) and that we believe we can replace it with a function of our own, written in PHP, that's much faster (I bet we can't). How would we even do this? Is it allowed?

One approach might be to use namespaces:

namespace CustomFunctions {
    function str_starts_with(string $haystack, string $needle): bool {
        return strpos($haystack, $needle) === 0;
    }
}

namespace App {
    use function CustomFunctions\str_starts_with;
    var_dump(str_starts_with('foo bar', 'foo'));
}

This works, but it's a bit of a cheat (in the sense that it doesn't truly replace anything), and, since it depends on a use function statement, it is limited to situations where we can modify the source files that reference the function.

A tool like Patchwork, which brings monkey-patching capabilities to PHP, is another possibility. This is a fantastic tool, and perhaps even the best solution in most cases, but it does come with a non-negligible performance impact. Mind you, it also goes beyond the scope of this post, because it also allows user-defined functions to be redefined (so, if that sort of thing is needed, Patchwork is your guy).

What other options are left? Well, we can knock out the default str_starts_with() function so long as we have the ability to configure PHP through it's ini files. In this case, we can create or add an ini directive to disable this and potentially various other functions:

disable_functions = "str_starts_with"

More info on the disable_functions directive can be found over here. Multiple (comma-sepated) functions can be passed, not just one. However, it does not work on user-defined functions or language constructs like isset (which look like functions, are used a little like functions, but aren't really functions).

Et voilà, we no longer have to worry about PHP's version of the function, and can define and force other source files to use our own version:

// This can be defined during app bootstrap, etc.
function str_starts_with(string $haystack, string $needle): bool {
    return strpos($haystack, $needle) === 0;
}

// Now our custom replacement will be used instead of PHP's built-in.
var_dump(str_starts_with('foo bar', 'foo'));

 

You may also like:

Custom (PHP) snippets in WordPress

Often you will see tutorials that describe how to customize WordPress and, frequently, they will suggest you do this by...