怎么一步步编写简单的PHP的Framework.docx
《怎么一步步编写简单的PHP的Framework.docx》由会员分享,可在线阅读,更多相关《怎么一步步编写简单的PHP的Framework.docx(87页珍藏版)》请在冰豆网上搜索。
怎么一步步编写简单的PHP的Framework
怎么一步步编写简单的PHP的Framework
自从入职天猫之后,都没怎么时间看oschina了,趁着这段时间参加培训,忙里偷闲,写几篇日志吧。
框架这个概念可能一开始就吓坏了很多PHP的Coder,其实你只要把一个Framework想明白了,其实也没啥,只是别人功能更复杂,细节考虑的更多,代码质量更高。
首先以我自己写的Toper为例讲解一下一般框架的流程(如果大家对我这个不成熟的框架有兴趣,可以在oschina里面搜索一下toper,也可以点击这里打开):
框架最重要的一个文件为入口文件,基本上相当于一个总控开关,所有的请求都需要经过这个文件:
php
define('APP_PATH',dirname(__FILE__).'/..');//应用路径
includeAPP_PATH.'/Library/Toper/Core/FrontController.class.php';//导入前端控制器
$frontController=Tp_FrontController:
:
getInstance();
$frontController->run();
这个文件可以只做一件事情,那就是将控制权交给框架。
大家都知道,一个MVC的应用,所有的请求都必须经过控制器,所以下面我们来编写一个比较简单的控制器:
php
classTest_IndexControllerextendsTp_Controller{
publicfunctionindexAction(){
echo'a';
}
}
这个类只需要继承自Tp_Controller即可,Tp_Controller是Toper的控制器的基类,只要你继承它,你就可以使用框架帮你写好的一系列方法,这样就可以大大减少你自己的工作量了,并且按照规范,函数名也是有意义的,如刚才写的这个函数代表的意义就是访问Test模块IndexContrller这个控制器下面的index这个Action。
那么如何使用模型呢?
实际上非常简单。
php
classTest_IndexModelextendsTp_Model{
publicfunctiontest(){
return'test';
}
}
原理和控制器一样,也是继承框架的类,然后自定义方法,这个地方的方法名没有限制,可以随意。
那么编写模型之后怎么在控制器中调用呢,其实方法就是在控制器中实例化这个模型类,然后调用相应的方法即可,所以修改刚才这个控制器的类:
php
classTest_IndexControllerextendsTp_Controller{
publicfunctionindexAction(){
$model=newTest_IndexModel();
echo$model->test();
}
}
为什么没有include语句?
那是因为框架帮你做完了这一切,当然,框架不是万能的,当你比较熟悉之后,也可以选择不使用自动导入。
刚才我们所做的一切都没有View,那么怎么编写View呢,实际上就是一个HTML文件,框架在View这一层一般是实现标签库,标签库帮你完成一些原来需要用PHP代码才能完成的事情,比如循环遍历,没有标签库可能你就只能在这个View的文件中使用
phpforeach(.....)?
>,这样对于代码分离很不好。
如果你对标签库没有概念,那么你直接看下面的代码吧!
test"type="str"/>
这是一段没有什么难度的代码,唯一的难度可能就是这个print标签,这个标签是框架定义的,它的功能很简单,就是打印一个字符串,你可能觉得这样没什么意义,因为我使用PHP代码也可以很轻易的完成这个功能,但是你想像一下一个做前端的为什么还需要懂PHP呢,如果使用标签库,那么前端开发人员就可以像使用HTML标签一样操作数据了。
我们知道所有的请求都必须要通过控制器,所以外部是无法直接访问这个视图文件的,所以又需要修改控制器的代码了!
!
!
php
classTest_IndexControllerextendsTp_Controller{
publicfunctionindexAction(){
$model=newTest_IndexModel();
echo$model->test();
$this->_display('Test.test');
}
}
如果你学过smarty,你可能对display方法很熟悉,实际上这个函数的功能就是显示一个模板文件!
!
!
好了,一个基本的MVC应用就搭起来了,不是很难吧!
!
!
如何查看效果呢,有两种方式:
1.CGI:
打开浏览器,浏览器访问时,如果您的域名是:
localhost/testframework,那么您可以使用localhost/testframework/Public/index.php/Test/Index/index来访问,如果您设置了虚拟主机,如,那么只需要使用
2.CLI:
通过命令行直接执行PHP脚本时,在Public目录下面使用phpindex.phpm:
testc:
Indexa:
index。
这个例子的代码点此下载
刚才是使用框架实现了一个MVC的应用,那么怎么不使用框架来构建一个MVC应用呢?
下次再讲,请继续关注!
!
!
!
刚把明天吃饭的事情安排好,有了时间,果断继续写吧!
!
!
实际上要自己实现一个MVC的应用也不难,我们知道MVC里面所有内容都必须经过控制器,所以如何把控制权交给控制器呢?
我们需要一个入口文件,入口文件负责将传递的请求交给对应的控制器,实际上也就是完成路由的功能。
为了学习的需要,可以将路由的功能简化,用户通过GET方式将控制器的名和Action的名传递过来,入口文件接收到所有参数之后,按照之前约定的规则include某一个文件,然后实例化这个类,再调用这个类的相应方法。
php
$controller=empty($_GET['c'])?
'Index':
trim($_GET['c']);//设置了默认的控制器
$action=empty($_GET['a'])?
'index':
trim($_GET['a']);//设置了默认的Action
$controllerBasePath=dirname(__FILE__).'/modules/controllers/';
$controllerFilePath=$controllerBasePath.$controller.'Controller.php';
if(is_file($controllerFilePath)){
include$controllerFilePath;
$controllerName=$controller.'Controller';
if(class_exists($controllerName)){
$controllerHandler=new$controllerName();
if(method_exists($controllerHandler,$action)){
$controllerHandler->$action();
}else{
echo'themethoddoesnotexists';
}
}else{
echo'theclassdoesnotexists';
}
}else{
echo'controllernotexists';
}
看着代码行数还是挺多的哦,实际上实现的功能比较简单,就是通过接受通过GET方式传递的控制器名和Action名,如果没有传递,那么调用默认的控制器名或者Action名,当用户传递了控制器名和Action名之后可能会存在这样一个问题,就是通过我们之前约定的规则找不到相应的文件或者类或者方法,那么我们需要显示友好的信息,而不是让PHP抛出一系列的警告,这样对于程序的健壮性很有帮助。
当有了控制器之后,一切都变得简单了,对于模型,我们可以把它看成是一个普通的类,只是在功能上它负责业务逻辑的处理。
php
classIndexModel{
publicfunctiontest(){
return'Helloworld!
';
}
}
作为演示,我们只是在这个模型里面返回一个HelloWorld,那么控制器怎么使用这个模型呢,实际上也就是首先include这个文件,然后实例化类,调用相应的方法。
我们现在修改控制器为:
php
classIndexController{
publicfunctionindex(){
$modelPath=dirname(__FILE__).'/../models/IndexModel.php';
if(file_exists($modelPath)){
include$modelPath;
$model=newIndexModel();
echo$model->test();
}else{
echo'modeldoesnotexists';
}
}
}
现在模型有了,那么怎么连接视图呢?
phpif(isset($var1)){echo$var1;}?
>
写完视图之后,怎么通过控制器调用这个视图呢?
修改控制器至如下:
php
classIndexController{
publicfunctionindex(){
$modelPath=dirname(__FILE__).'/../models/IndexModel.php';
if(file_exists($modelPath)){
include$modelPath;
$model=newIndexModel();
$var1=$model->test();
$viewPath=dirname(__FILE__).'/../views/index.php';
if(file_exists($viewPath)){
include$viewPath;
}else{
echo'viewdoesnotexists';
}
}else{
echo'modeldoesnotexists';
}
}
}这样一个MVC的应用就搭起来了,虽然比较简陋,问题还多多!
!
!
睡不着,继续写一篇吧!
!
按照上一次我讲的内容,一个基本的MVC构架是已经搭建起来了的,但是本身还存在很多问题,如:
模型这一块儿每次连接DB,关闭DB的代码冗余,视图这一块儿还是PHP代码,每个文件要使用很多include代码等等。
要编写一个框架,那么首先就要规定一个标准的目录结构,我们暂时把这个目