php7扩展自动加载类.

使用php扩展来开发框架似乎越来越来成来主流了,如phalcon,鸟哥的yaf。这些框架都以高性能著称,相对纯php使用的框架而,php扩展实现的框架更快,不会带来额外的系统消耗。在php启动时便已加载了框架,并且常驻内存。

几乎所有框架都带自动加载类,以便更好的管理代码。php实现方法这里就不多介绍了,读者可以自行百度。这里将介绍如何在php扩展中实现。

扩展中的实现原理与php实现基本原理一致,都是基于 spl_autoload_register 函数实现。

ZEND_METHOD(lxx_request,run) {
    zval arg;//参数
    zval * pthis = getThis();//当前类

    array_init(&arg);//初始化数据,
    Z_ADDREF_P(pthis);

    add_next_index_zval(&arg, pthis);
    add_next_index_string(&arg, "load");//当前类的中load的方法,表态方法(ZEND_ACC_STATIC)

    /*zend_call_method_with_1_params arg为数组参娄 php 代码spl_autoload_register([‘lxx\request‘,‘load‘]);*/
    zend_call_method_with_1_params(NULL, NULL, NULL, "spl_autoload_register", NULL, &arg);

   zval_ptr_dtor(&arg);
}

/*字符替换*/
static void str_replace(char *str,char o,char n) {
    while(*str != ‘\0‘) {
        if (*str == o) {
            *str = n;
        }
        str++;
    }
}

 ZEND_METHOD(lxx_request,load) {
    zend_string *cl;       /*php7中新增的数据类型 全用大写S接收,小写s则char指针*/
    long cl_len = 0;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &cl) == FAILURE) {
        RETURN_FALSE;
    }

    zend_file_handle zfd;
    zend_op_array *op_array;
    smart_str str = {0};
    smart_str_appendl(&str,cl->val,cl->len);
    smart_str_appendl(&str,".php",sizeof(".php")-1);
    smart_str_0(&str);

    str_replace(str.s->val,‘\\‘,‘/‘);
    zfd.type = ZEND_HANDLE_FILENAME;
    zfd.filename = str.s->val;
    zfd.free_filename = 0;
    zfd.opened_path = NULL;
    zfd.handle.fp = NULL;

    op_array = zend_compile_file(&zfd,ZEND_INCLUDE); 

    if (zfd.opened_path) {
        zend_hash_add_empty_element(&EG(included_files),zfd.opened_path);
    }
    zend_destroy_file_handle(&zfd);

    if(op_array) {
        zend_execute(op_array,NULL);
        //zend_exception_restore();

        destroy_op_array(op_array);
        efree(op_array);

    }

    //zend_printf("<BR>%s 有没有啊?帅不帅啊?",str.s->val);
    zend_string_release(cl);
    smart_str_free(&str);
}

注册当前类

ZEND_MODULE_STARTUP_D(lxx_request) {
    zend_class_entry ce;
    memset(&ce,0,sizeof(zend_class_entry));
    INIT_CLASS_ENTRY(ce,"Lxx\\request",lxx_request_functions);
    lxx_request_ce = zend_register_internal_class_ex(&ce,NULL);
    //lxx_request_ce->ce_flags = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
}

测试

$cl = new Lxx\request();
$cl->run();

$ab = new abc\ab();
echo $ab->test("lxx");

在abc目录下建立ab.php

namespace abc;
class ab {
    //php7新特性写法,
    public function test(string $name) :string {
         return "Hi : ".$name;
    }
}

输出

Hi : lxx


源文来自:www.lxxbl.com

时间: 2024-08-27 16:26:07

php7扩展自动加载类.的相关文章

自动加载类PHP中spl_autoload_register函数的用法

spl_autoload_register(PHP 5 >= 5.1.2) spl_autoload_register — 注册__autoload()函数 说明bool spl_autoload_register ([ callback $autoload_function ] )将函数注册到SPL __autoload函数栈中.如果该栈中的函数尚未激活,则激活它们. 如果在你的程序中已经实现了__autoload函数,它必须显式注册到__autoload栈中.因为 spl_autoload_

