构建自己的PHP框架--抽象Controller的基类
上一篇博客中,我们将简单的路由解析和执行,从入口文件public/index.php中移入到框架中。入口文件顿时变得清爽无比~~
但是,去我们的controller里看一下,会看到如下的code:
public function actionView()
{
$body = 'Test body information';
require '../views/site/view.php';
}
难道我们每写一个要去渲染页面的action,都要去找相应路径的view,然后把它require进来。肯定不能这样,所以我们要抽象出一个Controller的基类,实现一个渲染页面的方法,让其他的controller继承,就可以使用相应的方法。
不用说,这个controller的基类肯定要写到框架里。而且也要写两个,一个放在base中,一个放在web中,web中的Controller继承base中的。
先来看在base中的
<?php
namespace sf\base; /**
* Controller is the base class for classes containing controller logic.
* @author Harry Sun <sunguangjun@126.com>
*/
class Controller
{
}
只有一个空类,等待添加内容。
再来看web中的
<?php
namespace sf\web; /**
* Controller is the base class for classes containing controller logic.
* @author Harry Sun <sunguangjun@126.com>
*/
class Controller extends \sf\base\Controller
{
/**
* Renders a view
* @param string $view the view name.
* @param array $params the parameters (name-value pairs) that should be made available in the view.
*/
public function render($view, $params = [])
{
extract($params);
return require '../views/' . $view . '.php';
}
}
可以看到,我们首先从数组中把变量导入到当前的符号表中,然后引入相应的view页面。
然后,在SiteController,我们只需要这么写就可以了。
<?php
namespace app\controllers; use sf\web\Controller; class SiteController extends Controller
{
public function actionTest()
{
echo 'success!';
} public function actionView()
{
$this->render('site/view', ['body' => 'Test body information']);
}
}
然后,访问http://localhost/simple-framework/public/index.php?r=site/view,就可以看到跟之前一样的页面了。
我们来完善一下base中的Controller
<?php
namespace sf\base; /**
* Controller is the base class for classes containing controller logic.
* @author Harry Sun <sunguangjun@126.com>
*/
class Controller
{
/**
* @var string the ID of this controller.
*/
public $id;
/**
* @var Action the action that is currently being executed.
*/
public $action;
}
添加了两个属性,分别来记录当前的controller和action。
然后,我们要在解析router之后,将其赋值,code如下:
<?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);
$controllerNameAll = $this->controllerNamespace . '\\' . $ucController . 'Controller';
$controller = new $controllerNameAll();
$controller->id = $controllerName;
$controller->action = $actionName;
return call_user_func([$controller, 'action'. ucfirst($actionName)]);
}
}
然后我们就可以在controller和view中拿到相应的controller名字和action名字了,将view.php修改如下:
<html>
<head>
<title>title</title>
<head>
<body>
<?php echo $this->id;?><br/>
<?php echo $this->action;?><br/>
<?php echo $body;?>
</body>
</html>
然后我们就可以看到如下的页面了

