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 相关文章推荐
解决phpmyadmin 乱码,支持gb2312和utf-8
Nov 20 PHP
php下判断数组中是否存在相同的值array_unique
Mar 25 PHP
约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
Oct 12 PHP
php使用pdo连接并查询sql数据库的方法
Dec 24 PHP
分享常见的几种页面静态化的方法
Jan 08 PHP
关于php微信订阅号开发之token验证后自动发送消息给订阅号但是没有消息返回的问题
Dec 21 PHP
PHP利用imagick生成组合缩略图
Feb 19 PHP
PHP实现的线索二叉树及二叉树遍历方法详解
Apr 25 PHP
php实现的错误处理封装类实例
Jun 20 PHP
PHP观察者模式原理与简单实现方法示例
Aug 25 PHP
Laravel中10个有用的用法小结
May 06 PHP
详解使用php-cs-fixer格式化代码
Sep 16 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.MVC的模板标签系统(二)
2006/09/05 PHP
php中全局变量global的使用演示代码
2011/05/18 PHP
php中的PHP_EOL换行符详细解析
2013/10/26 PHP
curl和libcurl的区别简介
2015/07/01 PHP
PHP7新特性foreach 修改示例介绍
2016/08/26 PHP
php执行多个存储过程的方法【基于thinkPHP】
2016/11/08 PHP
JavaScript脚本性能优化注意事项
2008/11/18 Javascript
JS跨域总结
2012/08/30 Javascript
js模拟C#中List的简单实例
2014/03/06 Javascript
jQuery Validation PlugIn的使用方法详解
2015/12/18 Javascript
javascript实现仿百度图片的瀑布流加载效果
2016/04/20 Javascript
值得分享的bootstrap table实例
2016/09/22 Javascript
ReactNative页面跳转实例代码
2016/09/27 Javascript
在vue中封装可复用的组件方法
2018/03/01 Javascript
vue.js做一个简单的编辑菜谱功能
2018/05/08 Javascript
JS div匀速移动动画与变速移动动画代码实例
2019/03/26 Javascript
详解小程序如何避免多次点击,重复触发事件
2019/04/08 Javascript
Python中的__new__与__init__魔术方法理解笔记
2014/11/08 Python
浅谈Python 集合(set)类型的操作——并交差
2016/06/30 Python
老生常谈Python进阶之装饰器
2017/05/11 Python
Python复制Word内容并使用格式设字体与大小实例代码
2018/01/22 Python
PyCharm+Qt Designer+PyUIC安装配置教程详解
2019/06/13 Python
浅析python redis的连接及相关操作
2019/11/07 Python
简单了解python装饰器原理及使用方法
2019/12/18 Python
python opencv 实现对图像边缘扩充
2020/01/19 Python
在keras里面实现计算f1-score的代码
2020/06/15 Python
selenium如何定位span元素的实现
2021/01/13 Python
CSS3 Backgrounds属性相关介绍
2011/05/11 HTML / CSS
CSS实现聊天气泡效果
2020/04/26 HTML / CSS
印度尼西亚在线时尚购物网站:ZALORA印尼
2016/08/02 全球购物
马来西亚户外装备商店:PTT Outdoor
2019/07/13 全球购物
人力资源管理专业自荐书范文
2014/02/10 职场文书
纺织工程专业推荐信
2014/09/08 职场文书
大学生见习报告范文
2014/11/03 职场文书
清明祭英烈活动总结
2015/05/11 职场文书
Golang 空map和未初始化map的注意事项说明
2021/04/29 Golang