上一篇博客中,我们搭建了一个最简单的框架,从单一入口的public/index.php进入,解析出相应的Controller和Action,去执行,渲染出相应的页面或者输出相应的数据。

但是我们可以看到在public/index.php文件中,是一堆代码,如果之后,我要添加权限/事件等等的机制是不是也要也在这里,那不难想象,不就的将来,index.php就会变成一个巨大无比的php文件。我们当然不想看到这样的情景,所以我们需要将这些内容抽象出来,保持入口文件的简单明了。

那我们要将这些内容抽象到那里去呢?有聪明的同学已经想到了,就是之前在composer.json中定义的位置,我们来看一下composer.json文件:

{
"name": "craryprimitiveman/simple-framework",
"description": "A simple php framework",
"license": "MIT",
"authors": [
{
"name": "harrysun",
"email": "sunguangjun@126.com"
}
],
"require": {},
"autoload": {
"psr-4": {
"sf\\": "src/",
"app\\": ""
}
},
"repositories": [
{"type": "composer", "url": "http://packagist.phpcomposer.com"},
{"packagist": false}
]
}

可以看到autoload里的psr-4里还有个sf\\,他的地址是src/,这就是我们要放抽象出的内容的地方。

有人会问,为什么不直接使用app\\ 作为namespace呢?因为想到之后要将src下的内容做成一个composer包,迁移到vendor中。

下面就正式开始抽象了。

在src下创建两个文件夹,一个是base,一个是web。base用来存放基础的类,web用来存放与web相关的类。因为将来框架可能还要支持php脚本的执行,所以要将base和web分开,将来要加php脚本时,只需要建立一个console的文件夹就好了。

在两个文件夹中分别建立Application.php文件。

先来看在base里的Application.php

<?php
namespace sf\base; use Exception; /**
* Application is the base class for all application classes.
* @author Harry Sun <sunguangjun@126.com>
*/
abstract class Application
{
/**
* @var string the namespace that controller classes are located in.
* This namespace will be used to load controller classes by prepending it to the controller class name.
* The default namespace is `app\controllers`.
*/
public $controllerNamespace = 'app\\controllers'; /**
* Runs the application.
* This is the main entrance of an application.
*/
public function run()
{
try {
return $this->handleRequest();
} catch (Exception $e) {
return $e;
}
} /**
* Handles the specified request.
*/
abstract public function handleRequest();
}

它是一个抽象类,实现了一个简单的run方法,run方法就是去执行以下handleRequest方法。

它定义了一个抽象方法handleRequest,等待被继承,实现。

它定义了一个controllerNamespace属性,记录controller存放的namesapce,默认值是'app\\controllers'。

再来看在web里的Application.php

<?php
namespace sf\web; /**
* Application is the base class for all application classes.
* @author Harry Sun <sunguangjun@126.com>
*/
class Application extends \sf\base\Application
{
/**
* Handles the specified request.
* @return Response the resulting response
*/
public function handleRequest()
{
$router = $_GET['r'];
list($controllerName, $actionName) = explode('/', $router);
$ucController = ucfirst($controllerName);
$controllerName = $this->controllerNamespace . '\\' . $ucController . 'Controller';
$controller = new $controllerName();
return call_user_func([$controller, 'action'. ucfirst($actionName)]);
}
}

是不是觉得很眼熟,其实就是将之前放在index.php中的内容放到Application的handleRequest方法里了。

然后我们需要从入口文件调用到这里的代码,这就很简单了,index.php的内容如下:

<?php
require_once(__DIR__ . '/../vendor/autoload.php'); $application = new sf\web\Application();
$application->run();

直接去new一个web Application的实例,执行run方法就可以了,是不是很简单。

访问一下:http://localhost/simple-framework/public/index.php?r=site/test,你可以看到上一次一样的结果。

好了,今天就先到这里。项目内容和博客内容也都会放到Github上,欢迎大家提建议。

code:https://github.com/CraryPrimitiveMan/simple-framework/tree/0.2

blog project:https://github.com/CraryPrimitiveMan/create-your-own-php-framework

