php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #60128
Patch spl-classloader revision 2011-10-25 10:18 UTC by davidc@php.net

Patch spl-classloader for SPL related Bug #60128

Patch version 2011-10-25 10:18 UTC

Return to Bug #60128 | Download this patch
Patch Revisions:

Developer: davidc@php.net

Index: ext/spl/spl_classloader.c
===================================================================
--- ext/spl/spl_classloader.c	(revision 0)
+++ ext/spl/spl_classloader.c	(revision 0)
@@ -0,0 +1,464 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2009 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.01 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_01.txt                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: metagoto <runpac314@gmail.com>                              |
+   |          David Coallier <davidc@php.net>                             |
+   +----------------------------------------------------------------------+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "zend_interfaces.h"
+
+#include "spl_classloader.h"
+
+#include "php_spl.h"
+#include "spl_engine.h"
+#include "spl_functions.h"
+#include "spl_exceptions.h"
+
+zend_object_handlers spl_handler_SplClassLoader;
+PHPAPI zend_class_entry *spl_ce_SplClassLoader;
+
+/* zend_API.h: #define ZEND_NS_NAME(ns, name)           ns"\\"name */
+#define SPL_CLASSLD_NS_SEPARATOR '\\'
+
+
+static zend_class_entry* spl_classloader_ce;
+zend_object_handlers spl_SplClassLoader_handlers;
+
+
+typedef struct _spl_SplClassLoader { 
+    zend_object std;
+    char* ns;
+    int   ns_len;
+    char* inc_path;
+    int   inc_path_len;
+    char* file_ext;
+    int   file_ext_len;
+} spl_SplClassLoader;
+
+
+static void spl_SplClassLoader_dtor(void* object, zend_object_handle handle TSRMLS_DC)
+{
+    spl_SplClassLoader* obj = (spl_SplClassLoader*)object;
+    if (obj->ns) {
+        efree(obj->ns);
+        obj->ns = NULL;
+    }
+    if (obj->inc_path) {
+        efree(obj->inc_path);
+        obj->inc_path = NULL;
+    }
+    if (obj->file_ext) {
+        efree(obj->file_ext);
+        obj->file_ext = NULL;
+    }
+    zend_object_std_dtor(&obj->std TSRMLS_CC);
+    efree(obj);
+}
+
+
+zend_object_value spl_object_classloader_new_ex(zend_class_entry *class_type, spl_SplClassLoader **obj, zval *orig TSRMLS_DC) /* {{{ */
+{
+    zend_object_value retval;
+    spl_SplClassLoader *intern;
+
+    intern = emalloc(sizeof(spl_SplClassLoader));
+    memset(intern, 0, sizeof(spl_SplClassLoader));
+    *obj = intern;
+
+    zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+    object_properties_init(&intern->std, class_type);
+    
+    //zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void*)NULL, sizeof(zval*));
+
+    intern->file_ext = estrndup(".php", sizeof(".php")-1);
+    intern->file_ext_len = sizeof(".php")-1;
+    
+    retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (void*)spl_SplClassLoader_dtor, NULL TSRMLS_CC);
+    retval.handlers = &spl_SplClassLoader_handlers;
+
+    return retval;
+} /* }}} */
+
+/* {{{ spl_SplClassLoader_new */
+static zend_object_value spl_SplClassLoader_new(zend_class_entry *class_type TSRMLS_DC)
+{   
+    spl_SplClassLoader *tmp;
+    return spl_object_classloader_new_ex(class_type, &tmp, NULL TSRMLS_CC);
+}   
+/* }}} */
+
+/* {{{ proto void SplClassLoader::__construct([string $namespace [, string $include_path]])
+       Constructor */
+SPL_METHOD(SplClassLoader, __construct)
+{
+    char* ns = NULL;
+    int   ns_len = 0;
+    char* inc_path = NULL;
+    int   inc_path_len = 0;
+    spl_SplClassLoader* obj;
+    
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &ns, &ns_len, &inc_path, &inc_path_len) == FAILURE) {
+        return; /* should throw ? */
+    }
+
+    obj = (spl_SplClassLoader *) zend_object_store_get_object(getThis() TSRMLS_CC);
+    
+    if (ns_len) {
+        obj->ns = estrndup(ns, ns_len);
+        obj->ns_len = ns_len;
+    }
+
+    if (inc_path_len) {
+        obj->inc_path = estrndup(inc_path, inc_path_len);
+        obj->inc_path_len = inc_path_len;
+    }    
+} /* }}} */
+
+/* {{{ proto bool SplClassLoader::register()
+   Installs this class loader on the SPL autoload stack */
+SPL_METHOD(SplClassLoader, register)
+{   
+    zval* arr;
+    zval* retval = NULL;
+    zval* pthis = getThis();
+    int res = 0;
+    
+    MAKE_STD_ZVAL(arr);
+    array_init(arr);
+    Z_ADDREF_P(pthis);
+
+    add_next_index_zval(arr, pthis);
+    add_next_index_string(arr, estrndup("loadClass", sizeof("loadClass")-1), 0);
+
+    zend_call_method_with_1_params(NULL, NULL, NULL, "spl_autoload_register", &retval, arr);
+
+    zval_ptr_dtor(&arr);
+    
+    if (retval) {
+        res = i_zend_is_true(retval);
+        zval_ptr_dtor(&retval);
+    }
+    RETURN_BOOL(res);
+} /* }}} */
+
+/* {{{ proto bool SplClassLoader::unregister()
+   Uninstalls this class loader from the SPL autoloader stack */
+SPL_METHOD(SplClassLoader, unregister)
+{   
+    zval* arr;
+    zval* retval = NULL;
+    zval* pthis = getThis();
+    int res = 0;
+    
+    MAKE_STD_ZVAL(arr);
+    array_init(arr);
+    Z_ADDREF_P(pthis);
+
+    add_next_index_zval(arr, pthis);
+    add_next_index_string(arr, estrndup("loadClass", sizeof("loadClass")-1), 0);
+
+    zend_call_method_with_1_params(NULL, NULL, NULL, "spl_autoload_unregister", &retval, arr);
+
+    zval_ptr_dtor(&arr);
+    
+    if (retval) {
+        res = i_zend_is_true(retval);
+        zval_ptr_dtor(&retval);
+    }
+
+    RETURN_BOOL(res);
+} /* }}} */
+
+
+/* compute filename if (partial) ns and class match. returns filename len including '\0' or 0 */
+static int get_filename(spl_SplClassLoader* obj, char* cl, int cl_len, char* filename TSRMLS_DC)
+{
+    char* ccl = cl;
+    char* cns = obj->ns;
+    char* cur = &cl[cl_len-1];
+    int   len = 0;
+    
+    if (cl_len < obj->ns_len) {
+        return 0; 
+    }
+    
+    /* we have a ns to compare to the qualified class name */
+    if (obj->ns) {
+        int i = 0; /* compare and transform ns separator in place */
+        for ( ; i < obj->ns_len; ++i) {
+            if (*cns != *ccl) {
+                return 0;
+            }
+            if (*ccl == SPL_CLASSLD_NS_SEPARATOR) {
+                *ccl = PHP_DIR_SEPARATOR;
+            }
+            ++ccl;
+            ++cns;
+        }
+        if (*ccl != SPL_CLASSLD_NS_SEPARATOR) {
+            return 0;
+        }
+        *ccl = PHP_DIR_SEPARATOR;
+    }
+    
+    /* transform '_' in the class name from right to left */
+    for ( ; cur != ccl; --cur) {
+        if (*cur == SPL_CLASSLD_NS_SEPARATOR) {
+            break;
+        }
+        if (*cur == '_') {
+            *cur = PHP_DIR_SEPARATOR;
+        }
+    }
+    
+    /* tranform the remaining ns separator from right to left */
+    for ( ; cur != ccl; --cur) {
+        if (*cur == SPL_CLASSLD_NS_SEPARATOR) {
+            *cur = PHP_DIR_SEPARATOR;
+        }
+    }
+    
+    if (obj->inc_path) {  
+        len = obj->inc_path_len + 1 + cl_len + obj->file_ext_len + 1;
+        if (len > MAXPATHLEN) {
+            return 0;
+        }
+        /* sprintf: we know the len */
+        sprintf(filename, "%s%c%s%s", obj->inc_path, PHP_DIR_SEPARATOR, cl, obj->file_ext);
+        return len;
+    }
+    len = cl_len + obj->file_ext_len + 1;
+    if (len > MAXPATHLEN) {
+        return 0;
+    }
+    /* sprintf: we know the len */
+    sprintf(filename, "%s%s", cl, obj->file_ext);
+    return len;
+}
+
+
+/* {{{ proto bool SplClassLoader::loadClass(string $class_name)
+   Loads the given class or interface */
+SPL_METHOD(SplClassLoader, loadClass)
+{
+    char* cl;
+    int   cl_len = 0;
+    char  filename[MAXPATHLEN];
+    int   len = 0;
+    spl_SplClassLoader* obj;
+    
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s/", &cl, &cl_len) == FAILURE /* zval separation is required */
+        || !cl_len) {
+        return;
+    }
+   
+    obj = (spl_SplClassLoader*) zend_object_store_get_object(getThis() TSRMLS_CC);
+    
+    len = get_filename(obj, cl, cl_len, filename TSRMLS_CC);
+    if (len) {
+        zend_file_handle fh;
+        fh.filename = filename;
+        fh.opened_path = NULL;
+        fh.free_filename = 0;
+        fh.type = ZEND_HANDLE_FILENAME;
+        zend_execute_scripts(ZEND_INCLUDE TSRMLS_CC, NULL, 1, &fh);
+        RETURN_TRUE;
+    }
+
+    RETURN_FALSE;
+} /* }}} */
+
+/* {{{ proto bool SplClassLoader::setIncludePath(string $include_path)
+   Sets the base include path for all class files in the namespace of this class loader */
+SPL_METHOD(SplClassLoader, setIncludePath)
+{
+    char* inc_path;
+    int   inc_path_len;
+    spl_SplClassLoader* obj;
+    
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &inc_path, &inc_path_len)== FAILURE) {
+        return;
+    }
+    
+    obj = (spl_SplClassLoader*) zend_object_store_get_object(getThis() TSRMLS_CC);
+    
+    if (obj->inc_path) {
+        efree(obj->inc_path);
+        obj->inc_path = NULL;
+    }
+
+    if (inc_path_len) {
+        obj->inc_path = estrndup(inc_path, inc_path_len);    
+    }
+
+    obj->inc_path_len = inc_path_len;
+
+    RETURN_TRUE;
+} /* }}} */
+
+/* {{{ proto string SplClassLoader::getIncludePath()
+   Gets the base include path for all class files in the namespace of this class loader */
+SPL_METHOD(SplClassLoader, getIncludePath)
+{
+    spl_SplClassLoader* obj = (spl_SplClassLoader*) zend_object_store_get_object(getThis() TSRMLS_CC);
+    
+    if (obj->inc_path) {
+        RETURN_STRINGL(obj->inc_path, obj->inc_path_len, 1);
+    }
+
+    RETURN_EMPTY_STRING();
+} /* }}} */
+
+/* {{{ proto bool SplClassLoader::setFileExtension(string $file_extension)
+   Sets the file extension of class files in the namespace of this class loader */
+SPL_METHOD(SplClassLoader, setFileExtension)
+{
+    char* ext;
+    int   ext_len;
+    spl_SplClassLoader* obj;
+    
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ext, &ext_len) == FAILURE) {
+        RETURN_FALSE;
+    }
+    
+    obj = (spl_SplClassLoader*) zend_object_store_get_object(getThis() TSRMLS_CC);
+    
+    if (obj->file_ext) {
+        efree(obj->file_ext);
+        obj->file_ext = NULL;
+    }
+
+    if (ext_len) {
+        obj->file_ext = estrndup(ext, ext_len);    
+    }
+
+    obj->file_ext_len = ext_len;
+
+    RETURN_TRUE;
+} /* }}} */
+
+/* {{{ proto string SplClassLoader::getFileExtension()
+   Gets the file extension of class files in the namespace of this class loader */
+SPL_METHOD(SplClassLoader, getFileExtension)
+{
+    spl_SplClassLoader* obj = (spl_SplClassLoader*) zend_object_store_get_object(getThis() TSRMLS_CC);
+    
+    if (obj->file_ext) {
+        RETURN_STRINGL(obj->file_ext, obj->file_ext_len, 1);
+    }
+
+    RETURN_EMPTY_STRING();
+} /* }}} */
+
+/* {{{ proto mixed SplClassLoader::getPath(string $class_name)
+   Gets the path for the given class. Does not load anything. This is just a handy method */
+SPL_METHOD(SplClassLoader, getPath)
+{
+    char* cl;
+    int   cl_len = 0;
+    char  filename[MAXPATHLEN];
+    int   len = 0;
+    spl_SplClassLoader* obj;
+    
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &cl, &cl_len) == FAILURE
+        || !cl_len) {
+        return;
+    }
+    
+    obj = (spl_SplClassLoader*) zend_object_store_get_object(getThis() TSRMLS_CC);
+    
+    len = get_filename(obj, cl, cl_len, filename TSRMLS_CC);
+
+    if (len) {
+        RETURN_STRINGL(filename, --len, 1); /* cl_len > 0 and len includes '\0' */
+    }
+
+    RETURN_FALSE;
+} /* }}} */
+
+/* {{{ arginfo and function tables */
+ZEND_BEGIN_ARG_INFO(arginfo_spl_classloader___construct, 0)
+    ZEND_ARG_INFO(0, namespace)
+    ZEND_ARG_INFO(0, include_path)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_classloader_loadclass, 0, 0, 1)
+    ZEND_ARG_INFO(0, class_name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_classloader_setincludepath, 0, 0, 1)
+    ZEND_ARG_INFO(0, path)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_classloader_setfileextension, 0, 0, 1)
+    ZEND_ARG_INFO(0, file_ext)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_spl_cl_void, 0)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry spl_funcs_SplClassLoader[] = {
+    SPL_ME(SplClassLoader, __construct,      arginfo_spl_classloader___construct,   ZEND_ACC_PUBLIC)
+    SPL_ME(SplClassLoader, register,         arginfo_spl_cl_void,   ZEND_ACC_PUBLIC)
+    SPL_ME(SplClassLoader, unregister,       arginfo_spl_cl_void,   ZEND_ACC_PUBLIC)
+    SPL_ME(SplClassLoader, loadClass,        arginfo_spl_classloader_loadclass, ZEND_ACC_PUBLIC)
+    SPL_ME(SplClassLoader, setIncludePath,   arginfo_spl_classloader_setincludepath,    ZEND_ACC_PUBLIC)
+    SPL_ME(SplClassLoader, getIncludePath,   arginfo_spl_cl_void ,  ZEND_ACC_PUBLIC)
+    SPL_ME(SplClassLoader, setFileExtension, arginfo_spl_classloader_setfileextension,  ZEND_ACC_PUBLIC)
+    SPL_ME(SplClassLoader, getFileExtension, arginfo_spl_cl_void,   ZEND_ACC_PUBLIC)
+    SPL_ME(SplClassLoader, getPath,          arginfo_spl_cl_void,   ZEND_ACC_PUBLIC)
+    PHP_FE_END
+};
+
+/*const zend_function_entry spl_classloader_functions[] = {
+    {NULL, NULL, NULL}
+};*/
+/* }}} */
+
+/* {{{ PHP_M* */
+PHP_MINIT_FUNCTION(spl_classloader)
+{   
+    REGISTER_SPL_STD_CLASS_EX(SplClassLoader, spl_SplClassLoader_new, spl_funcs_SplClassLoader)
+
+    memcpy(&spl_SplClassLoader_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+    spl_SplClassLoader_handlers.clone_obj = NULL; /* no cloning! */
+
+    return SUCCESS;
+}
+
+PHP_MINFO_FUNCTION(spl_classloader)
+{
+    php_info_print_table_start ();
+    php_info_print_table_header(2, "SplClassLoader support", "enabled");
+    php_info_print_table_row   (2, "Conformance", "PSR-0");
+    php_info_print_table_end   ();
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: fdm=marker
+ * vim: noet sw=4 ts=4
+ */
Index: ext/spl/spl_classloader.h
===================================================================
--- ext/spl/spl_classloader.h	(revision 0)
+++ ext/spl/spl_classloader.h	(revision 0)
@@ -0,0 +1,40 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2009 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.01 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_01.txt                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: metagoto <runpac314@gmail.com>                              |
+   +----------------------------------------------------------------------+
+ */
+ 
+#ifndef SPL_CLASSLOADER_H
+#define SPL_CLASSLOADER_H
+
+#include "php.h"
+#include "php_spl.h"
+
+extern PHPAPI zend_class_entry *spl_ce_SplClassLoader;
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+#ifdef ZTS
+#define SPL_CLASSLD_G(v) TSRMG(spl_classloader_globals_id, zend_spl_classloader_globals *, v)
+#else
+#define SPL_CLASSLD_G(v) (spl_classloader_globals.v)
+#endif
+
+PHP_MINIT_FUNCTION(spl_classloader);
+PHP_MINFO_FUNCTION(spl_classloader);
+
+#endif /* SPL_CLASSLOADER_H */
Index: ext/spl/config.w32
===================================================================
--- ext/spl/config.w32	(revision 318369)
+++ ext/spl/config.w32	(working copy)
@@ -1,7 +1,7 @@
 // $Id$
 // vim:ft=javascript
 
-EXTENSION("spl", "php_spl.c spl_functions.c spl_engine.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c", false /*never shared */);
+EXTENSION("spl", "php_spl.c spl_functions.c spl_engine.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c spl_classloader.c", false /*never shared */);
 AC_DEFINE('HAVE_SPL', 1);
 PHP_SPL="yes";
-PHP_INSTALL_HEADERS("ext/spl", "php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h");
+PHP_INSTALL_HEADERS("ext/spl", "php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h spl_classloader.h");
Index: ext/spl/config.m4
===================================================================
--- ext/spl/config.m4	(revision 318369)
+++ ext/spl/config.m4	(working copy)
@@ -1,6 +1,5 @@
 dnl $Id$
 dnl config.m4 for extension SPL
-
   AC_MSG_CHECKING(whether zend_object_value is packed)
   old_CPPFLAGS=$CPPFLAGS
   CPPFLAGS="$INCLUDES -I$abs_srcdir $CPPFLAGS"
@@ -22,6 +21,6 @@
   CPPFLAGS=$old_CPPFLAGS
   AC_DEFINE_UNQUOTED(HAVE_PACKED_OBJECT_VALUE, $ac_result, [Whether struct _zend_object_value is packed])
   AC_DEFINE(HAVE_SPL, 1, [Whether you want SPL (Standard PHP Library) support]) 
-  PHP_NEW_EXTENSION(spl, php_spl.c spl_functions.c spl_engine.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c, no)
-  PHP_INSTALL_HEADERS([ext/spl], [php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h])
+  PHP_NEW_EXTENSION(spl, php_spl.c spl_functions.c spl_engine.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c spl_classloader.c, no)
+  PHP_INSTALL_HEADERS([ext/spl], [php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h spl_classloader.h])
   PHP_ADD_EXTENSION_DEP(spl, pcre, true)
Index: ext/spl/php_spl.c
===================================================================
--- ext/spl/php_spl.c	(revision 318369)
+++ ext/spl/php_spl.c	(working copy)
@@ -37,6 +37,7 @@
 #include "spl_dllist.h"
 #include "spl_fixedarray.h"
 #include "spl_heap.h"
+#include "spl_classloader.h"
 #include "zend_exceptions.h"
 #include "zend_interfaces.h"
 #include "ext/standard/php_rand.h"
@@ -255,6 +256,7 @@
 	SPL_ADD_CLASS(SplTempFileObject, z_list, sub, allow, ce_flags); \
 	SPL_ADD_CLASS(UnderflowException, z_list, sub, allow, ce_flags); \
 	SPL_ADD_CLASS(UnexpectedValueException, z_list, sub, allow, ce_flags); \
+	SPL_ADD_CLASS(SplClassLoader, z_list, sub, allow, ce_flags); \
 
 /* {{{ proto array spl_classes()
  Return an array containing the names of all clsses and interfaces defined in SPL */
@@ -1038,6 +1040,7 @@
 	PHP_MINIT(spl_heap)(INIT_FUNC_ARGS_PASSTHRU);
 	PHP_MINIT(spl_fixedarray)(INIT_FUNC_ARGS_PASSTHRU);
 	PHP_MINIT(spl_observer)(INIT_FUNC_ARGS_PASSTHRU);
+	PHP_MINIT(spl_classloader)(INIT_FUNC_ARGS_PASSTHRU);
 
 	return SUCCESS;
 }
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 15:01:29 2024 UTC