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

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

  }

  ...