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 相关文章推荐
3
Oct 09 PHP
PHP在字符断点处截断文字的实现代码
Apr 21 PHP
介绍一些PHP判断变量的函数
Apr 24 PHP
PHP中函数rand和mt_rand的区别比较
Dec 26 PHP
php实现加减法验证码代码
Feb 14 PHP
php中的四舍五入函数代码(floor函数、ceil函数、round与intval)
Jul 14 PHP
php画图实例
Nov 05 PHP
php简单的上传类分享
May 15 PHP
thinkphp3.2嵌入百度编辑器ueditor的实例代码
Jul 13 PHP
PHP递归统计系统中代码行数
Sep 19 PHP
浅谈Laravel中的三种中间件的作用
Oct 13 PHP
PHP如何通过带尾指针的链表实现'队列'
Oct 22 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实现)只使用++运算实现加法,减法,乘法,除法
2013/06/27 PHP
php 常用算法和时间复杂度
2013/07/01 PHP
PHP图像处理技术实例总结【绘图、水印、验证码、图像压缩】
2018/12/08 PHP
javascript新手语法小结
2008/06/15 Javascript
input 输入框内的输入事件详细分析
2010/03/17 Javascript
jQuery学习笔记 更改jQuery对象
2012/09/19 Javascript
javascript之典型高阶函数应用介绍二
2013/01/10 Javascript
深入理解javascript中return的作用
2013/12/30 Javascript
导入extjs、jquery 文件时$使用冲突问题解决方法
2014/01/14 Javascript
jQuery实现列表自动滚动循环滚动展示新闻
2014/08/22 Javascript
node.js中的fs.createWriteStream方法使用说明
2014/12/17 Javascript
jquery 无限极下拉菜单的简单实例(精简浓缩版)
2016/05/31 Javascript
JSON 必知必会 观后记
2016/10/27 Javascript
创建一般js对象的几种方式
2017/01/19 Javascript
微信小程序 在线支付功能的实现
2017/03/14 Javascript
vue拦截器实现统一token,并兼容IE9验证功能
2018/04/26 Javascript
详解如何在微信小程序中愉快地使用sass
2018/07/30 Javascript
vue-cli3 项目优化之通过 node 自动生成组件模板 generate View、Component
2019/04/30 Javascript
[02:20]DOTA2亚洲邀请赛 EHOME战队出场宣传片
2015/02/07 DOTA
详解字典树Trie结构及其Python代码实现
2016/06/03 Python
Centos 升级到python3后pip 无法使用的解决方法
2018/06/12 Python
对Pyhon实现静态变量全局变量的方法详解
2019/01/11 Python
啥是佩奇?使用Python自动绘画小猪佩奇的代码实例
2019/02/20 Python
我用Python抓取了7000 多本电子书案例详解
2019/03/25 Python
python 弹窗提示警告框MessageBox的实例
2019/06/18 Python
Windows平台Python编程必会模块之pywin32介绍
2019/10/01 Python
python flask搭建web应用教程
2019/11/19 Python
CSS3 优势以及网页设计师如何使用CSS3技术
2009/07/29 HTML / CSS
详解使用canvas保存网页为pdf文件支持跨域
2018/11/23 HTML / CSS
美国设计师精美珠宝购物网:Netaya
2016/08/28 全球购物
方正Java笔试题
2014/07/03 面试题
趣味比赛活动方案
2014/02/15 职场文书
中班中秋节活动反思
2014/02/18 职场文书
领导干部学习“三严三实”思想汇报
2014/09/15 职场文书
简单租房协议书
2014/10/21 职场文书
Pytorch 如何加速Dataloader提升数据读取速度
2021/05/28 Python