构建自己的PHP框架--抽象框架的内容的更多相关文章

  1. 抛弃EF,20分构建一个属于自己的ORM框架

    Poiuyt_cyc 博客园首页新随笔联系订阅管理随笔 - 11  文章 - 0  评论 - 111 抛弃EF,20分构建一个属于自己的ORM框架 相信EF大家都不陌生了,因为数据库表跟程序实体是一一 ...

  2. [资源共享]C#+AE构建GIS桌面端应用系统框架-全代码

    转自:http://www.cnblogs.com/gispeng/archive/2008/10/06/1304534.html    [资源共享]C#+AE构建GIS桌面端应用系统框架-全代码 ( ...

  3. 013-并发编程-java.util.concurrent.locks之-AbstractQueuedSynchronizer-用于构建锁和同步容器的框架、独占锁与共享锁的获取与释放

    一.概述 AbstractQueuedSynchronizer (简称AQS),位于java.util.concurrent.locks.AbstractQueuedSynchronizer包下, A ...

  4. 「 从0到1学习微服务SpringCloud 」08 构建消息驱动微服务的框架 Spring Cloud Stream

    系列文章(更新ing): 「 从0到1学习微服务SpringCloud 」01 一起来学呀! 「 从0到1学习微服务SpringCloud 」02 Eureka服务注册与发现 「 从0到1学习微服务S ...

  5. web 框架的本质及自定义web框架 模板渲染jinja2 mvc 和 mtv框架 Django框架的下载安装 基于Django实现的一个简单示例

    Django基础一之web框架的本质 本节目录 一 web框架的本质及自定义web框架 二 模板渲染JinJa2 三 MVC和MTV框架 四 Django的下载安装 五 基于Django实现的一个简单 ...

  6. 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结

    <Java并发编程实战>和<Java并发编程的艺术>           Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用 ...

  7. day06-初识Vuetify框架UI框架和使用域名访问本地项目

    本项目的笔记和资料的Download,请点击这一句话自行获取. day01-springboot(理论篇) :day01-springboot(实践篇) day02-springcloud(理论篇一) ...

  8. 介绍开源的.net通信框架NetworkComms框架 源码分析

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 售价249英镑 我曾经花了 ...

  9. 利用webBrowser获取框架内Html页面内容

    原文:利用webBrowser获取框架内Html页面内容 利用webBrowser获取页面比较简单,MSDN下有示例,在这里不必多说. 可是一些 HTML 文档由“框架”构成,或可以存放它们自己独特 ...

随机推荐

  1. Bootstrap 导航栏和登陆框

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  2. 自学日记--JavaScript 001

    1.1输出内容: document.write(); 1.2警告语句: alert(); 1.3确认语句: comfirm(str); 返回值:boolean  确认返回true  取消返回false ...

  3. Top ShooterHDU2863&&继续xxx定律HDU3784

    继续xxx定律 HDU3784 先看这个题目:HDU3782 #include<iostream> #include<algorithm> #include<stdio. ...

  4. kali基本设置

    一.更换比较快的软件源 修改sources.list文件(su): leafpad /etc/apt/sources.list #debain源 deb http://mirrors.163.com/ ...

  5. Resellerclub –Cpanel 主机中如何设置 index 缺省首页

    管理面板,点击[文件管理器],如图: ],如图 1. 进入 cPanel 管理面板,点击[文件管理器],如图: 选中[主目录] 显示隐藏文件],如图: ],如图 2. 选中[主目录]和[显示隐藏文件] ...

  6. [原创]cocos2dx加载网络图片&异步加载图片

    [动机] 之前看到一款卡牌游戏,当你要看全屏高清卡牌的时候,游戏会单独从网络上下载,本地只存了非高清的,这样可以省点包大小,所以我萌生了实现一个读取网络图片的类. [联想] 之前浏览网页的时候经常看到 ...

  7. Django如何搭建服务器

    建立django站点: 新建Django项目,我这里是使用命令创建项目的. django-admin startproject HelloDjango  创建HelloDjango项目 然后进入到He ...

  8. Linux下PHP安装oci8扩展

    PHP通常搭配Mysql使用,但有时候也会连接到Oracle数据库.安装PHP的oci8扩张之前,需要先安装Oracle Instant Client( basic 或 basic lite 版就行了 ...

  9. dojo/dom-style样式操作学习笔记

    基础总结 一个元素的样式信息由三个来源根据层叠规则确定.三个来源分别是: 由DOM元素style特性设置的内联样式 由style元素中嵌入的样式规则 由link元素引入的外部样式表 元素的样式 任何支 ...

  10. Winform文件下载之WinINet

    在C#中,除了webclient我们还可以使用一组WindowsAPI来完成下载任务.这就是Windows Internet,简称 WinINet.本文通过一个demo来介绍WinINet的基本用法和 ...