搭建自己的PHP框架心得(一)

前言

说到写PHP的MVC框架,大家想到的第一个词--“造轮子”,是的,一个还没有深厚功力的程序员,写出的PHP框架肯定不如那些出自大神们之手、经过时间和各种项目考验的框架。但我还是准备并且这么做了,主要是因为:

  • 认为有关PHP的方方面面都了解了,但自己学习PHP的时间还短,基础并不扎实,很多常用函数的参数还偶尔要查手册,而且对于PHP的一些较新的特性如命名空间、反射等只是简单的看过,并没有能实际应用过。
  • PHP的知识多且杂,一个普通的项目往住是业务逻辑代码为主,而框架是一个能把这些知识点能融汇在一起的项目。
  • 在自己写一个框架的时候,也会参考一些我使用过的框架如TP/CI/YII等的源码,在自己看源码时也能帮助自己理解框架,更容易接受以后要使用的框架。

所以说,这次造轮子的目的不是为了造轮子而是为了在造轮子的过程中熟悉其工艺,总结轮子特点,更好的使用轮子。

如果说写一个完整的PHP框架,那需要掌握的PHP知识点非常多,像设计模式、迭代器、事件与钩子等等,还有许多基础知识的灵活应用。我自认为这些还无法完全掌控,所以我的步骤是先自己搭建一个骨架,然后参考借鉴不同的PHP框架的特点,将其慢慢完善。因为工作原因,而且晚上还要补算法、网络等编程基础,PHP框架部分可能只有周末有时间更新,我会在进行框架功能更新之后,总结使用的知识点,更新博文。

首先放上框架的目前源码:GITHUB/zhenbianshu

框架整体

首先自己总结一下PHP的MVC框架的工作流程:

简单来说,它以一个入口文件来接受请求,选择路由,处理请求,返回结果。

当然,几句话总结完的东西实际上要做的工作很多,PHP框架会在每次接受请求时,定义常量,加载配置文件、基础类,根据访问的URL进行逻辑判断,选择对应的(模块)控制器和方法,并且自动加载对应类,处理完请求后,框架会选择并渲染对应的模板文件,以html页面的形式返回响应。在处理逻辑的时候,还要考虑到错误和异常的处理。

1、作为MVC框架,一定要有一个唯一的入口文件来统领全局,所有的访问请求都会首先进入这个入口文件,如我框架根目录的index.php,在里面,我定义了基本文件夹路径,当前环境,并根据当前环境定义错误报告的级别。

2、PHP中加载另外的文件,使用require和include,它们都是将目标文件内容加载到当前文件内,替换掉require或include语句,require是加载进来就执行,而include是加载进来在需要的时候执行,而它们的_once结构都是表示在写多次的时候只执行一次。

3、框架内的配置变量等使用专用的配置文件来保存,这里我仿照了TP里的数组返回法,用了一个compileConf()函数来解析数组,将数组的键定义为常量,值为数组的值。

if (!function_exists('compile_conf')) {
    function compileConf($conf) {
        foreach ($conf as $key => $val) {
        if(is_array($val)){
             compileConf($val);
            }else{
            define($key, $val);
            }
        }
     }
 }
 compileConf(require_once CONF_PATH.'config.php');

命名空间和自动加载

为什么把命名空间和自动加载放到一块说呢?

在一个PHP项目中,类特别多的时候,如果类名重复的话就会造成混乱,而且相同文件夹内也不能存在同名的文件,所以这时候命名空间和文件夹就搭档出场了。文件夹就是一个一个的盒子,命名空间在我理解就像是一个标签,盒子对应标签。我们定义类时,把各种类用不同的盒子分别装好,并贴上对应的标签。而在自动加载类时,我们根据标签(命名空间)可以很轻易找到对应的盒子(文件夹)然后找到对应的类文件。

而类的自动加载,我们知道的__autoload()魔术函数,它会在你实例化一个当前路径找不到的对象时自动调用,根据传入的类名,在函数体内加载对应的类文件。

现在我们多用spl_autoload_register()函数,它可以注册多个函数来代替__autoload函数的功能,我们传入一个函数名为参数,spl_autoload_register会将这个函数压入栈中,在实例化一个当前路径内找不到的类时,系统将会将函数出栈依次调用,直到实例化成功。

spl_autoload_register('Sqier\Loader::autoLoad');