有人觉得现在大家都前后端分离了,我们不需要用PHP去render一个页面,只需要返回一个josn字符串就好了,这个就更简单了,在web的Controller中添加一个toJson方法即可
/**
* Convert a array to json string
* @param string $data
*/
public function toJson($data)
{
if (is_string($data)) {
return $data;
}
return json_encode($data);
}
将SiteController中的actionTest,修改如下:
public function actionTest()
{
$data = ['first' => 'awesome-php-zh_CN', 'second' => 'simple-framework'];
echo $this->toJson($data);
}
访问http://localhost/simple-framework/public/index.php?r=site/view,你就可以看到相应的json字符串了。
好了,今天就先到这里。项目内容和博客内容也都会放到Github上,欢迎大家提建议。
code:https://github.com/CraryPrimitiveMan/simple-framework/tree/0.3
blog project:https://github.com/CraryPrimitiveMan/create-your-own-php-framework
构建自己的PHP框架--抽象Controller的基类的更多相关文章
- C# Winform下一个热插拔的MIS/MRP/ERP框架13(窗体基类)
作为一个ERP数据处理框架,大部分的开发场景都差不多. 理想中,对于通用数据处理,我的步骤如下: 1.为窗体指定数据来源(数据表/查询等): 2.拖入编辑控件,指定绑定字段: 3.结束. 为此,我设计 ...
- C# Winform下一个热插拔的MIS/MRP/ERP框架12(数据处理基类)
作为ERP等数据应用程序,数据库的处理是重中之重. 在框架中,我封装了一个数据库的基类,在每个模组启动或窗体启动过程中,实例化一个基类即可调用CRUD操作(create 添加read读取 update ...
- 构建自己的PHP框架--抽象框架的内容
上一篇博客中,我们搭建了一个最简单的框架,从单一入口的public/index.php进入,解析出相应的Controller和Action,去执行,渲染出相应的页面或者输出相应的数据. 但是我们可以看 ...
- 构建自己的PHP框架之自动加载类中详解spl_autoload_register()函数
在了解这个函数之前先来看另一个函数:__autoload. 一.__autoload 这是一个自动加载函数,在PHP5中,当我们实例化一个未定义的类时,就会触发此函数.看下面例子: printit.c ...
- C# Winform下一个热插拔的MIS/MRP/ERP框架16(窗体基类场景2)
如果没有特别需求,和场景1一样只变更表名,主键字段,检测字段等名称,不需要写其它代码了. * 清单列表+单笔编辑/保存,适用于大多数基础资料管理以及简单的单据资料录入(当然,排版是要改一改的): * ...
- C# Winform下一个热插拔的MIS/MRP/ERP框架15(窗体基类场景1)
最基础的窗体基类其实是通过应用场景反推的结构. 以下是场景一: 单表应用,普通的数据,比如单位/颜色/特殊字典等使用者少的,无需过多控制的可以使用一个数据表格来管理. 和Excel表格差不多,批量修改 ...
- 深度学习Keras框架笔记之核心层基类
Keras的Layers,就是构成网络的每一层.Keras实现了很多层,包括核心层.卷基层.RNN网络层等诸多常用的网络结构.下面开介绍核心层中包含了哪些内容.因为这个核心层我现在还没有全部用到,所以 ...
- 0014 基于DRF框架开发(02 基类视图 GenericAPIView)
前端于对数据操作的请求基本上就分为四类:增删改查,即增加.删除.修改.查询. 而DRF把前端请求分为两个大类:带ID参数请求和不带ID参数请求. 不带ID参数请求包括:增加.分布多条查询 带ID参数请 ...
- 0013 基于DRF框架开发(01 基类视图 APIView)
之前学习了模型序列化和普通序列化,我们用最简单的视图和url实现了对序列化的操作. 而实际上,象之前那种由DRF自动生成所有的视图和url的情况,在应用是使用很少.而需要用户根据实际业务需求,自定义视 ...
随机推荐
- [XAF] 多级联列表显示
XAF给的例子已经实现,详细可查看例子中的代码. 工作车间--工作中心--机器
- Keeping Async Methods Alive
Consider a type that will print out a message when it’s finalized, and that has a Dispose method whi ...
- 深入探究 WinRT 和 await
在最近发布的使用 Windows 运行时中异步性来始终保持应用程序能够快速流畅地运行这篇博文中,包含了一些如何在 C# 和 Visual Basic 中使用 await 关键字的示例,允许开发人员在使 ...
- Reactnative 随笔一
---恢复内容开始--- 1.ReactDOM.render() React的最基本方法,用于将模板转为HTML语言,并插入指定的DOM节点 将h标签插入example节点 2.HTML语言直接 ...
- iOS网络基础知识
iOS网络基础知识 1.一次HTTP请求的完整过程 (1)浏览器或应用发起Http请求,请求包含Http请求Http(请求),地址(url),协议(Http1.1)请求为头部 (2)web服务器接收到 ...
- Java解析网段下包含的所有IP地址
import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;impor ...
- vs的dll引用机制
vs2012编译的时候,遇到一个问题就是项目A中运行时缺失dll的问题,项目A引用类库B,类库B引用了x,y等dll,编译A项目的时候,出现x没拷贝到bin 目录. 通过跟踪编译输出发现,x没拷贝的原 ...
- RCP:为指定的导航器添加上下文菜单
可以参考Eclipse的Help->Help Content下的: Platform Plug-in Developer Guide > Programmer's Guide > P ...
- Java IO5:字符流
字符流 字节流提供了处理任何类型输入/输出操作的功能(因为对于计算机而言,一切都是0和1,只需把数据以字节形式表示就够了),但它们不可以直接操作Unicode字符,因为上一篇文章写了,一个Unicod ...
- 今天心情好,给各位免费呈上200兆SVN代码服务器一枚,不谢!
开篇先给大家讲个我自己的故事,几个月前在网上接了个小软件开发的私活,平日上班时间也比较忙,就中午一会儿休息时间能抽出来倒腾着去做点.每天下班复制一份到U盘带回去继续摸索,没多久U盘里躺着的文件列表那叫 ...