先上图,有图有真相

1. 加载index文件

index文件是整个项目的唯一入口,任何请求进入项目都是走的index,只是带的参数不一样,然后再在index文件里加载其他文件,相当于把其他文件整个复制到index文件中,但是开发中会更好看。

index.php 文件代码:

  1. <?php
  2. ini_set('display_errors', 'on');//开启或关闭PHP异常信息
  3. date_default_timezone_set('Asia/Shanghai');
  4. define('FD_DS', DIRECTORY_SEPARATOR);//定制目录符合
  5. define('ROOT', __DIR__ . FD_DS);
  6. define('CORE', ROOT . 'core' . FD_DS);
  7. define('MODEL', ROOT . 'model' . FD_DS);
  8. define('LIBS', ROOT . 'libs' . FD_DS);
  9. define('CONFIG', ROOT . 'config' . FD_DS);
  10. define('CTRL', ROOT . 'controller' . FD_DS);
  11. define('LOGS', ROOT . 'logs' . FD_DS);
  12. define('STATIC', ROOT . 'static' . FD_DS);
  13. require_once(CORE . 'core.php');
  14. spl_autoload_register('\core\core::load');
  15. require "vendor/autoload.php";
  16. include LIBS . 'function.php';
  17. \core\core::run();

2. 在index文件设置必要信息

  1. ini_set('display_errors', 'on');//开启或关闭PHP异常信息
  2. date_default_timezone_set('Asia/Shanghai');

异常信息和时区信息一定开始设置好,如果是正式的项目,异常在生产haunting是一定要关闭的,可以通过配置文件来控制开发和生产环境的区别。包括如果是前后端不分离的架构,session也需要在这里开启。

3. 引入核心文件和设置自动加载类

  1. require_once(CORE . 'core.php');
  2. spl_autoload_register('\core\core::load');

引入core文件就不说了,引入了才能调用它的类。

spl_autoload_register 这个函数就有意思了,官网这么解释的

spl_autoload_register — 注册给定的函数作为 __autoload 的实现

就是说,php本身有一个机制,在你使用一个类的时候,如果这个文件还没有加载,就通过这个机制去发现一下包含这个类的文件,如果发现了,就加载进来。但是php默认的方法肯定不满足我们的需求,所以需要自己定制一下。

core文件代码:

  1. namespace core;
  2. use core\route;
  3. class core
  4. {
  5. //存储已经加载的文件
  6. public static $classArr = array();
  7. /**
  8. * 自动加载函数
  9. * @param $class
  10. * @return bool
  11. */
  12. public static function load($class)
  13. {
  14. if (isset($classArr[$class]))
  15. return true;
  16. $class = str_replace('\\', '/', $class);
  17. $file = ROOT . $class . '.php';
  18. if (is_file($file)) {
  19. include $file . '';
  20. self::$classArr[$class] = $class;
  21. return true;
  22. } else {
  23. return false;
  24. }
  25. }
  26. public static function run()
  27. {
  28. $route = route::Factory();
  29. $arr = $route->active();
  30. $classStr = $arr['ctrl'] . 'Ctrl';
  31. $file = CTRL . $classStr . '.php';
  32. $action = $arr['action'];
  33. if (!file_exists($file)) {
  34. $file = CTRL . 'indexCtrl.php';
  35. $action = 'index';
  36. $classStr = 'indexCtrl';
  37. }
  38. include $file;
  39. $classStr = '\\controller\\'.$classStr;
  40. $class = new $classStr();
  41. //公共初始化方法
  42. $methods = get_class_methods($class);
  43. foreach ($methods as &$v) {
  44. $v = strtolower($v);
  45. }
  46. if (in_array('init', $methods)) {
  47. call_user_func_array(array($class, 'Init'), array());
  48. }
  49. //运行本来的方法
  50. if (method_exists($class, $action)) {
  51. $class->$action();
  52. } elseif(method_exists($class, 'index')){
  53. $class->index();
  54. }else {
  55. echo 'error';
  56. }
  57. }
  58. }

