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是可以找到该注入的对象的. 而我们在使用的时候,缺报错了??? 注意,当我们在注入对象的时候,我们留 ...
随机推荐
- 百度杯 十二月 what_the_fuck
对于这道题,我还真的想说 what_the_fuck !! 这道题拿到就只发觉一个格式化字符串漏洞,其他的就找不到了 . unsigned __int64 sub_4008C5() { char s; ...
- linux awk进阶篇
上一篇主要是awk的进本应用.本节是awk的进阶篇 ACTION:除去常用的print和printf还有以下几个 expression:表达式 如$1>3 control statements: ...
- 最全 HTTP 安全响应头设置指南
销售“安全记分卡”的公司正在崛起,并已开始成为企业销售的一个因素.这些公司组合使用 HTTP 安全报头和 IP 信誉来进行评级.不过,在很大程度上,公司的得分取决于对外开放网站上设置的安全响应报头.本 ...
- word2vec:CBOW和skip-gram模型
1.CBOW模型 之前已经解释过,无论是CBOW模型还是skip-gram模型,都是以Huffman树作为基础的.值得注意的是,Huffman树中非叶节点存储的中间向量的初始化值是零向量,而叶节点对应 ...
- yum运行报错:libcurl.so.4: cannot open shared object file: No such file or directory
/usr/lib64/目录下存在libcurl.so.4文件 CURL的动态库找不到,这里我们加入到ld.so.conf [root@localhost bin]# vim /etc/ld.so.c ...
- Linux如何切换图形界面和命令行界面
在命令行,输入 init 3 命令,并按回车键执行,切换到命令行界面 切换到命令行界面后,在界面上只显示一个闪烁的光标,按下 Ctrl+Alt+F6(非虚拟机)或者 Alt+F6(虚拟机),显示用户登 ...
- Spring(Bean)1
Spring支持3种依赖注入的方式 (DI依赖注入)*属性注入 (配置bean set方法注入) <bean id="car" class="spring.bean ...
- Nginx安装、默认虚拟主机、Nginx用户认证和域名重定向
6月7日任务 12.6 Nginx安装12.7 默认虚拟主机12.8 Nginx用户认证12.9 Nginx域名重定向 扩展nginx.conf 配置详解 http://www.ha97.com/51 ...
- SSO单点登录思路
SSO (Single Sign On) 什么是单点登录: 在大型的互联网公司中会有多个系统, 多个项目, 虽然这些项目都属于同一家公司, 但是项目本身其实都是独立的, 那多个系统可不可以实现共享同一 ...
- Bean中要使用配置文件中的值,使用set方法注入
/** * Sensors Analytics Bean * @author Feng */ @Component public class SensorsAnalyticsBean { /*** * ...