YiluPHP是如何做到不用配置、不用注入就能直接使用所有的类?
使用过YiluPHP的人都会发现,不管是模型类还是逻辑类、辅助类还是工具类,使用所有类都不需要在配置文件中设置加载或注入,也不需要在页面中使用 include 或 require 或 use ,直接使用 $app->类名->方法名() 就可以了,这个机制如此方便,刚开始使用的人都会有点不知得措,担心自己是不是做错了什么?我现在告诉你,你没有少做啥,也没有做错啥,YiluPHP就是这样设计的,下面我来告诉你YiluPHP是如何做到的。
有人可能会想使用 spl_autoload_register() 函数就能做到, spl_autoload_register() 函数可以注册任意数量的自动加载器,比如第三方库中的,要找一个类需要遍历所有的自动加载器,效率很低,这不符合YiluPHP追求速度的原则。YiluPHP的 $app 是一个全局变量,是名为YiluPHP的类的实例,这个类使用了php的魔术方法 __get,代码如下:
public function __get($name)
{
if (isset($this->helper[$name])) {
return $this->helper[$name];
}
$fun = $this->autoload_class;
$class_name = $fun($name);
unset($fun);
if ($class_name!==false){
$this->helper[$name] = new $class_name;
return $this->helper[$name];
}
throw new Exception($this->lang('class_not_found').$name);
}
当使用 $app->类名->方法名() 时,会先从$app的helper属性中查找是否已经有对应的类实例(helper属性是一个容器,装有所有已经使用过的类实例,所以当同一个类被第二次使用时不会再去查找文件,也不会再做实例化操作,直接从helper容器中返回,helper容器的设计也是YiluPHP运行迅速的原因之一),若在容器找不到对应的类实例,会调用自身的 autoload_class() 函数查找文件,autoload_class() 函数是赋值给$app的一个属性的,它的实现在$app的初始化函数 __construct() 中,
public function __construct()
{
$this->autoload_class = function ($class_name){
$file = $GLOBALS['project_root'].'helper/'.$class_name.'.php';
if (file_exists($file)) {
//helper类文件的文件名、类名、app中的调用方法三者需要一致
require_once($file);
return $class_name;
} //将驼峰式的名称用下划线分割
$path = preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $class_name);
$path = explode('_', $path, 2);
$path = $path[0].'/'.$class_name;
$file = $GLOBALS['project_root'].$path.'.php';
if (file_exists($file)) {
//类文件的文件名、类名、app中的调用方法三者需要一致
require_once($file);
return $class_name;
} //支持给类取别名
if(!empty($GLOBALS['config']['helper_alias']) && array_key_exists($class_name, $GLOBALS['config']['helper_alias']) ){
$real_class_name = $GLOBALS['config']['helper_alias'][$class_name];
$file = $GLOBALS['project_root'].'helper/'.$real_class_name.'.php';
if (file_exists($file)) {
require_once($file);
return $real_class_name;
} //将驼峰式的名称用下划线分割
$path = preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $real_class_name);
$path = explode('_', $path, 2);
$path = $path[0].'/'.$real_class_name;
$file = $GLOBALS['project_root'].$path.'.php';
if (file_exists($file)) {
require_once($file);
return $real_class_name;
}
}
return false;
};
}

YiluPHP是如何做到不用配置、不用注入就能直接使用所有的类?的更多相关文章
- spring中bean配置和注入场景分析
bean与spring容器的关系 Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载.实例化Bean,并 ...
- ASP.NET Core 在 JSON 文件中配置依赖注入
前言 在上一篇文章中写了如何在MVC中配置全局路由前缀,今天给大家介绍一下如何在在 json 文件中配置依赖注入. 在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等 ...
- Spring boot将配置属性注入到bean类中
一.@ConfigurationProperties注解的使用 看配置文件,我的是yaml格式的配置: // file application.yml my: servers: - dev.bar.c ...
- Spring4学习笔记二:Bean配置与注入相关
一:Bean的配置形式 基于XML配置:在src目录下创建 applicationContext.xml 文件,在其中进行配置. 基于注解配置:在创建bean类时,通过注解来注入内容.(这个不好,因 ...
- Springboot学习笔记(六)-配置化注入
前言 前面写过一个Springboot学习笔记(一)-线程池的简化及使用,发现有个缺陷,打个比方,我这个线程池写在一个公用服务中,各项参数都定死了,现在有两个服务要调用它,一个服务的线程数通常很多,而 ...
- Spring boot将配置属性注入到bean 专题
https://blog.csdn.net/wangmx1993328/article/details/81002901 Error starting ApplicationContext. To d ...
- spring_入门配置和注入
Spring的获取容器: public static void main(String[] args) { //获取核心容器 BeanFactory延迟加载对象 ApplicationContext ...
- 转载:ASP.NET Core 在 JSON 文件中配置依赖注入
在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等)时候,都是提供了专有的接口以供使用第三方的依赖注入组件,比如我们常用的会使用 Autofac.Untiy.Stri ...
- 外部配置属性值是如何被绑定到XxxProperties类属性上的?--SpringBoot源码(五)
注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 前言 本篇接 SpringBoot是如何实现自动配置的?--SpringBoot源码(四) 温故而知新,我们来简单回顾一下上 ...
- idea下使用autowire注解注入对象,结果初始化不到类
如果idea下使用autowire注解注入对象,结果初始化不到类,明明使用快捷键alt+insert是可以找到该注入的对象的. 而我们在使用的时候,缺报错了??? 注意,当我们在注入对象的时候,我们留 ...
随机推荐
- 洛谷P2634 聪聪可可 (点分治)
###题目链接### 题目大意: 给你一棵树,假如树上两点间的距离是 3 的倍数 的点对有 s 对,则输出最简分数 s/n ,其中 n 表示所有整棵树的点对总数. 分析: 1.显然,可以采用点分治. ...
- 程序员用于机器学习编程的Python 数据处理库 pandas 入门教程
入门介绍 pandas适合于许多不同类型的数据,包括: · 具有异构类型列的表格数据,例如SQL表格或Excel数据 · 有序和无序(不一定是固定频率)时间序列数据. · 具有行列标签的任意矩阵数据( ...
- VueRouter爬坑第二篇-动态路由
VueRouter系列的文章示例编写时,项目是使用vue-cli脚手架搭建. 项目搭建的步骤和项目目录专门写了一篇文章:点击这里进行传送 后续VueRouter系列的文章的示例编写均基于该项目环境. ...
- UiPath之获取邮件相关信息
大家好,小U又来给大家分享UiPath文章,争取每一篇文章都给大家带来满满的干货. 本次案例是告诉大家如何使用GetOutLookMailMessage这个Activity, 案例的目的是将某个特定人 ...
- 阿里云上万个 Kubernetes 集群大规模管理实践
点击下载<不一样的 双11 技术:阿里巴巴经济体云原生实践> 本文节选自<不一样的 双11 技术:阿里巴巴经济体云原生实践>一书,点击上方图片即可下载! 作者 | 汤志敏,阿里 ...
- poj 2991 起重机
地址 http://poj.org/problem?id=2991 题解 本来以为这是一个简单的线段树模板 不料始终不太明白线段树如何记录转动角度后的各个线段端的XY值 学习了网络上的一些博客题解 感 ...
- java switch语句 要点注意
1.格式 switch(表达式){ case 常量1:语句1:break: case 常量2:语句2:break: case 常量3:语句3:break: .... case 常量n:语句n:brea ...
- LAMP架构介绍、MySQL、MariaDB介绍、MySQL安装
5月23日任务 课程内容: 11.1 LAMP架构介绍11.2 MySQL.MariaDB介绍11.3/11.4/11.5 MySQL安装扩展mysql5.5源码编译安装 http://www.ami ...
- 【github repo自荐】码农周刊一周精选分类
以下内容节选自我的github码农周刊整理repo,欢迎大家star. 写在最前面的话 作为最初的一批码农周刊的订阅者,不能说经历了其成长,但是确实见证了他的壮大.码农周刊确实从开始第一期的基本上都是 ...
- SDWebImage学习之 NSCache
1.使用SDWebImage的好处 1.异步下载(避免主线程卡死) 2.做好图片缓存(这样就不需要每次都加载网络图片) 3.解决了循环利用的问题 很容易造成内存警告