4. 引入composer的自动加载类

  1. require "vendor/autoload.php";

引入这个文件后,我们再去看这个文件的内容

  1. <?php
  2. // autoload.php @generated by Composer
  3. require_once __DIR__ . '/composer/autoload_real.php';
  4. return ComposerAutoloaderInitc3539f052cfb872b6af631934bd5b1d0::getLoader();

这个文件加载了一个叫做autoload_real.php的文件,看名字不难猜出,这个是进一步判断如何自动加载的文件。

调用这个类的getLoader方法,加载了它的自动加载方法,之后我们用composer拉取的第三方库,就也可以自动加载了。

5. 加载常用函数文件

  1. include LIBS . 'function.php';

这个function.php中,我习惯放一些常用的工具函数,比如目前只有的一个debug类,可以调试程序的时候打印一下各种变量的信息。

  1. function debug() {
  2. if(func_num_args() >= 2) {
  3. $var = func_get_args();
  4. }else{
  5. $var = current(func_get_args());
  6. }
  7. echo '<pre>';
  8. $vardump = false;
  9. $vardump = empty($var) ? true : $vardump;
  10. if($vardump) {
  11. var_dump($var);
  12. } else {
  13. print_r($var);
  14. }
  15. exit();
  16. }

不要看这个函数没有参数列表,其实它的参数可以是无限的。func_num_args这个方法就可以拿到调用它时传递的参数数组,然后把它打印在web中,随后中断程序。

6. 调用路由方法

  1. \core\core::run();

这个方法先去调用route类,去获取到控制器和方法的名称,然后加载这个类。这里我定义了一个默认的初始化方法,意思是如果有一个名叫init的方法,不管是自己的方法还是继承过来的方法,都要先调用这个方法。这样做的好处是,之后的业务里可以对接口做统一或者单独的初始化或者拦截设置。

core::run()方法,看上边有整个core文件的代码。

调用的route类代码:

  1. namespace core;
  2. class route
  3. {
  4. private static $in = null;
  5. private function __construct()
  6. {
  7. }
  8. public static function Factory()
  9. {
  10. if (!isset(self::$in)) {
  11. self::$in = new route();
  12. }
  13. return self::$in;
  14. }
  15. public function active()
  16. {
  17. $ctrl = 'index';
  18. $action = 'index';
  19. if (isset($_SERVER[REQUEST_URI]) && $_SERVER[REQUEST_URI] != '/') {
  20. $path = strtok($_SERVER['REQUEST_URI'], '?');
  21. $patharr = explode('/', trim($path, '/'));
  22. if (isset($patharr[0])) {
  23. $ctrl = $patharr[0];
  24. }
  25. if (isset($patharr[1])) {
  26. $action = $patharr[1];
  27. }
  28. }
  29. return array('ctrl'=>$ctrl,'action'=>$action);
  30. }
  31. }

所有代码

所有代码都在github上,框架部分在framework分支。

github地址: https://github.com/gaopu1995/hiphp.git

php手撸轻量级开发(二)框架加载的更多相关文章

  1. php手撸轻量级开发(一)

    聊聊本文内容 之前讲过php简单的内容,但是原生永远是不够看的,这次用框架做一些功能性的事情. 但是公司用自己的框架不能拿出来,用了用一些流行的框架比如tp,larveral之类的感觉太重,CI也不顺 ...

  2. php手撸轻量级开发(三)composer小白入门

    composer介绍 composer是php的一个依赖管理工具,在项目中声明所依赖的外部工具库,会自动安装这些工具库及所依赖的库文件. 对我等初阶工程狮来说,就是拉别人的代码,用别人的库,一个进阶版 ...

  3. 混合开发(一)——WebView开发高级技巧之加载网页以及JavaScript,加载进度条

    混合开发(一)--WebView开发高级技巧之加载网页以及JavaScript,加载进度条 现在关于混合开发也越来越多了,很多人喜欢跟随,比如HB,比如RN,其实这东西很早就有这么一个概念了,而且说实 ...

  4. iframe框架加载完成后执行函数

    var iframe = document.createElement("iframe"); iframe.src = "http://www.baidu.com/&qu ...

  5. 微信小程序开发动感十足的加载动画--都在这里!

    代码地址如下:http://www.demodashi.com/demo/14242.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...

  6. 从零开始实现ASP.NET Core MVC的插件式开发(六) - 如何加载插件引用

    标题:从零开始实现ASP.NET Core MVC的插件式开发(六) - 如何加载插件引用. 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/1171 ...

  7. 页面框架加载完自动执行函数$(function(){});

    页面中有一些大的资源文件,如图片,声音等,如果一个事件绑定写在这些加载资源代码的下方,那么要等资源加载完才会绑定,这样体验不够好. 于是想不等资源加载完,只要框架加载完成就绑定事件,就可以把代码放在以 ...

  8. jquery-事件之页面框架加载后自动执行

    jQuery事件之页面框架加载后自动执行 1)概述 HTML执行是按自上而下编译,而<script>一般写在body结束之前.如果在HTML加载的过程中卡住, 比如加载图片等,没有显示出来 ...

  9. 轻松搞定 easyui datagrid 二次加载的问题(转)

    对于使用url方式的初学者,经常碰到重复请求的问题,这个问题的根源是因为一旦设置了url参数,Datagrid组件在实例化的时候就会做请求,如何避免二次加载这样问题呢,个人觉得注意以下两点基本就可以防 ...

随机推荐

  1. Maven学习 二 Maven环境搭建

    第一步:下载Maven并解压 注意选择镜像地址,选择国内的会快点 解压目录 Maven目录分析 bin:含有mvn运行的脚本 boot:含有plexus-classworlds类加载器框架 conf: ...

  2. merge and saveorupdate

    首先 saveOrUpdate返回void 也就是什么都不返回 而merge会返回一个对象 merge 在执行session.merge(a)代码后,a对象仍然不是持久化状态,a对象仍然不会被关联到S ...

  3. Vue post提交

    vue中的axios 是不直接支持post方法的,所以我们得绕一下路,我目前在登录的时候运用到了,服务器端用php,可以收到数据 let param = new URLSearchParams(); ...

  4. CentOS7 启动中文输入法

    CentOS 系统中是带有中文输入法的(智能拼音),启动方式如下: Applications --> System Tools -->  Setting --> Region &am ...

  5. A股、B股区别

    A股也称为人民币普通股票.流通股.社会公众股.普通股.是指那些在中国大陆注册.在中国大陆上市的普通股票.以人民币认购和交易. A股不是实物股票,以无纸化电子记帐,实行“T+1”交割制度,有涨跌幅(10 ...

  6. bzoj4556(sam)

    二分答案,(具体可见http://blog.csdn.net/neither_nor/article/details/51669114),然后就是判定问题,sa和sam都可以做,用sam写了一下,先用 ...

  7. 32 bit 与 64 bit 程序(1)如何识别?

    一, 怎样判断一个exe可执行程序是32位的还是64位的? 简单的方法: 一般来说在64位的windows7下,打开任务管理器可以知道哪些程序是32位的哪些是64位的,但是因为自己的电脑是64位的wi ...

  8. MFS故障测试及维护总结

    一.测试环境说明: 10.2.2.230 mfsmaster     VIP:10.2.2.130 10.2.2.231 mfsbackup 10.2.2.253 mfsdata01 10.2.2.2 ...

  9. 怎样提供一个好的移动API接口服务/从零到一[开发篇]

    引语:现在互联网那么热,你手里没几个APP都不好意思跟别人打招呼!但是,难道APP就是全能的神吗?答案是否定的,除了优雅的APP前端展示,其实核心还是服务器端.数据的保存.查询.消息的推送,无不是在服 ...

  10. Spring Boot实现热部署

    在Spring Boot实现代码热部署是一件很简单的事情,代码的修改可以自动部署并重新热启动项目. 引用devtools依赖 <dependency> <groupId>org ...