PHP 手写MVC(二) —— 自动加载和Bootstrap

类自动加载:

在使用类的时候会用 requireinclude 将类加载进来,但是每次都手动加载,会导致一系列问题,比如类重复加载,管理困难等。所以解决上述问题,我们使用单独的一个文件来完成所有类的自动加载。

spl_autoload_register()

该函数可以注册任意数量的自动加载器,当使用尚未被定义的类(class)和接口(interface)时自动去加载。通过注册自动加载器,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。

尽管 __autoload() 函数也能自动加载类和接口,但更建议使用 spl_autoload_register() 函数。 spl_autoload_register() 提供了一种更加灵活的方式来实现类的自动加载(同一个应用中,可以支持任意数量的加载器,比如第三方库中的)。因此,不再建议使用 __autoload() 函数,在以后的版本中它可能被弃用。

core 目录下创建一个 Autoload.php 文件

$ cd tinyphp/core
$ touch Autoload.php

编辑 Autoload.php


// 命名空间和文件目录映射
 'core',
    'app' => 'app',
    'controller' => 'app/controllers',
    'model' => 'app/models',
    'view' => 'app/views',
    'dispatcher' => 'core/dispatcher',
];

/**
 * 参数 $class 表示自动加载的类名
 * 
 * 匿名函数中使用 use 可以使用外部变量
 */
spl_autoload_register(function($class) use ($path) {

    //解析类名,如果使用了命名空间,则会查找 $path 中对于的路径
    $position = strripos($class,'\\');

    $key = substr($class,0,$position);
    $value = $path[$key] ?? '';

    $file = substr($class,$position+1).'.php';

    require APP_PATH.'/'.$value.'/'.$file;
});

spl_autoload_register() 主要实现类自动加载,参数使用的是匿名函数,通过关键字 use 可以使用外部变量 $path,其作用是提供命名空间和路径的对应关系,例如使用 namespace controller,对应的类在路径 app/controllers

使用方式为,在入口文件public/index.php 中,直接 require 该文件即可。

然后我们在core 文件夹下创建一个名为 Application.php 并编辑内容

自动加载完成,待会启动(注册)框架之后就可以看到效果了。

注册启动项

有时候需要在框架启动时,额外加载一些应用配置或用户定义的方法,比如定义常量,加载自定义辅助函数等。

我们在应用目录 app 中创建一个启动脚本 Bootstrap.php,规定该脚本内所有以 init 的方法都会被调用,并在 Application 类的构造函数中调用该脚本

创建 app/Bootstrap.php,编辑内容

Application 类中添加启动项

  • 在构造函数 __construct() 中获取 Bootstrap 实例。
  • run() 方法中遍历 Bootstrap 类中以 init 开头的方法并执行。
boot = new \app\Bootstrap();
    }
    public function run()
    {
        /**
         * 执行启动项
         * 所有init开头的方法都会被调用
         *
         */
        foreach(get_class_methods($this->boot) as $func) {
            if (0 === strpos($func, 'init')) {
                call_user_func([$this->boot,$func]);
            }
        }
    }
...

启动框架

在入口文件 index.php 中启动框架,并执行 run() 方法

run();

进入 public 目录,两种方式执行 php

  • 命令行
$ php index.php
Bootstrap : 1
Bootstrap : 2
  • 使用 PHP 内置服务器
$ php -S localhost:8080

在浏览器输入 http://localhost:8080 , 结果如下

Bootstrap : 1Bootstrap : 2

从结果可以看出,Application 类在实例化的时候执行构造函数,构造函数中完成了启动项的方法调用。

三、总结

本节实现了一个简单的类自动加载和框架的核心类,在启动时加载用户启动项,在 app/Bootstrap.php 中所有以 init 开头的方法都会被依次调用。

下期见

你可能感兴趣的:(php,mvc,自动加载,bootstrap,框架源码)