构建本身的PHP框架--抽象框架的内容

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

可是咱们能够看到在public/index.php文件中,是一堆代码,若是以后,我要添加权限/事件等等的机制是否是也要也在这里,那不难想象,不就的未来,index.php就会变成一个巨大无比的php文件。咱们固然不想看到这样的情景,因此咱们须要将这些内容抽象出来,保持入口文件的简单明了。git

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

{
    "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/,这就是咱们要放抽象出的内容的地方。web

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

下面就正式开始抽象了。app

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

在两个文件夹中分别创建Application.php文件。框架

先来看在base里的Application.phpui

<?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方法。this

它定义了一个抽象方法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

相关文章
相关标签/搜索