0

0

一步步编写PHP的Framework(十一)

php中文网

php中文网

发布时间:2016-06-21 08:50:31

|

1360人浏览过

|

来源于php中文网

原创

 

之前讲了怎么让实现跳转和请求的转发,当然,也只是很简单的说了一下,更深的内容需要你自己去读一下具体框架的实现。

现在跳转和转发有了,对于模型的编写可以后面再来,那我就先说一下怎么讲数据从控制器传递到视图,之前我们的实现方式非常丑陋:

1 $viewPath = dirname(__FILE__) . '/../views/index.php';

2 if(file_exists($viewPath)) {

3     include $viewPath;

4 } else {

5     echo 'view does not exists';

6 }

现在我准备用更优雅一点的方式将数据传递到视图,现在先说一下怎么调用:

01

02 class TestController extends Controller {

03     public function test() {

04         $this->_assign(array(

05             'arr' => array(

06                 'test','test2'

07             ),

08             'str' => 'it is a str'

09         ));

10         $this->_display('test');

11     }

12 }

 

这就是今天我写之后的调用方式,如果你学过smarty,那么你会发现这和smarty很相似,的确,我写toper的时候也是受了smarty的影响,最开始的想法是视图这一块就使用smarty,后面想了一下,既然号称是自己的框架,那么视图这一块儿肯定也要全部自己写,虽然如此,但是我后面还是保留了assign,display这种写法,并且只要配置文件修改,完全可以将视图切换到smarty而不使用框架本身的实现。

好像扯得有点远了,首先说一下,为了代码的简单,我将assign和display的实现简化,大家理解思路就好,真实的框架的实现要复杂一些。

首先assign,它的功能是为变量赋值,这里我假设传递的参数都是关联数组,也就是常说的HashTable,它不应该直接调用View的接口,这接口实现怎么赋值:

1 protected  function _assign(Array $arr) {

2         View::assign($arr);

3     }

 

为了处理视图这一块的数据存储和展示,我定义了View.php这个文件,View::assign这个方法是它的一个静态方法,当然,实现的功能大家都懂的。。。

            具体View.php中怎么实现的呢?

1 private static $_data = array();

2     public static function assign($arr) {

3         foreach($arr as $key => $val) {

4             if(!is_int($key)) {

5                 //过滤掉如array('test','test2')这种数据

6                 self::$_data[$key] = $val;

7             }

8         }

9     }

由于assign是静态方法,数据又需要存储到这个类,所以需要定义一个静态的成员变量$_data,这个变量存储控制器传递的数据。因为之前在控制器的assign中已经进行了类型提示,所以可以保证在View中的assign传递的形参都是数组,现在只需要一个foreach然后依次存储即可,那为什么不直接使用self::$_data = $arr呢,这样只有一句话呢?

首先,数组中的数据有些可能是不对的,比如array('test','test2')我就不懂数据test和test2到底代表了什么,这样的数据应该在assign中就被剔除掉,如果你要求比较严苛,也可以直接给用户提示警告。

其次,有可能用户多次调用assign,如果直接使用引用,那么第二次调用assign就会把第一次的数据弄丢,这样是不可容忍的。

好,赋值搞定,然后就是怎么显示的问题了,在控制器中,还是直接调用接口,而不负责内部实现,但是在调用接口之前需要进行一定的格式化:

01 protected function _display($str) {

02         if(is_string($str)) {

03             $str = str_replace(array(

04                 '.','#'

05             ),array(

06                 '/','.'

07             ),$str);

08             View::display(MODULES_PATH . View::VIEW_BASE_PATH . $str . '.php');

09         }

10     }

为了视觉上的美观和其他一些XXX的原因,我们可以将表示路径的/在作为实参传递的时候变成.,这样假设要调用test/test2.php,那么只需要传递test.test2.php即可。当然,这样也存在一个问题,有时候需要使用.,就像刚才这个例子,实际上test.test2.php会被解析为test/test2/php,这样实际上是有问题的,那么怎么解决呢,我使用一个#代表.,这样刚才这个传递的时候就变成了test.test2#php。这样还有一个问题,.php基本上每个页面都有,那为什么还要传递进去呢,直接框架帮你加上就好了嘛,所以用户只需要输入test.test2就好,这样从逻辑上也容易理解,test模块下面的test2这个视图文件。如果你用过thinkphp,你会发现这和它的写法很类似,实际上我在最开始写的时候就是边看thinkphp源码边写的,所以很多东西都借鉴了它的思想。我个人比较讨厌使用#,所以我基本上在视图文件中没有使用过#,因为我觉得你自己不会这么无聊,去写类似于test.view.php这样的无意义的文件名,直接test.php就好了,这样的名字框架又帮你解决了一部分,所以基本上不存在这个问题了。

这儿还出现了一个常量View::VIEW_BASE_PATH,这个常量代表的含义是视图根目录的路径,这样传递进去的实际上是一个实际的绝对路径。

由于display是展示这个视图文件,那么肯定会使用include某一个文件,具体的实现如下:

1 public static function display($file) {

2         if(file_exists($file)) {

3             extract(self::$_data);

4             include $file;

5         } else {

6             throw new ViewException(ViewException::NOT_EXISTS_TEMPLATE);

7         }

8     }

extract就是讲数组打散,更多的请查询PHP手册。

这里由于可能这个视图文件不存在,所以需要判定一下,如果视图文件不存在,则直接抛出异常,注意,异常是使用了ViewException,这个类又是新定义的,传递的参数表示这个异常是因为视图模板不存在而引起的。

那我么来看看具体这个异常类的实现:

01

02 class ViewException extends BaseException {

03     const NOT_EXISTS_TEMPLATE = 1;

04     public function __construct($code = 0) {

05         switch($code) {

06             case ViewException::NOT_EXISTS_TEMPLATE:

07                 $msg = 'the template file is not exists';

08                 break;

09             default :

10                 $msg = 'unknown exception';

11                 break;

12         }

13         parent::__construct($msg,$code);

14     }

15 }

这个类它继承了BaseException,由于BaseException实现了debug模式开与关不同情况下展示内容不同,ViewException也具有这个特性,当debug关闭,抛出异常的时候,也只会跳转到错误页,不会直接展示异常,这样的处理更易维护。



PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法
包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法

本专题汇总了包子漫画官网和网页版入口,提供最新章节抢先看方法、正版免费阅读指南,以及稳定访问方式,帮助用户快速直达包子漫画页面,无广告畅享全集漫画内容。

47

2026.02.10

MC.JS网页版快速畅玩指南_MC.JS官网在线入口及免安装体验方法
MC.JS网页版快速畅玩指南_MC.JS官网在线入口及免安装体验方法

本专题汇总了MC.JS官网入口和网页版快速畅玩方法,提供免安装访问、不同版本(1.8.8、1.12.8)在线体验指南,以及正版网页端操作说明,帮助玩家轻松进入MC.JS世界,实现即时畅玩与高效体验。

34

2026.02.10

谷歌邮箱网页版登录与注册全指南_Gmail账号快速访问与安全操作教程
谷歌邮箱网页版登录与注册全指南_Gmail账号快速访问与安全操作教程

本专题汇总了谷歌邮箱网页版的最新登录入口和注册方法,详细提供官方账号快速访问方式、网页版操作教程及安全登录技巧,帮助用户轻松管理Gmail邮箱账户,实现高效、安全的邮箱使用体验。

25

2026.02.10

铁路12306订票与退改全攻略_高效购票与座位选取技巧
铁路12306订票与退改全攻略_高效购票与座位选取技巧

本专题全面汇总铁路12306订票、退票、改签及候补订单操作技巧,提供车厢座位分布参考、抢票攻略和高铁安检注意事项,帮助新手用户快速掌握高效购票与退改流程,提高出行效率和体验。

31

2026.02.10

TensorFlow2深度学习模型实战与优化
TensorFlow2深度学习模型实战与优化

本专题面向 AI 与数据科学开发者,系统讲解 TensorFlow 2 框架下深度学习模型的构建、训练、调优与部署。内容包括神经网络基础、卷积神经网络、循环神经网络、优化算法及模型性能提升技巧。通过实战项目演示,帮助开发者掌握从模型设计到上线的完整流程。

0

2026.02.10

Vue3组合式API与组件开发实战
Vue3组合式API与组件开发实战

本专题讲解 Vue 3 组合式 API 的核心概念与应用技巧,深入分析响应式系统、生命周期管理、组件设计与复用策略。通过完整项目案例,指导前端开发者实现高性能、结构清晰的 Vue 应用,提升开发效率与代码可维护性。

4

2026.02.10

Go语言微服务架构与gRPC实战
Go语言微服务架构与gRPC实战

本专题面向有 Go 基础的开发者,系统讲解微服务架构设计与 gRPC 的高效应用。内容涵盖服务拆分、RPC 通信、负载均衡、错误处理、服务注册与发现等关键技术。通过实战案例,帮助开发者搭建高性能、可扩展的 Go 微服务系统。

1

2026.02.10

React 18状态管理与Hooks高级实践
React 18状态管理与Hooks高级实践

本专题专注于 React 18 的高级开发技术,详细讲解 useState、useEffect、useReducer、useContext 等 Hooks 的使用技巧,以及 Redux、Zustand 等状态管理工具的集成与优化方法。通过真实案例,帮助前端开发者构建可维护、性能优良的现代 React 应用。

4

2026.02.10

Node.js后端开发与Express框架实践
Node.js后端开发与Express框架实践

本专题针对初中级 Node.js 开发者,系统讲解如何使用 Express 框架搭建高性能后端服务。内容包括路由设计、中间件开发、数据库集成、API 安全与异常处理,以及 RESTful API 的设计与优化。通过实际项目演示,帮助开发者快速掌握 Node.js 后端开发流程。

2

2026.02.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Web Forms  教程
Web Forms 教程

共19课时 | 4万人学习

Web Pages 教程
Web Pages 教程

共64课时 | 23.4万人学习

ASP.NET 教程
ASP.NET 教程

共78课时 | 43.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号