Author: ryat # www.wolvez.org
Team: http://www.80vul.com
Date: 2009-04-13
I. Description
See the description of this function in the manual:
Spl_autoload
(PHP 5> = 5.1.2)
Spl_autoload-Default implementation for _ autoload ()
Void spl_autoload (string $ class_name [, string $ file_extensions = spl_autoload_extensions ()])
This function is intended to be used as a default implementation for _ autoload (). if nothing else is specified and autoload_register () is called without any parameters then this functions will be used for any later call to _ autoload ().
We can see from the description that this function is used to replace the _ autoload method in the class.
Ii. Code Analysis
Php source code of spl_autoload:
// Php_spl.c
PHP_FUNCTION (spl_autoload)
{
...
Char * class_name, * lc_name, * file_exts = SPL_G (autoload_extensions );
Int class_name_len, file_exts_len = SPL_G (autoload_extensions_len), found = 0;
Char * copy, * pos1, * pos2;
...
If (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC, "s | s", & class_name, & class_name_len, & file_exts, & file_exts_len) = FAILURE ){
RETURN_FALSE;
}
If (file_exts = NULL) {/* autoload_extensions is not intialed, set to defaults */
Copy = pos1 = estrndup (SPL_DEFAULT_FILE_EXTENSIONS, sizeof (SPL_DEFAULT_FILE_EXTENSIONS)-1 );
// If the file_extensions parameter is not specified, set file_extensions to. inc or. php.
} Else {
Copy = pos1 = estrndup (file_exts, file_exts_len );
}
Lc_name = zend_str_tolower_dup (class_name, class_name_len );
While (pos1 & * pos1 &&! EG (exception )){
...
If (spl_autoload (class_name, lc_name, class_name_len, pos1 TSRMLS_CC )){
...
Static int spl_autoload (const char * class_name, const char * lc_name, int class_name_len, const char * file_extension TSRMLS_DC )/*{{{*/
{
...
Class_file_len = spprintf (& class_file, 0, "% s", lc_name, file_extension );
// Merge class_name and file_extensions
Ret = php_stream_open_for_zend_ex (class_file, & file_handle, ENFORCE_SAFE_MODE | USE_PATH | STREAM_OPEN_FOR_INCLUDE TSRMLS_CC );
// Open the specified file
...
If (ret = SUCCESS ){
If (! File_handle.opened_path ){
File_handle.opened_path = estrndup (class_file, class_file_len );
}
If (zend_hash_add (& EG (included_files), file_handle.opened_path, strlen (file_handle.opened_path) + 1, (void *) & dummy, sizeof (int), NULL) = SUCCESS ){
New_op_array = zend_compile_file (& file_handle, ZEND_REQUIRE TSRMLS_CC );
// Compile the file into an opcode
...
} Else {
New_op_array = NULL;
...
}
If (new_op_array ){
...
Zend_execute (new_op_array TSRMLS_CC );
// Execute opcode :)
As you can see, this function can completely replace the include/require function. [of course, if you are familiar with the use of the _ autoload method, you may soon realize this :)]
Iii. Test code
PoC:
// Test. php
<? Php
Spl_autoload (info,. txt );
// Info.txt
<? Php
Phpinfo ();