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 相关文章推荐
php防攻击代码升级版
Dec 29 PHP
php日期转时间戳,指定日期转换成时间戳
Jul 17 PHP
PHP使用正则表达式清除超链接文本
Nov 12 PHP
php实现在限定区域里自动调整字体大小的类实例
Apr 02 PHP
PHP处理会话函数大总结
Aug 05 PHP
浅析ThinkPHP缓存之快速缓存(F方法)和动态缓存(S方法)(日常整理)
Oct 26 PHP
PHP中strncmp()函数比较两个字符串前2个字符是否相等的方法
Jan 07 PHP
分析PHP中单双引号的误区和双引号小隐患
Jul 19 PHP
Laravel搭建后台登录系统步骤详解
Jul 26 PHP
详解如何在云服务器上部署Laravel
Jun 30 PHP
php+layui数据表格实现数据分页渲染代码
Oct 26 PHP
PHP与Web页面的交互示例详解一
Aug 04 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
把PHP安装为Apache DSO
2006/10/09 PHP
ThinkPHP上使用多说评论插件的方法
2014/10/31 PHP
php调用mysql存储过程实例分析
2014/12/29 PHP
PHP中preg_match函数正则匹配的字符串长度问题
2015/05/27 PHP
php 使用redis锁限制并发访问类示例
2016/11/02 PHP
Javascript中的数学函数集合
2007/05/08 Javascript
JS实现拖动示例代码
2013/11/01 Javascript
Jquery遍历Json数据的方法
2015/04/20 Javascript
在JavaScript中处理字符串之link()方法的使用
2015/06/08 Javascript
JS实现获取键盘按下的按键并显示在页面上的方法
2015/11/04 Javascript
基于JS代码实现导航条弹出式悬浮菜单
2016/06/17 Javascript
Javascript 高性能之递归,迭代,查表法详解及实例
2017/01/08 Javascript
详解微信小程序开发聊天室—实时聊天,支持图片预览
2019/05/20 Javascript
js实现计时器秒表功能
2019/12/16 Javascript
Python使用urllib2模块抓取HTML页面资源的实例分享
2016/05/03 Python
TF-IDF与余弦相似性的应用(二) 找出相似文章
2017/12/21 Python
Numpy数组转置的两种实现方法
2018/04/17 Python
Python网页正文转换语音文件的操作方法
2018/12/09 Python
对Python之gzip文件读写的方法详解
2019/02/08 Python
PyQt打开保存对话框的方法和使用详解
2019/02/27 Python
Python简易版停车管理系统
2019/08/12 Python
Python 切分数组实例解析
2019/11/07 Python
pycharm 设置项目的根目录教程
2020/02/12 Python
Python中socket网络通信是干嘛的
2020/05/27 Python
Fossil美国官网:化石手表、手袋、首饰及配饰
2019/02/17 全球购物
饿了么订餐官网:外卖、网上订餐
2019/06/28 全球购物
Ado与Ado.net的相同与不同
2014/12/08 面试题
如何提高MySql的安全性
2014/06/19 面试题
2014年小学元旦活动方案
2014/02/12 职场文书
测量工程专业求职信
2014/02/24 职场文书
单位未婚证明范本
2014/11/25 职场文书
简历自荐信范文
2015/03/09 职场文书
入伍通知书
2015/04/23 职场文书
公司考勤管理制度
2015/08/04 职场文书
热爱劳动主题班会
2015/08/14 职场文书
Python四款GUI图形界面库介绍
2022/06/05 Python