2003-05-02 07:28:28 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-09 02:17:39 +08:00
| PHP Version 5 |
2003-05-02 07:28:28 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 20:51:34 +08:00
| Copyright ( c ) 1997 - 2006 The PHP Group |
2003-05-02 07:28:28 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 20:51:34 +08:00
| This source file is subject to version 3.01 of the PHP license , |
2003-05-02 07:28:28 +08:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-13 03:30:54 +08:00
| available through the world - wide - web at the following url : |
2006-01-01 20:51:34 +08:00
| http : //www.php.net/license/3_01.txt |
2003-05-02 07:28:28 +08:00
| 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 : Marcus Boerger < helly @ php . net > |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2004-01-21 04:59:45 +08:00
/* $Id$ */
2003-05-02 07:28:28 +08:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "php.h"
# include "php_ini.h"
# include "ext/standard/info.h"
# include "php_spl.h"
# include "spl_functions.h"
# include "spl_engine.h"
# include "spl_array.h"
2003-11-09 22:05:36 +08:00
# include "spl_directory.h"
# include "spl_iterators.h"
2004-01-18 23:33:38 +08:00
# include "spl_sxe.h"
2004-11-01 23:50:25 +08:00
# include "spl_exceptions.h"
2005-02-09 04:42:48 +08:00
# include "spl_observer.h"
2005-03-02 09:14:41 +08:00
# include "zend_exceptions.h"
# include "zend_interfaces.h"
2003-05-02 07:28:28 +08:00
# ifdef COMPILE_DL_SPL
ZEND_GET_MODULE ( spl )
# endif
ZEND_DECLARE_MODULE_GLOBALS ( spl )
/* {{{ spl_functions_none
*/
2005-12-06 10:00:14 +08:00
zend_function_entry spl_functions_none [ ] = {
2003-05-02 07:28:28 +08:00
{ NULL , NULL , NULL }
} ;
/* }}} */
2006-06-16 02:33:09 +08:00
/* {{{ PHP_GINIT_FUNCTION
2003-05-02 07:28:28 +08:00
*/
2006-06-16 02:33:09 +08:00
static PHP_GINIT_FUNCTION ( spl )
2003-05-02 07:28:28 +08:00
{
2005-04-01 01:17:38 +08:00
spl_globals - > autoload_extensions = NULL ;
2005-03-02 09:14:41 +08:00
spl_globals - > autoload_functions = NULL ;
2003-05-02 07:28:28 +08:00
}
/* }}} */
2005-04-06 23:16:45 +08:00
static zend_class_entry * spl_find_ce_by_name ( char * name , int len , zend_bool autoload TSRMLS_DC )
{
zend_class_entry * * ce ;
int found ;
2005-09-15 11:33:04 +08:00
2005-04-06 23:16:45 +08:00
if ( ! autoload ) {
char * lc_name ;
lc_name = do_alloca ( len + 1 ) ;
zend_str_tolower_copy ( lc_name , name , len ) ;
found = zend_hash_find ( EG ( class_table ) , lc_name , len + 1 , ( void * * ) & ce ) ;
free_alloca ( lc_name ) ;
} else {
found = zend_lookup_class ( name , len , & ce TSRMLS_CC ) ;
}
if ( found ! = SUCCESS ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Class %s does not exist%s " , name , autoload ? " and could not be loaded " : " " ) ;
return NULL ;
}
return * ce ;
}
2005-12-18 23:40:34 +08:00
/* {{{ proto array class_parents(object instance)
2005-02-14 02:14:34 +08:00
Return an array containing the names of all parent classes */
2003-05-02 07:28:28 +08:00
PHP_FUNCTION ( class_parents )
{
zval * obj ;
2005-04-06 23:16:45 +08:00
zend_class_entry * parent_class , * ce ;
zend_bool autoload = 1 ;
2003-05-02 07:28:28 +08:00
2005-04-06 23:16:45 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " z|b " , & obj , & autoload ) = = FAILURE ) {
2003-05-02 07:28:28 +08:00
RETURN_FALSE ;
}
2005-04-06 23:16:45 +08:00
if ( Z_TYPE_P ( obj ) ! = IS_OBJECT & & Z_TYPE_P ( obj ) ! = IS_STRING ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " object or string expected " ) ;
RETURN_FALSE ;
}
if ( Z_TYPE_P ( obj ) = = IS_STRING ) {
if ( NULL = = ( ce = spl_find_ce_by_name ( Z_STRVAL_P ( obj ) , Z_STRLEN_P ( obj ) , autoload TSRMLS_CC ) ) ) {
RETURN_FALSE ;
}
} else {
ce = Z_OBJCE_P ( obj ) ;
}
2003-05-02 07:28:28 +08:00
array_init ( return_value ) ;
2005-04-06 23:16:45 +08:00
parent_class = ce - > parent ;
2003-05-02 07:28:28 +08:00
while ( parent_class ) {
2004-01-26 01:30:19 +08:00
spl_add_class_name ( return_value , parent_class , 0 , 0 TSRMLS_CC ) ;
2003-05-02 07:28:28 +08:00
parent_class = parent_class - > parent ;
}
}
/* }}} */
2005-04-06 23:16:45 +08:00
/* {{{ proto array class_implements(mixed what [, bool autoload ])
2005-02-14 02:14:34 +08:00
Return all classes and interfaces implemented by SPL */
2003-05-02 07:28:28 +08:00
PHP_FUNCTION ( class_implements )
{
zval * obj ;
2005-04-06 23:16:45 +08:00
zend_bool autoload = 1 ;
zend_class_entry * ce ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " z|b " , & obj , & autoload ) = = FAILURE ) {
2003-05-02 07:28:28 +08:00
RETURN_FALSE ;
}
2005-04-06 23:16:45 +08:00
if ( Z_TYPE_P ( obj ) ! = IS_OBJECT & & Z_TYPE_P ( obj ) ! = IS_STRING ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " object or string expected " ) ;
RETURN_FALSE ;
}
if ( Z_TYPE_P ( obj ) = = IS_STRING ) {
if ( NULL = = ( ce = spl_find_ce_by_name ( Z_STRVAL_P ( obj ) , Z_STRLEN_P ( obj ) , autoload TSRMLS_CC ) ) ) {
RETURN_FALSE ;
}
} else {
ce = Z_OBJCE_P ( obj ) ;
}
2003-05-02 07:28:28 +08:00
array_init ( return_value ) ;
2005-04-06 23:16:45 +08:00
spl_add_interfaces ( return_value , ce , 1 , ZEND_ACC_INTERFACE TSRMLS_CC ) ;
2003-05-02 07:28:28 +08:00
}
/* }}} */
2004-01-26 01:30:19 +08:00
# define SPL_ADD_CLASS(class_name, z_list, sub, allow, ce_flags) \
spl_add_classes ( & spl_ce_ # # class_name , z_list , sub , allow , ce_flags TSRMLS_CC )
# define SPL_LIST_CLASSES(z_list, sub, allow, ce_flags) \
2004-11-01 08:26:59 +08:00
SPL_ADD_CLASS ( AppendIterator , z_list , sub , allow , ce_flags ) ; \
2004-01-26 01:30:19 +08:00
SPL_ADD_CLASS ( ArrayIterator , z_list , sub , allow , ce_flags ) ; \
2005-08-24 18:17:43 +08:00
SPL_ADD_CLASS ( ArrayObject , z_list , sub , allow , ce_flags ) ; \
2004-11-02 01:39:59 +08:00
SPL_ADD_CLASS ( BadFunctionCallException , z_list , sub , allow , ce_flags ) ; \
2005-08-02 10:20:01 +08:00
SPL_ADD_CLASS ( BadMethodCallException , z_list , sub , allow , ce_flags ) ; \
2004-01-26 01:30:19 +08:00
SPL_ADD_CLASS ( CachingIterator , z_list , sub , allow , ce_flags ) ; \
2004-11-01 18:45:54 +08:00
SPL_ADD_CLASS ( Countable , z_list , sub , allow , ce_flags ) ; \
2004-01-26 01:30:19 +08:00
SPL_ADD_CLASS ( DirectoryIterator , z_list , sub , allow , ce_flags ) ; \
2004-11-01 23:50:25 +08:00
SPL_ADD_CLASS ( DomainException , z_list , sub , allow , ce_flags ) ; \
2004-11-01 04:59:39 +08:00
SPL_ADD_CLASS ( EmptyIterator , z_list , sub , allow , ce_flags ) ; \
2004-01-26 01:30:19 +08:00
SPL_ADD_CLASS ( FilterIterator , z_list , sub , allow , ce_flags ) ; \
2004-11-01 03:49:18 +08:00
SPL_ADD_CLASS ( InfiniteIterator , z_list , sub , allow , ce_flags ) ; \
2004-11-01 23:50:25 +08:00
SPL_ADD_CLASS ( InvalidArgumentException , z_list , sub , allow , ce_flags ) ; \
2004-11-01 02:43:00 +08:00
SPL_ADD_CLASS ( IteratorIterator , z_list , sub , allow , ce_flags ) ; \
2004-11-01 23:50:25 +08:00
SPL_ADD_CLASS ( LengthException , z_list , sub , allow , ce_flags ) ; \
2004-01-26 01:30:19 +08:00
SPL_ADD_CLASS ( LimitIterator , z_list , sub , allow , ce_flags ) ; \
2004-11-01 23:50:25 +08:00
SPL_ADD_CLASS ( LogicException , z_list , sub , allow , ce_flags ) ; \
2004-11-01 02:43:00 +08:00
SPL_ADD_CLASS ( NoRewindIterator , z_list , sub , allow , ce_flags ) ; \
2004-10-30 04:12:57 +08:00
SPL_ADD_CLASS ( OuterIterator , z_list , sub , allow , ce_flags ) ; \
2004-11-01 23:50:25 +08:00
SPL_ADD_CLASS ( OutOfBoundsException , z_list , sub , allow , ce_flags ) ; \
2005-08-24 18:17:43 +08:00
SPL_ADD_CLASS ( OutOfRangeException , z_list , sub , allow , ce_flags ) ; \
2004-11-01 23:50:25 +08:00
SPL_ADD_CLASS ( OverflowException , z_list , sub , allow , ce_flags ) ; \
2004-01-26 01:30:19 +08:00
SPL_ADD_CLASS ( ParentIterator , z_list , sub , allow , ce_flags ) ; \
2004-11-01 23:50:25 +08:00
SPL_ADD_CLASS ( RangeException , z_list , sub , allow , ce_flags ) ; \
2005-09-19 01:15:04 +08:00
SPL_ADD_CLASS ( RecursiveArrayIterator , z_list , sub , allow , ce_flags ) ; \
SPL_ADD_CLASS ( RecursiveCachingIterator , z_list , sub , allow , ce_flags ) ; \
2004-01-26 01:30:19 +08:00
SPL_ADD_CLASS ( RecursiveDirectoryIterator , z_list , sub , allow , ce_flags ) ; \
2005-09-15 11:33:04 +08:00
SPL_ADD_CLASS ( RecursiveFilterIterator , z_list , sub , allow , ce_flags ) ; \
2004-01-26 01:30:19 +08:00
SPL_ADD_CLASS ( RecursiveIterator , z_list , sub , allow , ce_flags ) ; \
SPL_ADD_CLASS ( RecursiveIteratorIterator , z_list , sub , allow , ce_flags ) ; \
2006-06-04 18:47:22 +08:00
SPL_ADD_CLASS ( RecursiveRegexIterator , z_list , sub , allow , ce_flags ) ; \
SPL_ADD_CLASS ( RegexIterator , z_list , sub , allow , ce_flags ) ; \
2004-11-01 23:50:25 +08:00
SPL_ADD_CLASS ( RuntimeException , z_list , sub , allow , ce_flags ) ; \
2004-01-26 01:30:19 +08:00
SPL_ADD_CLASS ( SeekableIterator , z_list , sub , allow , ce_flags ) ; \
SPL_ADD_CLASS ( SimpleXMLIterator , z_list , sub , allow , ce_flags ) ; \
2005-11-29 11:33:59 +08:00
SPL_ADD_CLASS ( SplFileInfo , z_list , sub , allow , ce_flags ) ; \
2005-09-15 22:08:16 +08:00
SPL_ADD_CLASS ( SplFileObject , z_list , sub , allow , ce_flags ) ; \
2005-09-15 11:33:04 +08:00
SPL_ADD_CLASS ( SplObjectStorage , z_list , sub , allow , ce_flags ) ; \
SPL_ADD_CLASS ( SplObserver , z_list , sub , allow , ce_flags ) ; \
SPL_ADD_CLASS ( SplSubject , z_list , sub , allow , ce_flags ) ; \
2005-12-17 06:29:02 +08:00
SPL_ADD_CLASS ( SplTempFileObject , z_list , sub , allow , ce_flags ) ; \
2004-11-01 23:50:25 +08:00
SPL_ADD_CLASS ( UnderflowException , z_list , sub , allow , ce_flags ) ; \
2005-08-24 18:17:43 +08:00
SPL_ADD_CLASS ( UnexpectedValueException , z_list , sub , allow , ce_flags ) ; \
2003-06-05 04:54:48 +08:00
2005-02-14 02:14:34 +08:00
/* {{{ proto array spl_classes()
Return an array containing the names of all clsses and interfaces defined in SPL */
2003-05-02 07:28:28 +08:00
PHP_FUNCTION ( spl_classes )
{
array_init ( return_value ) ;
2004-01-26 01:30:19 +08:00
SPL_LIST_CLASSES ( return_value , 0 , 0 , 0 )
}
/* }}} */
2003-06-05 04:54:48 +08:00
2005-03-02 09:14:41 +08:00
int spl_autoload ( const char * class_name , const char * lc_name , int class_name_len , const char * file_extension TSRMLS_DC ) /* { { { */
{
char * class_file ;
int class_file_len ;
int dummy = 1 ;
zend_file_handle file_handle ;
zend_op_array * new_op_array ;
zval * result = NULL ;
2005-04-05 17:24:53 +08:00
2005-03-02 09:14:41 +08:00
class_file_len = spprintf ( & class_file , 0 , " %s%s " , lc_name , file_extension ) ;
if ( zend_stream_open ( class_file , & file_handle TSRMLS_CC ) = = 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 ) ;
zend_destroy_file_handle ( & file_handle TSRMLS_CC ) ;
} else {
new_op_array = NULL ;
zend_file_handle_dtor ( & file_handle ) ;
}
if ( new_op_array ) {
EG ( return_value_ptr_ptr ) = & result ;
EG ( active_op_array ) = new_op_array ;
zend_execute ( new_op_array TSRMLS_CC ) ;
destroy_op_array ( new_op_array TSRMLS_CC ) ;
efree ( new_op_array ) ;
if ( ! EG ( exception ) ) {
if ( EG ( return_value_ptr_ptr ) ) {
zval_ptr_dtor ( EG ( return_value_ptr_ptr ) ) ;
}
}
efree ( class_file ) ;
return zend_hash_exists ( EG ( class_table ) , ( char * ) lc_name , class_name_len + 1 ) ;
}
}
efree ( class_file ) ;
return 0 ;
} /* }}} */
2005-12-18 23:40:34 +08:00
/* {{{ proto void spl_autoload(string class_name [, string file_extensions])
2005-03-02 09:14:41 +08:00
Default implementation for __autoload ( ) */
PHP_FUNCTION ( spl_autoload )
{
char * class_name , * lc_name , * file_exts ;
int class_name_len , file_exts_len , found = 0 ;
char * copy , * pos1 , * pos2 ;
zval * * original_return_value = EG ( return_value_ptr_ptr ) ;
zend_op * * original_opline_ptr = EG ( opline_ptr ) ;
zend_op_array * original_active_op_array = EG ( active_op_array ) ;
zend_function_state * original_function_state_ptr = EG ( function_state_ptr ) ;
zval err_mode ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s|s " , & class_name , & class_name_len , & file_exts , & file_exts_len ) = = FAILURE ) {
RETURN_FALSE ;
}
ZVAL_LONG ( & err_mode , EG ( error_reporting ) ) ;
php_alter_ini_entry ( " error_reporting " , sizeof ( " error_reporting " ) , " 0 " , 1 , ZEND_INI_USER , ZEND_INI_STAGE_RUNTIME ) ;
copy = pos1 = estrdup ( ZEND_NUM_ARGS ( ) > 1 ? file_exts : SPL_G ( autoload_extensions ) ) ;
lc_name = zend_str_tolower_dup ( class_name , class_name_len ) ;
while ( pos1 & & * pos1 & & ! EG ( exception ) ) {
EG ( return_value_ptr_ptr ) = original_return_value ;
EG ( opline_ptr ) = original_opline_ptr ;
EG ( active_op_array ) = original_active_op_array ;
EG ( function_state_ptr ) = original_function_state_ptr ;
pos2 = strchr ( pos1 , ' , ' ) ;
if ( pos2 ) * pos2 = ' \0 ' ;
if ( spl_autoload ( class_name , lc_name , class_name_len , pos1 TSRMLS_CC ) ) {
found = 1 ;
break ; /* loaded */
}
pos1 = pos2 ? pos2 + 1 : NULL ;
}
efree ( lc_name ) ;
if ( copy ) {
efree ( copy ) ;
}
if ( ! EG ( error_reporting ) & & Z_LVAL ( err_mode ) ! = EG ( error_reporting ) ) {
convert_to_string ( & err_mode ) ;
zend_alter_ini_entry ( " error_reporting " , sizeof ( " error_reporting " ) , Z_STRVAL ( err_mode ) , Z_STRLEN ( err_mode ) , ZEND_INI_USER , ZEND_INI_STAGE_RUNTIME ) ;
zendi_zval_dtor ( err_mode ) ;
}
EG ( return_value_ptr_ptr ) = original_return_value ;
EG ( opline_ptr ) = original_opline_ptr ;
EG ( active_op_array ) = original_active_op_array ;
EG ( function_state_ptr ) = original_function_state_ptr ;
if ( ! found ) {
zend_throw_exception_ex ( spl_ce_LogicException , 0 TSRMLS_CC , " Class %s could not be loaded " , class_name ) ;
}
} /* }}} */
2005-12-18 23:46:46 +08:00
/* {{{ proto string spl_autoload_extensions([string file_extensions])
2005-03-03 04:59:06 +08:00
Register and return default file extensions for spl_autoload */
2005-03-02 09:14:41 +08:00
PHP_FUNCTION ( spl_autoload_extensions )
{
char * file_exts ;
int file_exts_len ;
2005-03-03 04:59:06 +08:00
if ( ZEND_NUM_ARGS ( ) > 0 ) {
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & file_exts , & file_exts_len ) = = FAILURE ) {
return ;
}
if ( SPL_G ( autoload_extensions ) ) {
efree ( SPL_G ( autoload_extensions ) ) ;
}
SPL_G ( autoload_extensions ) = estrdup ( file_exts ) ;
2005-03-02 09:14:41 +08:00
}
2005-03-03 04:59:06 +08:00
RETURN_STRING ( SPL_G ( autoload_extensions ) , 1 ) ;
2005-03-02 09:14:41 +08:00
} /* }}} */
2005-09-26 02:04:35 +08:00
typedef struct {
zend_function * func_ptr ;
zval * obj ;
zend_class_entry * ce ;
} autoload_func_info ;
static void autoload_func_info_dtor ( autoload_func_info * alfi )
{
if ( alfi - > obj ) {
zval_ptr_dtor ( & alfi - > obj ) ;
}
}
2005-12-18 23:40:34 +08:00
/* {{{ proto void spl_autoload_call(string class_name)
2005-03-02 09:14:41 +08:00
Try all registerd autoload function to load the requested class */
PHP_FUNCTION ( spl_autoload_call )
{
2006-02-13 00:44:36 +08:00
zval * class_name , * retval = NULL ;
2005-12-22 04:05:24 +08:00
int class_name_len ;
2005-03-02 09:14:41 +08:00
char * func_name , * lc_name ;
2005-10-27 06:47:23 +08:00
uint func_name_len ;
ulong dummy ;
2005-03-02 09:14:41 +08:00
HashPosition function_pos ;
2005-09-26 02:04:35 +08:00
autoload_func_info * alfi ;
2005-03-02 09:14:41 +08:00
2006-02-13 00:44:36 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " z " , & class_name ) = = FAILURE | | Z_TYPE_P ( class_name ) ! = IS_STRING ) {
2005-03-02 09:14:41 +08:00
return ;
}
if ( SPL_G ( autoload_functions ) ) {
2006-02-13 00:44:36 +08:00
class_name_len = Z_STRLEN_P ( class_name ) ;
lc_name = zend_str_tolower_dup ( Z_STRVAL_P ( class_name ) , class_name_len ) ;
2005-03-02 09:14:41 +08:00
zend_hash_internal_pointer_reset_ex ( SPL_G ( autoload_functions ) , & function_pos ) ;
2005-04-05 17:24:53 +08:00
while ( zend_hash_has_more_elements_ex ( SPL_G ( autoload_functions ) , & function_pos ) = = SUCCESS & & ! EG ( exception ) ) {
2005-03-02 09:14:41 +08:00
zend_hash_get_current_key_ex ( SPL_G ( autoload_functions ) , & func_name , & func_name_len , & dummy , 0 , & function_pos ) ;
2005-09-26 02:04:35 +08:00
zend_hash_get_current_data_ex ( SPL_G ( autoload_functions ) , ( void * * ) & alfi , & function_pos ) ;
2006-02-13 00:44:36 +08:00
zend_call_method ( alfi - > obj ? & alfi - > obj : NULL , alfi - > ce , & alfi - > func_ptr , func_name , func_name_len , & retval , 1 , class_name , NULL TSRMLS_CC ) ;
2005-03-02 09:14:41 +08:00
if ( retval ) {
zval_ptr_dtor ( & retval ) ;
}
2005-12-22 04:05:24 +08:00
if ( zend_hash_exists ( EG ( class_table ) , lc_name , class_name_len + 1 ) ) {
2005-03-02 09:14:41 +08:00
break ;
}
zend_hash_move_forward_ex ( SPL_G ( autoload_functions ) , & function_pos ) ;
}
efree ( lc_name ) ;
} else {
/* do not use or overwrite &EG(autoload_func) here */
2006-02-13 00:44:36 +08:00
zend_call_method_with_1_params ( NULL , NULL , NULL , " spl_autoload " , NULL , class_name ) ;
2005-03-02 09:14:41 +08:00
}
} /* }}} */
2006-03-24 03:55:16 +08:00
/* {{{ proto bool spl_autoload_register([mixed autoload_function = "spl_autoload" [, throw = true]])
2005-03-03 08:20:57 +08:00
Register given function as __autoload ( ) implementation */
2005-03-02 09:14:41 +08:00
PHP_FUNCTION ( spl_autoload_register )
{
2005-09-26 02:04:35 +08:00
char * func_name ;
int func_name_len ;
char * lc_name = NULL ;
2005-07-29 04:59:44 +08:00
zval * zcallable = NULL ;
2005-05-13 05:23:56 +08:00
zend_bool do_throw = 1 ;
2005-09-26 02:04:35 +08:00
zend_function * spl_func_ptr ;
autoload_func_info alfi ;
zval * * obj_ptr ;
2005-03-02 09:14:41 +08:00
2005-11-03 04:31:01 +08:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " |zb " , & zcallable , & do_throw ) = = FAILURE ) {
return ;
}
if ( ZEND_NUM_ARGS ( ) ) {
if ( Z_TYPE_P ( zcallable ) = = IS_STRING ) {
if ( Z_STRLEN_P ( zcallable ) = = sizeof ( " spl_autoload_call " ) - 1 ) {
2005-12-17 07:58:38 +08:00
if ( ! zend_binary_strcasecmp ( Z_STRVAL_P ( zcallable ) , sizeof ( " spl_autoload_call " ) , " spl_autoload_call " , sizeof ( " spl_autoload_call " ) ) ) {
2005-11-03 04:31:01 +08:00
if ( do_throw ) {
2005-11-07 21:08:24 +08:00
zend_throw_exception_ex ( spl_ce_LogicException , 0 TSRMLS_CC , " Function spl_autoload_call() cannot be registered " ) ;
2005-11-03 04:31:01 +08:00
}
2006-03-24 03:55:16 +08:00
RETURN_FALSE ;
2005-11-03 04:31:01 +08:00
}
}
2005-07-29 04:59:44 +08:00
}
2005-11-03 04:31:01 +08:00
2005-12-17 06:17:32 +08:00
if ( ! zend_is_callable_ex ( zcallable , IS_CALLABLE_STRICT , & func_name , & func_name_len , & alfi . ce , & alfi . func_ptr , & obj_ptr TSRMLS_CC ) ) {
2005-11-03 04:31:01 +08:00
if ( Z_TYPE_P ( zcallable ) = = IS_ARRAY ) {
2005-11-04 05:28:43 +08:00
if ( ! obj_ptr & & alfi . func_ptr & & ! ( alfi . func_ptr - > common . fn_flags & ZEND_ACC_STATIC ) ) {
2005-11-03 04:31:01 +08:00
if ( do_throw ) {
zend_throw_exception_ex ( spl_ce_LogicException , 0 TSRMLS_CC , " Passed array specifies a non static method but no object " ) ;
}
efree ( func_name ) ;
2006-03-24 03:55:16 +08:00
RETURN_FALSE ;
2005-11-03 04:31:01 +08:00
}
else if ( do_throw ) {
2005-12-17 06:17:32 +08:00
zend_throw_exception_ex ( spl_ce_LogicException , 0 TSRMLS_CC , " Passed array does not specify %s %smethod " , alfi . func_ptr ? " a callable " : " an existing " , ! obj_ptr ? " static " : " " ) ;
2005-11-03 04:31:01 +08:00
}
efree ( func_name ) ;
2006-03-24 03:55:16 +08:00
RETURN_FALSE ;
2005-11-03 04:31:01 +08:00
} else if ( Z_TYPE_P ( zcallable ) = = IS_STRING ) {
if ( do_throw ) {
2005-12-17 06:17:32 +08:00
zend_throw_exception_ex ( spl_ce_LogicException , 0 TSRMLS_CC , " Function '%s' not %s " , func_name , alfi . func_ptr ? " callable " : " found " ) ;
2005-11-03 04:31:01 +08:00
}
efree ( func_name ) ;
2006-03-24 03:55:16 +08:00
RETURN_FALSE ;
2005-11-03 04:31:01 +08:00
} else {
if ( do_throw ) {
2005-12-17 06:38:17 +08:00
zend_throw_exception_ex ( spl_ce_LogicException , 0 TSRMLS_CC , " Illegal value passed " ) ;
2005-11-03 04:31:01 +08:00
}
efree ( func_name ) ;
2006-03-24 03:55:16 +08:00
RETURN_FALSE ;
2005-07-29 04:59:44 +08:00
}
}
2005-11-03 04:31:01 +08:00
2005-07-29 04:59:44 +08:00
lc_name = do_alloca ( func_name_len + 1 ) ;
zend_str_tolower_copy ( lc_name , func_name , func_name_len ) ;
2005-09-26 02:04:35 +08:00
efree ( func_name ) ;
if ( obj_ptr & & ! ( alfi . func_ptr - > common . fn_flags & ZEND_ACC_STATIC ) ) {
alfi . obj = * obj_ptr ;
alfi . obj - > refcount + + ;
} else {
alfi . obj = NULL ;
}
2006-03-24 03:55:16 +08:00
2005-03-02 09:14:41 +08:00
if ( ! SPL_G ( autoload_functions ) ) {
ALLOC_HASHTABLE ( SPL_G ( autoload_functions ) ) ;
2005-09-26 02:04:35 +08:00
zend_hash_init ( SPL_G ( autoload_functions ) , 1 , NULL , ( dtor_func_t ) autoload_func_info_dtor , 0 ) ;
2005-03-02 09:14:41 +08:00
}
2005-03-03 08:20:57 +08:00
zend_hash_find ( EG ( function_table ) , " spl_autoload " , sizeof ( " spl_autoload " ) , ( void * * ) & spl_func_ptr ) ;
if ( EG ( autoload_func ) = = spl_func_ptr ) { /* registered already, so we insert that first */
2005-11-04 05:59:13 +08:00
autoload_func_info spl_alfi ;
spl_alfi . func_ptr = spl_func_ptr ;
spl_alfi . obj = NULL ;
spl_alfi . ce = NULL ;
2005-09-26 02:04:35 +08:00
zend_hash_add ( SPL_G ( autoload_functions ) , " spl_autoload " , sizeof ( " spl_autoload " ) , & spl_alfi , sizeof ( autoload_func_info ) , NULL ) ;
2005-03-03 08:20:57 +08:00
}
2005-09-26 02:04:35 +08:00
zend_hash_add ( SPL_G ( autoload_functions ) , lc_name , func_name_len + 1 , & alfi . func_ptr , sizeof ( autoload_func_info ) , NULL ) ;
2005-03-02 09:14:41 +08:00
free_alloca ( lc_name ) ;
}
if ( SPL_G ( autoload_functions ) ) {
zend_hash_find ( EG ( function_table ) , " spl_autoload_call " , sizeof ( " spl_autoload_call " ) , ( void * * ) & EG ( autoload_func ) ) ;
} else {
zend_hash_find ( EG ( function_table ) , " spl_autoload " , sizeof ( " spl_autoload " ) , ( void * * ) & EG ( autoload_func ) ) ;
}
2006-03-24 03:55:16 +08:00
RETURN_TRUE ;
2005-03-02 09:14:41 +08:00
} /* }}} */
2006-03-24 03:55:16 +08:00
/* {{{ proto bool spl_autoload_unregister(mixed autoload_function)
2005-03-03 08:20:57 +08:00
Unregister given function as __autoload ( ) implementation */
PHP_FUNCTION ( spl_autoload_unregister )
{
2006-03-24 03:55:16 +08:00
char * func_name ;
int func_name_len ;
zval * zcallable ;
int success = FAILURE ;
2005-03-03 08:20:57 +08:00
zend_function * spl_func_ptr ;
2006-03-24 03:55:16 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " z " , & zcallable ) = = FAILURE ) {
2005-03-03 08:20:57 +08:00
return ;
}
2006-03-24 03:55:16 +08:00
if ( ! zend_is_callable_ex ( zcallable , IS_CALLABLE_CHECK_SYNTAX_ONLY , & func_name , & func_name_len , NULL , NULL , NULL TSRMLS_CC ) ) {
if ( func_name ) {
efree ( func_name ) ;
}
RETURN_FALSE ;
}
zend_str_tolower ( func_name , func_name_len ) ;
2005-03-03 08:20:57 +08:00
if ( SPL_G ( autoload_functions ) ) {
2006-03-24 03:55:16 +08:00
if ( func_name_len = = sizeof ( " spl_autoload_call " ) - 1 & & ! strcmp ( func_name , " spl_autoload_call " ) ) {
2005-03-03 08:20:57 +08:00
/* remove all */
zend_hash_destroy ( SPL_G ( autoload_functions ) ) ;
FREE_HASHTABLE ( SPL_G ( autoload_functions ) ) ;
SPL_G ( autoload_functions ) = NULL ;
EG ( autoload_func ) = NULL ;
success = SUCCESS ;
} else {
/* remove specific */
2006-03-24 03:55:16 +08:00
success = zend_hash_del ( SPL_G ( autoload_functions ) , func_name , func_name_len + 1 ) ;
2005-03-03 08:20:57 +08:00
}
2006-03-24 03:55:16 +08:00
} else if ( func_name_len = = sizeof ( " spl_autoload " ) - 1 & & ! strcmp ( func_name , " spl_autoload " ) ) {
2005-03-03 08:20:57 +08:00
/* register single spl_autoload() */
zend_hash_find ( EG ( function_table ) , " spl_autoload " , sizeof ( " spl_autoload " ) , ( void * * ) & spl_func_ptr ) ;
if ( EG ( autoload_func ) = = spl_func_ptr ) {
success = SUCCESS ;
EG ( autoload_func ) = NULL ;
}
}
2006-03-24 03:55:16 +08:00
efree ( func_name ) ;
2005-03-03 08:20:57 +08:00
RETURN_BOOL ( success = = SUCCESS ) ;
} /* }}} */
2005-12-18 23:40:34 +08:00
/* {{{ proto false|array spl_autoload_functions()
2005-03-03 08:20:57 +08:00
Return all registered __autoload ( ) functionns */
PHP_FUNCTION ( spl_autoload_functions )
{
zend_function * fptr , * * func_ptr_ptr ;
HashPosition function_pos ;
if ( ! EG ( autoload_func ) ) {
if ( zend_hash_find ( EG ( function_table ) , ZEND_AUTOLOAD_FUNC_NAME , sizeof ( ZEND_AUTOLOAD_FUNC_NAME ) , ( void * * ) & fptr ) = = SUCCESS ) {
array_init ( return_value ) ;
add_next_index_stringl ( return_value , ZEND_AUTOLOAD_FUNC_NAME , sizeof ( ZEND_AUTOLOAD_FUNC_NAME ) - 1 , 1 ) ;
return ;
}
RETURN_FALSE ;
}
zend_hash_find ( EG ( function_table ) , " spl_autoload_call " , sizeof ( " spl_autoload_call " ) , ( void * * ) & fptr ) ;
if ( EG ( autoload_func ) = = fptr ) {
array_init ( return_value ) ;
zend_hash_internal_pointer_reset_ex ( SPL_G ( autoload_functions ) , & function_pos ) ;
while ( zend_hash_has_more_elements_ex ( SPL_G ( autoload_functions ) , & function_pos ) = = SUCCESS ) {
zend_hash_get_current_data_ex ( SPL_G ( autoload_functions ) , ( void * * ) & func_ptr_ptr , & function_pos ) ;
2005-07-29 04:59:44 +08:00
if ( ( * func_ptr_ptr ) - > common . scope ) {
zval * tmp ;
MAKE_STD_ZVAL ( tmp ) ;
array_init ( tmp ) ;
add_next_index_string ( tmp , ( * func_ptr_ptr ) - > common . scope - > name , 1 ) ;
add_next_index_string ( tmp , ( * func_ptr_ptr ) - > common . function_name , 1 ) ;
add_next_index_zval ( return_value , tmp ) ;
} else
add_next_index_string ( return_value , ( * func_ptr_ptr ) - > common . function_name , 1 ) ;
2005-03-03 08:20:57 +08:00
zend_hash_move_forward_ex ( SPL_G ( autoload_functions ) , & function_pos ) ;
}
return ;
}
array_init ( return_value ) ;
add_next_index_string ( return_value , EG ( autoload_func ) - > common . function_name , 1 ) ;
} /* }}} */
2005-02-14 02:30:26 +08:00
int spl_build_class_list_string ( zval * * entry , char * * list TSRMLS_DC ) /* { { { */
2004-01-26 01:30:19 +08:00
{
char * res ;
spprintf ( & res , 0 , " %s, %s " , * list , Z_STRVAL_PP ( entry ) ) ;
efree ( * list ) ;
* list = res ;
return ZEND_HASH_APPLY_KEEP ;
2005-02-14 02:30:26 +08:00
} /* }}} */
2004-01-26 01:30:19 +08:00
/* {{{ PHP_MINFO(spl)
*/
PHP_MINFO_FUNCTION ( spl )
{
zval list ;
char * strg ;
php_info_print_table_start ( ) ;
php_info_print_table_header ( 2 , " SPL support " , " enabled " ) ;
INIT_PZVAL ( & list ) ;
array_init ( & list ) ;
SPL_LIST_CLASSES ( & list , 0 , 1 , ZEND_ACC_INTERFACE )
strg = estrdup ( " " ) ;
zend_hash_apply_with_argument ( Z_ARRVAL_P ( & list ) , ( apply_func_arg_t ) spl_build_class_list_string , & strg TSRMLS_CC ) ;
zval_dtor ( & list ) ;
php_info_print_table_row ( 2 , " Interfaces " , strg + 2 ) ;
efree ( strg ) ;
INIT_PZVAL ( & list ) ;
array_init ( & list ) ;
SPL_LIST_CLASSES ( & list , 0 , - 1 , ZEND_ACC_INTERFACE )
strg = estrdup ( " " ) ;
zend_hash_apply_with_argument ( Z_ARRVAL_P ( & list ) , ( apply_func_arg_t ) spl_build_class_list_string , & strg TSRMLS_CC ) ;
zval_dtor ( & list ) ;
php_info_print_table_row ( 2 , " Classes " , strg + 2 ) ;
efree ( strg ) ;
php_info_print_table_end ( ) ;
2003-05-02 07:28:28 +08:00
}
/* }}} */
2006-02-21 06:21:54 +08:00
static
ZEND_BEGIN_ARG_INFO ( arginfo_iterator , 0 )
2006-06-07 17:44:42 +08:00
ZEND_ARG_OBJ_INFO ( 0 , iterator , Traversable , 0 )
ZEND_END_ARG_INFO ( ) ;
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_iterator_apply , 0 , 0 , 2 )
ZEND_ARG_OBJ_INFO ( 0 , iterator , Traversable , 0 )
ZEND_ARG_INFO ( 0 , function )
ZEND_ARG_ARRAY_INFO ( 0 , args , 1 )
2006-02-21 06:21:54 +08:00
ZEND_END_ARG_INFO ( ) ;
2005-02-14 02:30:26 +08:00
/* {{{ spl_functions
*/
2005-12-06 10:00:14 +08:00
zend_function_entry spl_functions [ ] = {
2005-02-14 02:30:26 +08:00
PHP_FE ( spl_classes , NULL )
2005-03-02 09:14:41 +08:00
PHP_FE ( spl_autoload , NULL )
PHP_FE ( spl_autoload_extensions , NULL )
PHP_FE ( spl_autoload_register , NULL )
2005-03-03 08:20:57 +08:00
PHP_FE ( spl_autoload_unregister , NULL )
PHP_FE ( spl_autoload_functions , NULL )
2005-03-02 09:14:41 +08:00
PHP_FE ( spl_autoload_call , NULL )
2005-02-14 02:30:26 +08:00
PHP_FE ( class_parents , NULL )
PHP_FE ( class_implements , NULL )
# ifdef SPL_ITERATORS_H
2006-02-21 06:21:54 +08:00
PHP_FE ( iterator_to_array , arginfo_iterator )
PHP_FE ( iterator_count , arginfo_iterator )
2006-06-07 17:44:42 +08:00
PHP_FE ( iterator_apply , arginfo_iterator_apply )
2005-02-14 02:30:26 +08:00
# endif /* SPL_ITERATORS_H */
{ NULL , NULL , NULL }
} ;
/* }}} */
/* {{{ PHP_MINIT_FUNCTION(spl)
*/
PHP_MINIT_FUNCTION ( spl )
{
PHP_MINIT ( spl_iterators ) ( INIT_FUNC_ARGS_PASSTHRU ) ;
PHP_MINIT ( spl_array ) ( INIT_FUNC_ARGS_PASSTHRU ) ;
PHP_MINIT ( spl_directory ) ( INIT_FUNC_ARGS_PASSTHRU ) ;
PHP_MINIT ( spl_sxe ) ( INIT_FUNC_ARGS_PASSTHRU ) ;
PHP_MINIT ( spl_exceptions ) ( INIT_FUNC_ARGS_PASSTHRU ) ;
PHP_MINIT ( spl_observer ) ( INIT_FUNC_ARGS_PASSTHRU ) ;
return SUCCESS ;
}
/* }}} */
2005-03-02 09:14:41 +08:00
PHP_RINIT_FUNCTION ( spl ) /* {{{ */
{
2005-08-10 16:36:46 +08:00
SPL_G ( autoload_extensions ) = estrndup ( " .inc,.php " , sizeof ( " .inc,.php " ) - 1 ) ;
2005-09-27 01:56:26 +08:00
SPL_G ( autoload_functions ) = NULL ;
2005-03-02 09:14:41 +08:00
return SUCCESS ;
} /* }}} */
PHP_RSHUTDOWN_FUNCTION ( spl ) /* {{{ */
{
if ( SPL_G ( autoload_extensions ) ) {
efree ( SPL_G ( autoload_extensions ) ) ;
2005-04-01 01:17:38 +08:00
SPL_G ( autoload_extensions ) = NULL ;
2005-03-02 09:14:41 +08:00
}
if ( SPL_G ( autoload_functions ) ) {
zend_hash_destroy ( SPL_G ( autoload_functions ) ) ;
FREE_HASHTABLE ( SPL_G ( autoload_functions ) ) ;
2005-09-27 01:56:26 +08:00
SPL_G ( autoload_functions ) = NULL ;
2005-03-02 09:14:41 +08:00
}
return SUCCESS ;
} /* }}} */
2005-06-18 00:42:54 +08:00
# ifdef HAVE_SIMPLEXML
static zend_module_dep spl_deps [ ] = {
ZEND_MOD_REQUIRED ( " libxml " )
ZEND_MOD_REQUIRED ( " simplexml " )
{ NULL , NULL , NULL }
} ;
# endif
2005-02-14 02:30:26 +08:00
/* {{{ spl_module_entry
*/
zend_module_entry spl_module_entry = {
2005-06-18 00:42:54 +08:00
# ifdef HAVE_SIMPLEXML
STANDARD_MODULE_HEADER_EX , NULL ,
spl_deps ,
# else
2005-02-14 02:30:26 +08:00
STANDARD_MODULE_HEADER ,
2005-06-18 00:42:54 +08:00
# endif
2005-02-14 02:30:26 +08:00
" SPL " ,
spl_functions ,
PHP_MINIT ( spl ) ,
NULL ,
2005-03-02 09:14:41 +08:00
PHP_RINIT ( spl ) ,
PHP_RSHUTDOWN ( spl ) ,
2005-02-14 02:30:26 +08:00
PHP_MINFO ( spl ) ,
" 0.2 " ,
2006-06-16 02:33:09 +08:00
PHP_MODULE_GLOBALS ( spl ) ,
PHP_GINIT ( spl ) ,
NULL ,
NULL ,
STANDARD_MODULE_PROPERTIES_EX
2005-02-14 02:30:26 +08:00
} ;
/* }}} */
2003-05-02 07:28:28 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
* vim600 : fdm = marker
* vim : noet sw = 4 ts = 4
*/