zend api扩展的php对象的autoload工具
程序员文章站
2023-10-31 22:05:58
类似spl的autoload功能,bloader为php对象的autoload工具,但相比较起来更简单高效,配置也更灵活. bloader提供一个常用的autoload函数...
类似spl的autoload功能,bloader为php对象的autoload工具,但相比较起来更简单高效,配置也更灵活.
bloader提供一个常用的autoload函数ld,以及两个辅助函数,ld_new(实例化)和ld_unset(销毁对象).
#1 bloader会自动搜索当前文件 或 当前目录下的<类名>.class.php文件,以及通过'_modules'常量定义的路径,实例化类返回对象.
#2 可直接使用ld('类名')操作对象(见实例 1-1)
#3 bloader会在当前作用域自动注册一个以类名为变量名的变量'$类名'(见实例 1-2)
#4 bloader中使用ld函数访问对象是全局范围有效 (见实例 1-3)
#5 使用ld_new实例化多个不同的对象,而不注册变量 (见实例 1-4)
#6 使用ld_unset注销已经实例化的对象 (见实例 1-5)
下载地址:
安装:
phpize
./configure --with-php-config=php-config --enable-bloader
make && make install
实例 1-1
<?php
///define('_modules',dirname( __file__ ).'/class'); ///可选配置,在指定目录下查找类文件,以便于实例化
ld('c1',array('1','2'))->a1="a1"; ///参数2为构造函数的参数
ld('c1')->a2='a2';
ld('c1')->printt();
/**
show:
c1 object
(
[a1] => a1
[a2] => a2
[a3] => array
(
[0] => 1
[1] => 2
)
)
*/
?>
<?php
/**
example:
./class/c1.class.php:
*/
class c1
{
public $a1=123;
public $a2='abc';
public $a3=100;
public function __construct($ls)
{
$this->a3=$ls;
}
public function printt()
{
print_r(ld('c1')); /**使用了全局特性*/
}
}
?>
实例 1-2
<?php
...
ld('users');
//自动注册了$users变量
$users->method();
....
?>
实例 1-3
<?php
ld('users');
printt(); //打印对象
...
function printt()
{
var_dump(ld('users'));
}
?>
实例 1-4
<?php
$users_1=ld_new('users');
$users_2=ld_new('users');
...
?>
实例 1-5
<?php
ld('users');
unset_users();
...
function unset_users()
{
ld_unset('users');
}
?>
奉上主要代码供拍砖
...
php_function(ld)
{
char *obj_name;
int slen;
zval **var,*para = null;
if(zend_parse_parameters(zend_num_args() tsrmls_cc, "s|z", &obj_name,&slen,¶) != success)
{
zend_error(e_error, "parameters failed.");
}
else
{
zval_dtor(return_value);
if(zend_hash_find(&eg(symbol_table),obj_name,slen+1,(void **) &var)!=success)
{
ld_autoload_path(obj_name tsrmls_dc);
*return_value = *ld_new_class(obj_name,slen,para,1);
}
else
{
*return_value = **var;
}
zval_copy_ctor(return_value);
}
}
php_function(ld_new)
{
char *obj_name;
int slen;
zval *para = null;
if(zend_parse_parameters(zend_num_args() tsrmls_cc, "s|z", &obj_name,&slen,¶) != success)
{
zend_error(e_error, "parameters failed.");
}
else
{
zval_dtor(return_value);
ld_autoload_path(obj_name tsrmls_dc);
*return_value = *ld_new_class(obj_name,slen,para,0);
zval_copy_ctor(return_value);
}
}
php_function(ld_unset)
{
char *obj_name;
int slen;
if(zend_parse_parameters(zend_num_args() tsrmls_cc, "s", &obj_name,&slen) != success)
{
zend_error(e_error, "parameters failed.");
}
else
{
zend_hash_del(&eg(symbol_table),obj_name,slen+1);
return_true;
}
}
/* }}} */
static zval *ld_new_class(char *obj_name,int slen,zval *para,int is_set)
{
zval *obj;
zend_class_entry **class_entry;
zend_function *constructor;
make_std_zval(obj);
if(zend_lookup_class(obj_name, slen, &class_entry tsrmls_cc)==success)
{
object_init_ex(obj, *class_entry);
constructor = z_obj_ht_p(obj)->get_constructor(obj tsrmls_cc);
if (constructor != null)
{
int is_arg = (para == null) ? 0 : 1;
zend_call_method(&obj, *class_entry,&constructor, "__construct", 11, null, is_arg, para, null tsrmls_cc);
}
if(is_set==1) zend_set_symbol(&eg(symbol_table),obj_name, obj);
}
else
{
zval_false(obj);
}
return obj;
}
static int ld_autoload_path(char *class_name tsrmls_dc)
{
char *ext_name = ".class.php";
char *file_path;
zval const_root;
int path_len = spprintf(&file_path, 0, "%s%s",class_name,ext_name);
if(ld_autoload_file(file_path,path_len tsrmls_dc)==success) return success;
if(zend_get_constant("_modules",8,&const_root tsrmls_cc))
//if(zend_get_constant_ex("_modules",8,const_root,null, 0 tsrmls_cc)) //zend_fetch_class_silent
{
if(z_type(const_root) == is_string)
{
char *root_file_path;
int root_path_len = spprintf(&root_file_path, 0, "%s/%s", z_strval(const_root),file_path);
return ld_autoload_file(root_file_path,root_path_len tsrmls_dc);
}
}
return failure;
}
static int ld_autoload_file(char *file_path,int file_path_len tsrmls_dc) /* {{{ */
{
zend_file_handle file_handle;
if (php_stream_open_for_zend_ex(file_path, &file_handle, enforce_safe_mode|use_path|stream_open_for_include tsrmls_cc) == success)
{
zend_op_array *new_op_array;
unsigned int dummy = 1;
if (!file_handle.opened_path) file_handle.opened_path = estrndup(file_path, file_path_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 tsrmls_cc);
}
if (new_op_array)
{
zval *result = null;
eg(return_value_ptr_ptr) = &result;
eg(active_op_array) = new_op_array;
if (!eg(active_symbol_table)) zend_rebuild_symbol_table(tsrmls_c);
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));
}
return success;
}
return failure;
}
...
bloader提供一个常用的autoload函数ld,以及两个辅助函数,ld_new(实例化)和ld_unset(销毁对象).
#1 bloader会自动搜索当前文件 或 当前目录下的<类名>.class.php文件,以及通过'_modules'常量定义的路径,实例化类返回对象.
#2 可直接使用ld('类名')操作对象(见实例 1-1)
#3 bloader会在当前作用域自动注册一个以类名为变量名的变量'$类名'(见实例 1-2)
#4 bloader中使用ld函数访问对象是全局范围有效 (见实例 1-3)
#5 使用ld_new实例化多个不同的对象,而不注册变量 (见实例 1-4)
#6 使用ld_unset注销已经实例化的对象 (见实例 1-5)
下载地址:
安装:
phpize
./configure --with-php-config=php-config --enable-bloader
make && make install
实例 1-1
复制代码 代码如下:
<?php
///define('_modules',dirname( __file__ ).'/class'); ///可选配置,在指定目录下查找类文件,以便于实例化
ld('c1',array('1','2'))->a1="a1"; ///参数2为构造函数的参数
ld('c1')->a2='a2';
ld('c1')->printt();
/**
show:
c1 object
(
[a1] => a1
[a2] => a2
[a3] => array
(
[0] => 1
[1] => 2
)
)
*/
?>
复制代码 代码如下:
<?php
/**
example:
./class/c1.class.php:
*/
class c1
{
public $a1=123;
public $a2='abc';
public $a3=100;
public function __construct($ls)
{
$this->a3=$ls;
}
public function printt()
{
print_r(ld('c1')); /**使用了全局特性*/
}
}
?>
实例 1-2
复制代码 代码如下:
<?php
...
ld('users');
//自动注册了$users变量
$users->method();
....
?>
实例 1-3
复制代码 代码如下:
<?php
ld('users');
printt(); //打印对象
...
function printt()
{
var_dump(ld('users'));
}
?>
实例 1-4
复制代码 代码如下:
<?php
$users_1=ld_new('users');
$users_2=ld_new('users');
...
?>
实例 1-5
复制代码 代码如下:
<?php
ld('users');
unset_users();
...
function unset_users()
{
ld_unset('users');
}
?>
奉上主要代码供拍砖
复制代码 代码如下:
...
php_function(ld)
{
char *obj_name;
int slen;
zval **var,*para = null;
if(zend_parse_parameters(zend_num_args() tsrmls_cc, "s|z", &obj_name,&slen,¶) != success)
{
zend_error(e_error, "parameters failed.");
}
else
{
zval_dtor(return_value);
if(zend_hash_find(&eg(symbol_table),obj_name,slen+1,(void **) &var)!=success)
{
ld_autoload_path(obj_name tsrmls_dc);
*return_value = *ld_new_class(obj_name,slen,para,1);
}
else
{
*return_value = **var;
}
zval_copy_ctor(return_value);
}
}
php_function(ld_new)
{
char *obj_name;
int slen;
zval *para = null;
if(zend_parse_parameters(zend_num_args() tsrmls_cc, "s|z", &obj_name,&slen,¶) != success)
{
zend_error(e_error, "parameters failed.");
}
else
{
zval_dtor(return_value);
ld_autoload_path(obj_name tsrmls_dc);
*return_value = *ld_new_class(obj_name,slen,para,0);
zval_copy_ctor(return_value);
}
}
php_function(ld_unset)
{
char *obj_name;
int slen;
if(zend_parse_parameters(zend_num_args() tsrmls_cc, "s", &obj_name,&slen) != success)
{
zend_error(e_error, "parameters failed.");
}
else
{
zend_hash_del(&eg(symbol_table),obj_name,slen+1);
return_true;
}
}
/* }}} */
static zval *ld_new_class(char *obj_name,int slen,zval *para,int is_set)
{
zval *obj;
zend_class_entry **class_entry;
zend_function *constructor;
make_std_zval(obj);
if(zend_lookup_class(obj_name, slen, &class_entry tsrmls_cc)==success)
{
object_init_ex(obj, *class_entry);
constructor = z_obj_ht_p(obj)->get_constructor(obj tsrmls_cc);
if (constructor != null)
{
int is_arg = (para == null) ? 0 : 1;
zend_call_method(&obj, *class_entry,&constructor, "__construct", 11, null, is_arg, para, null tsrmls_cc);
}
if(is_set==1) zend_set_symbol(&eg(symbol_table),obj_name, obj);
}
else
{
zval_false(obj);
}
return obj;
}
static int ld_autoload_path(char *class_name tsrmls_dc)
{
char *ext_name = ".class.php";
char *file_path;
zval const_root;
int path_len = spprintf(&file_path, 0, "%s%s",class_name,ext_name);
if(ld_autoload_file(file_path,path_len tsrmls_dc)==success) return success;
if(zend_get_constant("_modules",8,&const_root tsrmls_cc))
//if(zend_get_constant_ex("_modules",8,const_root,null, 0 tsrmls_cc)) //zend_fetch_class_silent
{
if(z_type(const_root) == is_string)
{
char *root_file_path;
int root_path_len = spprintf(&root_file_path, 0, "%s/%s", z_strval(const_root),file_path);
return ld_autoload_file(root_file_path,root_path_len tsrmls_dc);
}
}
return failure;
}
static int ld_autoload_file(char *file_path,int file_path_len tsrmls_dc) /* {{{ */
{
zend_file_handle file_handle;
if (php_stream_open_for_zend_ex(file_path, &file_handle, enforce_safe_mode|use_path|stream_open_for_include tsrmls_cc) == success)
{
zend_op_array *new_op_array;
unsigned int dummy = 1;
if (!file_handle.opened_path) file_handle.opened_path = estrndup(file_path, file_path_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 tsrmls_cc);
}
if (new_op_array)
{
zval *result = null;
eg(return_value_ptr_ptr) = &result;
eg(active_op_array) = new_op_array;
if (!eg(active_symbol_table)) zend_rebuild_symbol_table(tsrmls_c);
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));
}
return success;
}
return failure;
}
...
下一篇: python+pyqt5实现24点小游戏
推荐阅读
-
zend api扩展的php对象的autoload工具
-
当前比较流行的两款PHP加密、解密工具Zend Guard和iconCube介绍
-
PHP 扩展与 ZEND 引擎的整合
-
PHP的bz2压缩扩展工具详解
-
ionCube 一款类似zend的PHP加密/解密工具
-
PHP管理依赖(dependency)关系工具 Composer的自动加载(autoload)
-
php mysqli扩展Client API library version版本不统一导致获取出来的数据讲整型转换成了字符串类型
-
使用php开发,基于swoole扩展开发的工具 swoole-crontab 作业/任务调度
-
PHP中的MySQLi扩展学习(五)MySQLI_STMT对象操作
-
[翻译][php扩展开发和嵌入式]第10章-php4的对象