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
[FAQ]PHP中的一些常识:类篇
Oct 09 PHP
php,不用COM,生成excel文件
Oct 09 PHP
收藏的一个php小偷的核心程序
Apr 09 PHP
php Memcache 中实现消息队列
Nov 24 PHP
php对数组排序的简单实例
Dec 25 PHP
php function用法如何递归及return和echo区别
Mar 07 PHP
PHP中一些可以替代正则表达式函数的字符串操作函数
Nov 17 PHP
PHP下载远程文件到本地存储的方法
Mar 24 PHP
PHP5.4起内置web服务器使用方法
Aug 09 PHP
php批量删除操作代码分享
Feb 26 PHP
ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
Apr 03 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
win7下memCache的安装过程(具体操作步骤)
2013/06/28 PHP
PHP中array_map与array_column之间的关系分析
2014/08/19 PHP
PHP框架Laravel的小技巧两则
2015/02/10 PHP
PHP如何使用Memcached
2016/04/05 PHP
PHP+jquery+CSS制作头像登录窗(仿QQ登陆)
2016/10/20 PHP
php基于协程实现异步的方法分析
2019/07/17 PHP
PHP pthreads v3下同步处理synchronized用法示例
2020/02/21 PHP
javascript attachEvent和addEventListener使用方法
2009/03/19 Javascript
基于jquery的finkyUI插件与Ajax实现页面数据加载功能
2010/12/03 Javascript
javascript计算当月剩余天数(天数计算器)示例代码
2014/01/09 Javascript
JQuery删除DOM节点的方法
2015/06/11 Javascript
Javascript实现网络监测的方法
2015/07/31 Javascript
JavaScript实现多种排序算法
2016/02/24 Javascript
javascript css红色经典选项卡效果实现代码
2016/05/17 Javascript
JS 对象(Object)和字符串(String)互转方法
2016/05/20 Javascript
通用无限极下拉菜单的实现代码
2016/05/31 Javascript
AngularJs Understanding the Controller Component
2016/09/02 Javascript
jQuery实现的浮动层div浏览器居中显示效果
2017/02/03 Javascript
JS触摸与手势事件详解
2017/05/09 Javascript
Vue组件之自定义事件的功能图解
2018/02/01 Javascript
实例详解vue.js浅度监听和深度监听及watch用法
2018/08/16 Javascript
[04:49]期待西雅图之战 2016国际邀请赛中国区预选赛WINGS战队赛后采访
2016/06/29 DOTA
python查找第k小元素代码分享
2013/12/18 Python
python删除某个字符
2018/03/19 Python
Python中偏函数用法示例
2018/06/07 Python
python3解析库lxml的安装与基本使用
2018/06/27 Python
python实现傅里叶级数展开的实现
2018/07/21 Python
django最快程序开发流程详解
2019/07/19 Python
flask框架jinja2模板与模板继承实例分析
2019/08/01 Python
如何基于Python实现电子邮件的发送
2019/12/16 Python
太阳镜仓库,售价20美元或更少:Sunglass Warehouse
2016/09/28 全球购物
EJB面试题
2015/07/28 面试题
大一新生学期自我评价
2014/04/09 职场文书
2015年信息化建设工作总结
2015/07/23 职场文书
2016高校自主招生自荐信范文
2016/01/28 职场文书
详解Python生成器和基于生成器的协程
2021/06/03 Python