zend api扩展的php对象的autoload工具


Posted in PHP onApril 18, 2011

类似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)

下载地址:http://code.google.com/p/bloader/downloads/detail?name=bloader.tar.gz

安装:
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; 
} 
...
PHP 相关文章推荐
一个多文件上传的例子(原创)
Oct 09 PHP
实现“上一页”和“下一页按钮
Oct 09 PHP
请php正则走开
Mar 15 PHP
php 取得瑞年与平年的天数的代码
Aug 10 PHP
php 在文件指定行插入数据的代码
May 08 PHP
windows下升级PHP到5.3.3的过程及注意事项
Oct 12 PHP
PHP函数篇之掌握ord()与chr()函数应用
Dec 05 PHP
php对二维数组按指定键值key排序示例代码
Nov 26 PHP
ThinkPHP3.2.2的插件控制器功能简述
Jul 09 PHP
CentOS下PHP安装Oracle扩展
Feb 15 PHP
php集成套件服务器xampp安装使用教程(适合第一次玩PHP的新手)
Jun 03 PHP
Yii2实现中国省市区三级联动实例
Feb 08 PHP
Drupal 添加模块出现莫名其妙的错误的解决方法(往往出现在模块较多时)
Apr 18 #PHP
ThinkPHP采用模块和操作分析
Apr 18 #PHP
PHP学习之数组值的操作
Apr 17 #PHP
PHP学习之数组的定义和填充
Apr 17 #PHP
PHP学习之正则表达式
Apr 17 #PHP
PHP学习之字符串比较和查找
Apr 17 #PHP
PHP学习之整理字符串
Apr 17 #PHP
You might like
UCenter Home二次开发指南
2009/05/28 PHP
php+mysql数据库实现无限分类的方法
2014/12/12 PHP
ajax+php实现无刷新验证手机号的实例
2017/12/22 PHP
实现php删除链表中重复的结点
2018/09/27 PHP
script标签属性type与language使用选择
2012/12/02 Javascript
JavaScript NodeTree导航栏(菜单项JSON类型/自制)
2013/02/01 Javascript
jQuery中parentsUntil()方法用法实例
2015/01/07 Javascript
基于javascript html5实现多文件上传
2016/03/03 Javascript
完美JQuery图片切换效果的简单实现
2016/07/21 Javascript
使用vue-cli打包过程中的步骤以及问题的解决
2018/05/08 Javascript
JS获取今天是本月第几周、本月共几周、本月有多少天、是今年的第几周、是今年的第几天的示例代码
2018/12/05 Javascript
优雅地使用loading(推荐)
2019/04/20 Javascript
Vue的双向数据绑定实现原理解析
2020/02/17 Javascript
vue实现前端列表多条件筛选
2020/10/26 Javascript
Python标准库内置函数complex介绍
2014/11/25 Python
python实现简易云音乐播放器
2018/01/04 Python
Python File readlines() 使用方法
2018/03/19 Python
解读python logging模块的使用方法
2018/04/17 Python
Python将list中的string批量转化成int/float的方法
2018/06/26 Python
pycharm 在windows上编辑代码用linux执行配置的方法
2018/10/27 Python
欧洲高端品牌直销店:Fashionesta
2016/08/31 全球购物
欧缇丽加拿大官方网站:Caudalie加拿大
2019/07/18 全球购物
莫斯科大型旅游休闲商品超市:Camping.ru
2020/09/16 全球购物
求职者简历中的自我评价
2013/10/20 职场文书
优秀辅导员事迹材料
2014/02/16 职场文书
小学运动会入场式解说词
2014/02/18 职场文书
法律专业自荐信
2014/06/03 职场文书
整顿机关作风心得体会
2014/09/10 职场文书
退休党员个人对照检查材料思想汇报
2014/09/29 职场文书
银行会计主管岗位职责
2014/10/01 职场文书
庆六一宣传标语
2014/10/08 职场文书
吴仁宝观后感
2015/06/09 职场文书
党员理论学习心得体会
2016/01/21 职场文书
导游词之镜泊湖
2019/12/09 职场文书
python神经网络 tf.name_scope 和 tf.variable_scope 的区别
2022/05/04 Python
win10如何快速切换窗口 win10切换窗口快捷键分享
2022/07/23 数码科技