先上图,有图有真相
1. 加载index文件
index文件是整个项目的唯一入口,任何请求进入项目都是走的index,只是带的参数不一样,然后再在index文件里加载其他文件,相当于把其他文件整个复制到index文件中,但是开发中会更好看。
index.php 文件代码:
<?phpini_set('display_errors', 'on');//开启或关闭PHP异常信息date_default_timezone_set('Asia/Shanghai');define('FD_DS', ????DIRECTORY_SEPARATOR);//定制目录符合define('ROOT', ?????__DIR__ . ??????????????FD_DS);define('CORE', ?????ROOT . 'core' . ????????FD_DS);define('MODEL', ????ROOT . 'model' . ???????FD_DS);define('LIBS', ?????ROOT . 'libs' . ????????FD_DS);define('CONFIG', ???ROOT . 'config' . ??????FD_DS);define('CTRL', ?????ROOT . 'controller' . ??FD_DS);define('LOGS', ?????ROOT . 'logs' . ????????FD_DS);define('STATIC', ???ROOT . 'static' . ??????FD_DS);require_once(CORE . 'core.php');spl_autoload_register('\core\core::load');require "vendor/autoload.php";include LIBS . 'function.php';\core\core::run();
2. 在index文件设置必要信息
ini_set('display_errors', 'on');//开启或关闭PHP异常信息date_default_timezone_set('Asia/Shanghai');
异常信息和时区信息一定开始设置好,如果是正式的项目,异常在生产haunting是一定要关闭的,可以通过配置文件来控制开发和生产环境的区别。包括如果是前后端不分离的架构,session也需要在这里开启。
3. 引入核心文件和设置自动加载类
require_once(CORE . 'core.php');spl_autoload_register('\core\core::load');
引入core文件就不说了,引入了才能调用它的类。
spl_autoload_register 这个函数就有意思了,官网这么解释的
spl_autoload_register — 注册给定的函数作为 __autoload 的实现
就是说,php本身有一个机制,在你使用一个类的时候,如果这个文件还没有加载,就通过这个机制去发现一下包含这个类的文件,如果发现了,就加载进来。但是php默认的方法肯定不满足我们的需求,所以需要自己定制一下。
core文件代码:
namespace core;use core\route;class core{ ???//存储已经加载的文件 ???public static $classArr = array(); ???/** ????* 自动加载函数 ????* @param $class ????* @return bool ????*/ ???public static function load($class) ???{ ???????if (isset($classArr[$class])) ???????????return true; ???????$class = str_replace('\\', '/', $class); ???????$file ?= ROOT . $class . '.php'; ???????if (is_file($file)) { ???????????include $file . ''; ???????????self::$classArr[$class] = $class; ???????????return true; ???????} else { ???????????return false; ???????} ???} ???public static function run() ???{ ???????$route ???= route::Factory(); ???????$arr ?????= $route->active(); ???????$classStr = $arr['ctrl'] . 'Ctrl'; ???????$file ????= CTRL . $classStr . '.php'; ???????$action ??= $arr['action']; ???????if (!file_exists($file)) { ???????????$file ??= CTRL . 'indexCtrl.php'; ???????????$action = 'index'; ???????????$classStr = 'indexCtrl'; ???????} ???????include $file; ???????$classStr = '\\controller\\'.$classStr; ???????$class = new $classStr(); ???????//公共初始化方法 ???????$methods = get_class_methods($class); ???????foreach ($methods as &$v) { ???????????$v = strtolower($v); ???????} ???????if (in_array('init', $methods)) { ???????????call_user_func_array(array($class, 'Init'), array()); ???????} ???????//运行本来的方法 ???????if (method_exists($class, $action)) { ???????????$class->$action(); ???????} elseif(method_exists($class, 'index')){ ???????????$class->index(); ???????}else { ???????????echo 'error'; ???????} ???}}
4. 引入composer的自动加载类
require "vendor/autoload.php";
引入这个文件后,我们再去看这个文件的内容
<?php// autoload.php @generated by Composerrequire_once __DIR__ . '/composer/autoload_real.php';return ComposerAutoloaderInitc3539f052cfb872b6af631934bd5b1d0::getLoader();
这个文件加载了一个叫做autoload_real.php的文件,看名字不难猜出,这个是进一步判断如何自动加载的文件。
调用这个类的getLoader方法,加载了它的自动加载方法,之后我们用composer拉取的第三方库,就也可以自动加载了。
5. 加载常用函数文件
include LIBS . 'function.php';
这个function.php中,我习惯放一些常用的工具函数,比如目前只有的一个debug类,可以调试程序的时候打印一下各种变量的信息。
function debug() { ???if(func_num_args() >= 2) { ???????$var = func_get_args(); ???}else{ ???????$var = current(func_get_args()); ???} ???echo '<pre>'; ???$vardump = false; ???$vardump = empty($var) ? true : $vardump; ???if($vardump) { ???????var_dump($var); ???} else { ???????print_r($var); ???} ???exit();}
不要看这个函数没有参数列表,其实它的参数可以是无限的。func_num_args这个方法就可以拿到调用它时传递的参数数组,然后把它打印在web中,随后中断程序。
6. 调用路由方法
\core\core::run();
这个方法先去调用route类,去获取到控制器和方法的名称,然后加载这个类。这里我定义了一个默认的初始化方法,意思是如果有一个名叫init的方法,不管是自己的方法还是继承过来的方法,都要先调用这个方法。这样做的好处是,之后的业务里可以对接口做统一或者单独的初始化或者拦截设置。
core::run()方法,看上边有整个core文件的代码。
调用的route类代码:
namespace core;class route{ ???private static $in = null; ???private function __construct() ???{ ???} ???public static function Factory() ???{ ???????if (!isset(self::$in)) { ???????????self::$in = new route(); ???????} ???????return self::$in; ???} ???public function active() ???{ ???????$ctrl ??= 'index'; ???????$action = 'index'; ???????if (isset($_SERVER[REQUEST_URI]) && $_SERVER[REQUEST_URI] != '/') { ???????????$path ???= strtok($_SERVER['REQUEST_URI'], '?'); ???????????$patharr = explode('/', trim($path, '/')); ???????????if (isset($patharr[0])) { ???????????????$ctrl = $patharr[0]; ???????????} ???????????if (isset($patharr[1])) { ???????????????$action = $patharr[1]; ???????????} ???????} ???????return array('ctrl'=>$ctrl,'action'=>$action); ???}} ?
所有代码
所有代码都在github上,框架部分在framework分支。
github地址: https://github.com/gaopu1995/hiphp.git
php手撸轻量级开发(二)框架加载
原文地址:https://www.cnblogs.com/alexfly/p/10452964.html