php 自动加载函数、自动加载方法、自动加载类

在PHP开发过程中,如果希望从 外部引入一个class,通常会使用include和require方法,去把定义这个class的文件包含进来.这个在小规模开发的时候,没什么大问 题.但在大型的开发项目中,这么做会产生大量的require或者include方法调用,这样不因降低效率,而且使得代码难以维护,况且 require_once的代价很大. 在PHP5之前,各个PHP框架如果要实现类的自动加载,一般都是按照某种约定自己实现一个遍历 目录,自动加载所有符合约定规则的文件的类或函数. 当然,PHP

php中自动加载类_autoload()和spl_autoload_register()实例详解

一._autoload 自动加载类:当我们实例化一个未定义的类时,就会触此函数.到了php7.1以后版本不支持此函数好像抛弃了 新建一个类文件名字自己随便去:news类在auto.php文件里面去实例news类而没有引入该类,可以用_autoload自动加载方法类去处理. news.class.php文件 class news{ function do_new() { echo 'aaa'; } } auto.php文件使用_autoload函数要定义函数体自己去定义 function __au

_autoload 自动加载类和spl_autoload_register()函数

一._autoload 自动加载类:当我们实例化一个未定义的类时,就会触此函数.到了php7.1以后版本不支持此函数好像抛弃了 新建一个类文件名字自己随便去:news类在auto.php文件里面去实例news类而没有引入该类,可以用_autoload自动加载方法类去处理. news.class.php文件 class news{ function do_new() { echo 'aaa'; } } auto.php文件使用_autoload函数要定义函数体自己去定义 function __au

框架开发(五)----自动加载类

一 . 为什么自动加载 自动加载字面的意思就不解释了.我这里自动加载类解析下 是自动加载类文件的意思.__autoload方法完全可行,但是不要问为什么,还是用spl_autoload_register.不只是灵活,而且就是灵活,还是灵活,体现在__autoload只能这么命名,spl_auto_register() 能调用不同的函数. 二  自动加载函数原理   通常情况下,一个类的定义都是一个文件,当类与类需要相互引用的时候,就需要include(require)相应的类文件,带来的问题就是

PHP面向对象 – 自动加载类

在设计面向对象的程序开发时,通常为每个类的定义都单独建立一个PHP源文件.当你尝试使用一个未定义的类时,php会报一个致命错误.可以用include或require包含一个类所在的源文件,毕竟你知道要用到那个类.如果一个页面需要使用多个类,就不得不在脚本页面开头编写一个长长的包含文件的列表,将本页面需要的类全部包含进来.这样处理不仅繁琐,而且容易出错.  PHP提供了类的自动加载功能,这可以节省编程的时间.当你尝试使用一个PHP没有组织到的类时,它会寻找一个__autoload()的全局函数(不

克隆对象和自动加载类

//克隆对象//关键字clone(克隆)class Ren{ public $name ="张三"; public function __clone() { $this->name = "李四"; } } $a = new Ren();$b = clone $a; $b->name="李四";echo $b->name; //加载类//include("写类文件的地址")require("写文件地址

自动加载类 (面向对象)----2017-04-20

一.__tostring()方法(了解) 写在类里:必须有返回值 class Ren { public $name; public function __ tostring() { return "该类是人类,name代表姓名"; } } $r = new Ren(); echo $r; 二.__clone()方法(了解) class Ren { public $name="张三"; //第二种修改成员变量值的方法 public function __clone()

spl_autoload_register自动加载类回调函数实现

随手写的,后台发现用不上,放上来以后可能用的着 1 /** 2 * SPL自动加载类 3 */ 4 class AutoLoad 5 { 6 7 /** 8 * 类文件所在目录 9 * 10 * @var string 11 */ 12 protected $dir = ""; 13 14 /** 15 * 类名与目录名映射数组 16 * 17 * @var array 18 */ 19 protected $map = array(); 20 21 /** 22 * 初始化自动加载类