怎么样写一个自己的渣渣PHP框架(2)

gongzhiyang 8月前 262


项目地址
本节主要讲自动加载,想了半天该如何引入呢!

既然如此,就先把自动加载说一下。

框架来说,简单点,就是根据你的ur地址,比如http://gzy.com/index.php?g=home&c=index&a=run 大多数应该都是这样吧,那么框架是如何根据 index 和 run 去找到 index 控制器,然后调用其中的 run 方法。当然后面还可以加很多的参数暂且先不说。确切的来讲你的home是模块, 你呢 index 控制器也是一个类,你什么时候 new 的这个类呢?你什么时候调用的 run 方法?这就是框架要做的事情,就是我理解的 路由 和 自动加载 。

接着来,建立框架核心目录 /gzy/core 在core目录建立 init.php 文件作为框架核心入口文件。 建立目录 /gzy/core/gzy 在 gzy 里建立 AutoLoad.php 文件.用于加载文件。

namespace core\gzy;


class AutoLoad
{
	public static function loadprint($class){

		$file = YIN_PATH."/".$class.".php";
		//echo YIN_PATH; echo "<br/>";

//		// "Linux需要转义斜杠";
		$file = str_replace('\\','/',$file);
		$path = pathinfo($file);
		//print_r($path) ;
		$file = $path["dirname"].'/'.$path["basename"];
		//echo $file ."<br>";    //这句话是为了调试使用

		if (is_file($file)) {

			//var_dump(str_replace('\\','/',pathinfo($file)["dirname"].'/'.pathinfo($file)["basename"])) ; echo "<br/>";
			include_once($file);
		}

	}

使用命名空间,你使用过命名空间吗?没有的话一定要用上。你说这么小的项目完全不需要使用命名空间啊,小项目正好用熟悉一下,不然大项目更不会用。(命名空间一定要根据目录来定义,这样为自动加载做准备)

然后在 gzy 里建立 gzy.php 文件,作为框架核心类。
namespace core\gzy;
use core\lib\Route;
use Noodlehaus\Config;
class Gzy
{
private $modules; //默认模块
private $controller; //默认控制器
private $action; //默认方法
private $conf; //配置文件
private $parm;

public function __construct() {
	$this->conf = new Config(YIN_PATH. '/config/conf.php');

}

public function run(){


	//echo "====";exit;
	// 路由分发功能
	$route = new Route();
	// 根据一些列的路由方法目的也是找到$_GET['c']和$_GET['a']
	// 只不过方法更严谨,从 $_SERVER 里获取相应的内容
	$file = YIN_PATH."/"."core/Common/functions.php";
	//echo $file;
	include $file;
	$dispatcher = $route->dispatcher();
	//var_dump($dispatcher);exit;
	// 这里我们直接获取
	//$this->getRequest();
	$this->modules    = $dispatcher["modules"];
	$this->controller = $dispatcher["controller"];
	$this->action     = $dispatcher["action"];
	//$this->parm       = $dispatcher["param"];

	$class = "\\$this->modules\\controller\\".ucfirst($this->controller)."Controller";

	$obj = new $class();

	$action = $dispatcher["action"];
	//var_dump($_SERVER);
	$obj->$action();


}

这个时候来看 init.php :

use \core\gzy\AutoLoad;
use \core\gzy\Gzy;

// 自动加载
spl_autoload_register([new AutoLoad(),'loadprint']);

// 框架核心入口
$gzy = new Gzy();
$gzy->run();

spl_autoload_register 是今天的重点。
摘抄网上的
spl_autoload_register函数是实现自动加载未定义类功能的的重要方法,所谓的自动加载意思就是 我们的new 一个类的时候必须先include或者require的类文件,如果没有include或者require,则会报错。那这样我们就必须在文件头部写上许多include或require文件,非常麻烦,
为了使得没有include或者require类的时候也正常new一个类,所以有了自动加载的概念,也就是说new一个类之前不用事先包含类文件也可以正常new,这样我们的文件头部就不用包含许多include(require)。其实这算一种封装!

自己的理解
当你要在代码中 new 一个 Route 类的时候,你肯定得先 include 这个类文件。不然会直接报错告诉你 “Class ‘Route’ not found” 的。比如我在上面 new 了 gzy 这个类,我没有 include ,这个时候 spl_autoload_register 就会发生作用,当我要 new 一个不存在的类的时候,程序就会自动触发 spl_autoload_register 自动注册的方法,也就是 AutoLoad 类里面的 loadprint 方法。loadprint 方法会接收到你要 new 的这个类,包含命名空间。然后,定义这个文件,file=MOMOMAPATH."/".class.".php"; 转义,然后判断它是否是一个文件,是就 include_one 。

去框架的入口文件 index.php 的最下面引入 核心文件 init.php :(一定要在"filp/whoops"之后引入,不然错误信息没法提示了。因为如果你在之前引入,程序出了问题,程序执行不到"filp/whoops"了)

require_once YIN_PATH . '/core/gzy/AutoLoad.php';
require_once YIN_PATH . '/core/init.php'; //引入框架核心文件

文字叙述好无力呀,来张图表述一下当前目录结构:

在这里插入图片描述

休息一下。哈哈!


最新回复 (0)
    • 都市菜鸟网
      2
        立即登录 立即注册 
返回
发新帖