There is a patch in their .src.rpm called 'php-5.0.4-dlopen.patch'. You can blame it on for this :-)
--- php-5.0.4/Zend/zend.h.dlopen
+++ php-5.0.4/Zend/zend.h
@@ -102,11 +102,11 @@
# endif
# if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT)
-# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT)
+# define DL_LOAD(libname) dlopen(libname, RTLD_NOW | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT)
# elif defined(RTLD_DEEPBIND)
-# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND)
+# define DL_LOAD(libname) dlopen(libname, RTLD_NOW | RTLD_GLOBAL | RTLD_DEEPBIND)
# else
-# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL)
+# define DL_LOAD(libname) dlopen(libname, RTLD_NOW | RTLD_GLOBAL)
# endif
# define DL_UNLOAD dlclose
# if defined(DLSYM_NEEDS_UNDERSCORE)
All it does is replaces RTLD_LAZY with RTLD_NOW.
See https://linux.die.net/man/3/dlopen
RTLD_LAZY
Perform lazy binding. Only resolve symbols as the code that references them is executed. If the symbol is never referenced, then it is never resolved. (Lazy binding is only performed for function references; references to variables are always immediately bound when the library is loaded.)
RTLD_NOW
If this value is specified, or the environment variable LD_BIND_NOW is set to a nonempty string, all undefined symbols in the library are resolved before dlopen() returns. If this cannot be done, an error is returned.
As you can see, the default PHP's behavior (RTLD_LAZY) allows to resolve the external symbols after all extensions have been loaded. The patch changes this behavior requesting that all symbols be resolvbed when the extension is loaded. And because of this patch the order of loaded extensions is important.