博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一步步编写简单的PHP的Framework(四)
阅读量:6917 次
发布时间:2019-06-27

本文共 2441 字,大约阅读时间需要 8 分钟。

  hot3.png

 班级聚会刚回来,继续写这个文章吧!!

      上一篇文章我提了一个问题,怎么实现自动载入一个类呢?

       实际上PHP已经有相应的机制可以实现这个功能了,这个机制就是autoload,它会在试图使用尚未被定义的类时自动调用。

       现在我们可以在Route.php中的开头定义autoload函数(当然,这样是不规范的,但是为了简单,先这么做)。

        我们现在的自动导入需要导入两类文件,一类是框架类文件,另外一类是用户应用模块的类文件,为了简化代码,可以假设框架的所有文件都存放在/Library/Test目录下面,用户类文件都存放在/UserApps/Modules目录下面,并且只会在Controllers,Models,Helpers这三个目录下面,并且这几个目录下面没有子目录。

         对于这个自动导入的函数,它需要首先尝试导入框架类文件,如果该文件不存在,说明是用户类文件,然后再尝试导入用户类文件,如果是,那么include它。

         注意:

             由于要频繁使用UserApps/Modules这个目录,所以我定义了一个MODULES_PATH这个常量;

       

function __autoload($className) {	$frameworkFileName = FRAMEWORK_PATH . '/' . $className . '.php';	if(is_file($frameworkFileName)) {		include $frameworkFileName;	} else {		//用户类文件		$controllerFileName = MODULES_PATH . '/Controllers/' . $className . '.php';		if(is_file($controllerFileName)) {			include $controllerFileName;		} else {			$modelFileName = MODULES_PATH . '/Models/' . $className . '.php';			if(is_file($modelFileName)) {				include $modelFileName;			} else {				$helperFileName = MODULES_PATH . '/Helpers/' . $className . '.php';				if(is_file($helperFileName)) {					include $helperFileName;				} else {					throw new Exception("class not found");				}			}		}	}}

 

 

           当你把这个函数写完之后,可以在之前已经写好的IndexController.php中去测试一下,比如在和IndexController同一目录下面建立一个文件Test.php,文件代码如下:

 

然后在IndexController.php中使用如下:

 

 

test(); }}

如果出现Test,那么恭喜你,自动导入成功了!!

 

             现在再考虑一下,如果针对一个很复杂的项目,使用这种方式来自动导入,有什么问题吗?

             其实问题是比较严重的,首先对于框架的文件,我们不可能将所有文件都存放在一个目录下面,这样当文件多了之后就检索就麻烦了;对于用户类文件,比如控制器的文件,我们不可能将它全部存放在一个目录下面,我们需要按照模块切分目录等。如果用__autoload来实现的话,这个函数的代码量就太大了,而且如果有一个地方的修改那么就可能牵一发而动全身,这样对于项目的维护是很不利的。

             那么我们怎么解决这个问题呢?

             方法一:

                 我们定义很多辅助函数,比如导入框架文件,我们定义一个frameworkAutoloadHelper,对于用户文件定义一个userAutoloadHelper,然后将业务逻辑存放在这两个函数中,最后在__autoload中调用这两个函数即可,当用户功能需要修改的时候,代码维护性就好一些了;

             方法2:

                 在SPL中已经定义了一个spl_autoload_register,可以使用这个来讲自动导入的功能分摊到多个类中,而且还可以将自动导入的控制权交给用户,这对于框架来说是比较重要的,所以,我推荐使用这种方式。

                  具体这种方式怎么实现,读者可以自己查查PHP手册,也可以查看我写的的相应实现,具体实现类在/Library/Toper/Loader.class.php。

           当我们使用了spl_autoload_register之后,是不是一切就高枕无忧了?

            其实不是,我们现在可以想一下是否可以去除自动导入呢,因为当业务逻辑很复杂并且自动导入设计的又不是特别好的时候,自动导入的效率就不是很高了!!

             不用自动导入,难道还是使用include?No。

             大家都知道include,include_once,require,require_once的区别吧!!

             include和require每次调用都会包含这个文件,include_once和require_once只会导入一次,include如果包含了一个不存在的文件,只会抛出警告,程序会继续执行,而require会停止执行,所以这四个函数我比较建议使用require_once,但是很遗憾,这个函数效率很低,因为它要考虑的东西太多了!!

               PS:使用这四个函数的时候,最好使用绝对路径,这样效率要高一些;

              如果我们使用require,那么效率会高很多,但是如果使用require怎么实现require_once的功能呢?

              我给大家提供一个思路,使用static变量:

 

 

            当然,还可以使用class_exists来判定。

             这次的代码可以

转载于:https://my.oschina.net/hjchhx/blog/719754

你可能感兴趣的文章
js数值计算精度再次入坑
查看>>
iOS 快速注释工具VVDocumenter-加强版支持Xcode 7
查看>>
Arduino语音天气预报(三)
查看>>
微信小程序中页面间跳转传参方式
查看>>
【Delphi】Base64加解密模块
查看>>
买卖股票的最佳时机 II
查看>>
导入Alamofire
查看>>
RPA、AI、BPO、IT系统,你PICK谁? 如何选择提升业务效率的工具?
查看>>
SQL 中的常用函数及使用
查看>>
Windows10状态栏右下角的上升三角号没有了
查看>>
VMware无法连接MKS:套接字连接尝试次数太多解决
查看>>
输入框状态禁止enter键提交表单
查看>>
Spring Boot Environment的初始化和预处理
查看>>
React-redux原理探索
查看>>
CSS解决无空格太长的字母,数字不会自动换行的问题
查看>>
jeesite快速开发平台(二)----环境搭建
查看>>
65.Express---express-session
查看>>
P4576 [CQOI2013]棋盘游戏
查看>>
bzoj4889: [Tjoi2017]不勤劳的图书管理员(树套树)
查看>>
静态库链接时的依赖关系和先后顺序
查看>>