PHP源码分析-file_get_contents函数

马庆
2023-12-01

php版本:7.3.4

一直在做php方面的工作,总是在用php但也仅限于用,总想着有时间见去看看php的源码,总算得点时间去自己看下php的源码看完有些心得但总怕忘记,这里算是对php源码的一些记录.
先大概说明下流程PHP的协议都是伪协议,比如:php://,http://,glob://等等,都是经过一层封装的协议.

首先从file_get_contents函数源码进去然后层层追踪具体流程如下

//file.c (ext\standard) line 523 : PHP_FUNCTION(file_get_contents)
PHP_FUNCTION(file_get_contents)
{
//省略好多
stream = php_stream_open_wrapper_ex(filename, "rb",
				(use_include_path ? USE_PATH : 0) | REPORT_ERRORS,
				NULL, context);
//省略好多
}

首先这里PHP提供给语言调用的函数的定义方法就不多说了,php_stream_open_wrapper_ex是打开相应的为协议的封装.然后

//php_streams.h (main) line 571 :
#define php_stream_open_wrapper_ex(path, mode, options, opened, context)	_php_stream_open_wrapper_ex((path), (mode), (options), (opened), (context) STREAMS_CC)

//streams.c (main\streams) line 1981 
PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mode, int options,
		zend_string **opened_path, php_stream_context *context STREAMS_DC)
{
//省略好多
wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options);
//省略好多
}

这里也是对前边的一次封装然后关键的位置在php_stream_locate_url_wrapper

//streams.c (main\streams) line 1721 :
PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options)
{
	HashTable *wrapper_hash = (FG(stream_wrappers) ? FG(stream_wrappers) : &url_stream_wrappers_hash);
//省略好多
wrapper = zend_hash_str_find_ptr(wrapper_hash, protocol, n)
//省略好多
}

这里是将已经封装好的伪协议赋值给wrapper_hash 然后通过zend_hash_str_find_ptr去匹配相应的协议对应的底层实现.FG(stream_wrappers忽略,那么关键的地方在于url_stream_wrappers_hash从哪来的,接着全局搜索

//php_register_url_stream_wrapper in streams.c (main\streams) : 	
PHPAPI int php_register_url_stream_wrapper(const char *protocol, const php_stream_wrapper *wrapper)
{
	//省略好多
	ret = zend_hash_add_ptr(&url_stream_wrappers_hash, str, (void*)wrapper) ? SUCCESS : FAILURE;
	//省略一些
}

到这一步就一目了然了这个量是通过php_register_url_stream_wrapper来注册的
那么问题又来了谁?何时?调用了这个方法呢?接着搜

//PHP_MINIT_FUNCTION in basic_functions.c (ext\standard) :
/*php_register_url_stream_wrapper("php", &php_stream_php_wrapper);
php_register_url_stream_wrapper("file", &php_plain_files_wrapper);
php_register_url_stream_wrapper("glob", &php_glob_stream_wrapper);
php_register_url_stream_wrapper("data", &php_stream_rfc2397_wrapper);
php_register_url_stream_wrapper("http", &php_stream_http_wrapper);
php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper);*/
//这里就很清楚了
PHP_MINIT_FUNCTION(basic) /* {{{ */
{
    //省略非常多
	php_register_url_stream_wrapper("php", &php_stream_php_wrapper);
	php_register_url_stream_wrapper("file", &php_plain_files_wrapper);
#ifdef HAVE_GLOB
	php_register_url_stream_wrapper("glob", &php_glob_stream_wrapper);
#endif
	php_register_url_stream_wrapper("data", &php_stream_rfc2397_wrapper);
	php_register_url_stream_wrapper("http", &php_stream_http_wrapper);
	php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper);
	//又省略常多
}

看到PHP_MINIT_FUNCTION就一目了然了.
至于用到的几个结构体等等,有时间再写吧(^▽^)

 类似资料: