先上图,有图有真相

1. 加载index文件

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

index.php 文件代码:

<?php
ini_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 Composer

require_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手撸轻量级开发(二)框架加载的更多相关文章

  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. Spring MVC 上传和下载文件

    上传文件 Commons FileUpload 元件 Servlet 3.0 本地文件上传特性 HTML 5 下载文件

  2. windows下使用redis c++

    redis是高效key-value NOSQL 数据库 代码开源 windows下使用需要使用微软在redis官方上的改进版 地址 https://redis.io/download 寻找window ...

  3. c#new和override

    new是覆盖父类的虚方法,当用子类构造方法构造父类对象时调用该虚方法调的是父类的方法(视为子类屏蔽了父类的方法,没实现,还是调用父类的方法). override是重写父类的虚方法,当用子类构造方法构造 ...

  4. The current state of generics in Delphi( 转载)

    The current state of generics in Delphi   To avoid duplication of generated code, the compiler build ...

  5. Kali proxychains

    1.什么是proxychains 在linux系统中有很多软件是不支持代理的,但是proxychains 却可以让不支持代理的软件 也能走代理通道,支持HTTP,HTTPS,SOCKS4,SOCKS5 ...

  6. spring中aop事务

    一.事务 二.spring封装了事务管理代码 1.事务操作 2.事务操作对象 (1)因为在不同平台,操作事务的代码各不相同.spring提供了一个接口 (2) PlatformTransactionM ...

  7. A - 饭卡

    电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够).所以大家 ...

  8. 第 1 篇 Scrum 冲刺博客

    各个成员在 Alpha 阶段认领的任务 姓名 Alpha 阶段认领的任务 徐婉萍 创建服务器.域名,环境搭建查询界面及页面的设计,查询方法的编写 谭燕 支出.收入添加界面及设计,收入.支出的方法编写, ...

  9. ubuntu16.04下idea、webstorm等开发工具不能输入中文问题

    问题: ubuntu16.04下idea.webstorm开发工具不能输入中文,就算切换到中文输入法输入的也是英文字母. 解决方案: 1.vim打开开发工具的启动文件(idea下就是idea.sh) ...

  10. nlog 的手动配置

    使用nlog的时候,有时候需要手动配置.比如数据库链接和密码不配在文件里,或者统计配置在一个位置之类的. var config = new NLog.Config.LoggingConfigurati ...