class Loader {
public static function autoLoad($class) {
    //如果有的话,去除类最左侧的\
    $class = ltrim($class, '\\');
    //获取类的路径全名
    $class_path = str_replace('\\', '/', $class) . EXT;
    if (file_exists(SYS_PATH . $class_path)) {
        include SYS_PATH . $class_path;
        return;
    }
    if (file_exists(APP_PATH . $class_path)) {
        include APP_PATH . $class_path;
        return;
    }
}

现在Loader类还是一个简单的类,待以后慢慢完善。

路由选择

接下来就是路由选择了,其本质是根据当前定义的全局URL模式选择合适的方法来分析传入的URI,加载对应的类,并实现对应的方法。

class Router {
public static $uri;

public static function bootstrap() {
    self::$uri = $_SERVER['REQUEST_URI'];
    switch (URL_MODE) {
        case 1: {
            self::rBoot();
            break;
        }
        default: {
            self::rBoot();
        }
    }
}

public static function rBoot() {
    $router = isset($_GET['r']) ? explode('/', $_GET['r']) : [
        'index',
        'index'
    ];
    $cName = 'Controller\\' . ucfirst($router[0]);
    $aName = isset($router[1]) ? strtolower($router[1]) . 'Action' : 'indexAction';
    $controller = new $cName();
    $controller->$aName();
    }
}

这样,我在地址栏输入 zbs.com/index.php?r=index/login 后,系统会自动调用/app/Controller/Index.php下的login方法。完成了这么一个简单的路由。

后续

接下来我会优化现有的工具类,添加显示层,添加数据库类,还会将一些别的框架里非常cool的功能移植进来~

待续...

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏惨绿少年

EduSoho程序上线实录

1.1 修改配置文件 [root@web01 nginx]# cat /application/nginx/conf/extra/edusoho.conf s...

34000
来自专栏枕边书

PHP模拟发送POST请求之五curl基本使用和多线程优化

今天来介绍PHP模拟发送POST请求的重型武器——cURL函数库的使用和其多线程的优化方法。 说起cURL函数,可谓是老生常谈,但网上许多资料都在关键部分语焉不...

53700
来自专栏贤羽的前端小栈

探索 PHP 与 Vue 通用直出模板方案

我们通常说的“页面直出”,其实就是服务端渲染(SSR, Server-Side Render)。最初的 JS SPA 方案有个常见的问题,就是脚本没有加载执行完...

3.3K20
来自专栏腾讯开源的专栏

【 开源公告 】基于协程和 swoole 驱动的高性能 PHP 框架 TSF 正式开源

TSF是一套基于协程和 swoole 驱动的高性能 PHP 框架,可以帮助开发者快速开发和部署具备高 IO 吞吐能力的 HTTP/TCP/UDP 服务。

92410
来自专栏运维前线

CentOS 7 配置php语言开发环境

CentOS 7 配置php语言开发环境 初始化设置参考:http://blog.csdn.net/wh211212/article/details/5292...

52280
来自专栏云加头条

智能云上手指南:如何使用腾讯云开放的图片鉴黄能力?

今天,腾讯云发布2017战略新品——智能云,对于普通开发者而言,现在可以通过腾讯云开发者实验室0门槛体验优图鉴黄等AI能力。

1K10
来自专栏运维前线

使用CentOS7 kvm虚拟机安装蓝鲸社区版(3.15)

使用C7 kvm虚拟机安装蓝鲸平台 蓝鲸介绍 蓝鲸官网: http://bk.tencent.com/ 蓝鲸社区版本下载:http://bk.tencent.c...

40260
来自专栏张宁的专栏

【腾讯云的1001种玩法】AMH 4.2 升级Nginx与PHP实战练习与笔记

最近对AMH的系统比较感兴趣,特拿来了AMH 4.2来尝试下对其内核版本升级一下,并做了笔记供需要的同学参考。前几天在对张宁网进行更新改版,配置SSL的时候碰见...

64900
来自专栏Script Boy (CN-SIMO)

Deprecated: Methods with the same name as their class will not be constructors in a future version o

<?php class Car { var $color = "add"; function Car($color="green") { ...

23400
来自专栏郑科的专栏

PHP7 新特性简介(一)

PHP7是PHP编程语言全新的一个版本,在性能方面获得了极大的提升。官方的文档显示,PHP7可以达到PHP5.x版本两倍的性能。同时还提供了很多其他语言流行的语...

72500

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励