轻松自学ThinkPHP3.0第一天·上午

来源:互联网 发布:d算法 编辑:程序博客网 时间:2024/05/17 05:15

1.0框架概念

     有人解释为,框架是别人写好的一堆类,库,按一定的规则来使用。这种解释是不准确的。

     框架,framework。

     框架是半成品

框架能组装你的代码(与库不同,与工具类不同)

     成熟的框架往往包含了大量的常用库(图片,SESSION,上传等等)


2.0为什么要使用框架

     统一了环境(如,PHP4,5的函数不用考虑,由框架处理);

     简化了大量重复操作,直接上手写与业务相关的代码(如,连接数据库);

     成熟的框架有大量的库文件,调用方便;

     语法相对规范(函数名,类命名等),方便团队协作;

     作为一个程序员,当你连续两次编写同一种业务逻辑的代码时,你就应该考虑将这段代码封装成一个函数或者一个工具类来使用。


开发上的好处

     1)屏蔽了平台,版本的区别

linux与win的区别:权限问题,大小写敏感问题。

当我们将win下写好的代码发布到Linux中时就常会遇到大小写敏感问题。如,index.php和Index.php在win下是同一个文件,在Linux下却表示不同的两个文件。当我们发布项目网站时就可能存在因为文件名的大小写敏感而导致运行出错。使用think php框架时它就会帮我们处理这一点,屏蔽了平台间的差异性。

     具体例子:ThinkPHP框架屏蔽了PHP版本的差异,如,mkdir函数。

     mkdir()函数在php5.0以前是不能递归创建目录的,在5.0及以后可以递归创建目录。框架的mk_dir()函数已经考虑了版本的区别,无论是在php 5.0前后版本都可以递归创建目录,可以放心调用。

     2)不用写大量的重复代码

数据验证功能等,数据库类,分页类等,可以直接在框架的库文件中调用

     3)提供很多成熟的工具(库)

分页类,数据库类,文件上传类,图片处理类等等.便于调用

    4)方便团队合作

框架有自身的命名及代码规范,便于团队之间合作


2.1为什么不用框架

     1)效率低

     PHP是每次HTTP请求过来以后,初始化全部资源(例如,创建数据库连接、加载系统类库,创建缓存等),处理完毕,释放全部资源。

     2)应用门槛上升,学习成本也相对较高

     这对于原本只是定位中小应用的PHP变得尤为尴尬,和PHP的快、糙、猛”的特点相悖。

     3)大型框架考虑的因素过多,开发人员在开发应用时还需要额外关注代码以外的细节过多

     如:非标准约定、冗长的手册、琐碎的配置、复杂的文件目录结构、难以限制的合理约束、千姿百态的类库等等,使大多数程序员开发过程屡遭困惑。提高开发效率也成了一句空话。


     具体分析:

     ①框架代码多,降低了运行效率

     通过Zend Framework 框架输出一个”hello,world“,框架在运行时前后需要引入上百个文件;TP(ThinkPHP)也需要引入将近10个文件。

     PHP作为脚本语言,不能常驻内存,每次执行结束后内存中关于PHP文件的相关的资源都会被清空,这就会在每次HTTP请求发送过来时,都要初始化整个框架(将框架载入内存),开销很大,影响效率。

     对比Java程序,Java程序可以常驻内存,首次执行Java程序时,可以将Java框架载入内存,以后执行时可以不用再次载入内存,不影响效率。

     附:脚本语言都有不能常驻内存的特点?

     ②在web应用的开发语言中,PHP具有”快、糙、猛“的特点

     用了框架后,代码”转弯“多,与本身的特点相悖。

     ③框架本身也是有学习成本的

     使用一件工具本身是为了降低成本,但是付出的学习成本却比能够降低的成本高。

     有一些框架,命名规范非常复杂,继承关系复杂,导致开发效率降低


2.2到底用不用框架?

     1:用不用框架?

      用!
     分析:

     1)硬件效率的发展速度远超软件效率

     大内存,大硬盘,高带宽,已不必把程序效率放在首位考虑,而是把开发效率放在首位。

     2)PHP已经走向大企业应用,不再是草根语言

     如,百度贴吧、facebook等。(facebook考虑到PHP不能常驻内存,自行写了一个hihop,可以将PHP代码转化成C++代码)

     在网站开发中,PHP已经占有了70%的市场份额。

     3)开发中的个人英雄时代已经成为历史,大家都要适应团队合作

     在项目开发的过程中,如果不使用框架,很难去规范不同程序员的编码习惯,这就让团队很难进行合作开发,影响开发的效率。使用框架,能够使程序之间达成一种统一的约束,共同遵守框架的规范,有利于团队的合作。


     2:学不学框架?

     学

     你学的框架本身(比如ThinkPHP,ZendFramework,cakePHP),未必能在工作中用上(有的公司可能会自己内部编写一个小型框架来使用),但是框架的思想,肯定会用上

     框架的种类有很多种,学习框架的目的在于掌握框架的思想,在之后遇到其他类型的框架类型时也可以很快的上手。


3.0主流框架介绍

     Zend FrameworkCakePHPYiiThink PHPCI...

3.1Zend framework

     Zend framework(简写ZF)是由Zend公司支持开发的完全基于PHP5的开源PHP开发框架:
     代码完全采用PHP5面向对象编写;
     良好的Ajax支持;
     模块化的结构设计,易于扩展;
     完善的文档资料;
     使用MVC模式来提高程序的可维护性;
     缺点:笨重,学习成本高。

3.2CakePHP

     CakePHP是一个基于PHP,免费且开源的迅速发展起来的框架,最开始是从Ruby On Rails框架里得到灵感(就是照抄的)。
     特点:
     CakePHP是类似于ROR的框架,包括设计方式,数据库操作的Active Record方式;
     设计层面很优雅,没有自带多余的library,所有的功能都是纯粹的框架,执行效率还不错;
     数据库层hasOne,hasMany功能很强大,对于复杂业务处理比较合适;
     路由功能,配置功能还不错;
     适合中型应用;
     基本实现了MVC的每一层;
     具有自动操作命令行脚本功能。
     文档比较齐全,在国内推广的比较成功,学习成本中等。

3.3Yii

     Yii是一个纯OOP的通用Web编程框架,和大多数PHP框架一样,Yii是一个MVC框架。
     Yii在设计时借鉴和完成了其他著名web编程框架和应用的思想和工作:
     Prado:这是Yii的思想的注意来源。Yii采用了它的基于部件和事件驱动的编程范式,数据库抽象层,模块应用框架,国际化和本地化以及其他一些东西;
     Ruby on Rails:Yii继承了它的易于配置的特点,还参考了他的活动记录设计模式的实现;
     Jquery:作为javascript框架的基础集成到Yii中;
     Symfony:Yii参考了它的过滤器设计以及插件框架;
     Joom la:Yii参考了它的模块设计以及消息传递体系。

3.4ThinkPHP

     ThinkPHP的思想很大程度上受Java的Struts影响,同时也借鉴了国外很多优秀的框架和模式,使面向对象的开发结构和MVC模式,融合了Struts的思想和TagLib(标签库)、RoR的ORM映射和ActiveRocord模式,封装了CURD和一些常用操作,单一入口模式等。
     在模版引擎、缓存机制、认证机制和扩展性方面均有独特的表现,已经越来越多的受到国内PHP开发人员的认可。
     ThinkPHP在国产框架中位于使用量第一位。

4.0ThinkPHP3.0(简称TP3.0)的特点

     MVC模式+单入口
     核心文件编译执行;
     CBD架构核心Core+行为Behavior+驱动Driver
     面向切面AOP,Aspect-oriented Programming
     比2.0版有架构上的变化。

5.0框架的学习思路

与所有的MVC框架类似,一般来说,都有3个部分。(一般)单一入口,想访问控制器需要从index.php来中转。Model,Controller都有自己独特的命名规范。
学习框架的思路:
如何引入并配置框架,Controller的命名规范和书写规范,Model的命名规范和书写规范,View的书写规范,操作数据库的方式,扩展包/工具/库的功能。

     1)学习TP的用法
     2)研究TP的源码,了解框架的运转机制
     3)总结MVC框架的共性,方便快速学习其他框架

5.1单入口解释

     1:TP框架的引入

     下载ThinkPHP_3.0_Core.zip核心版解压得到ThinkPHP目录,复制到apache的www目录或htdocs目录下的TP目录中。(C:\AppServ\www\TP\)
     1)输出”helo,world“
     ①普通PHP程序输出”hello,world“
<?phpecho "hello,world";?>
     ②使用ThinkPHP框架输出“hello,world”: C:\AppServ\www\TP\02.php
<?php// 引入并配置框架include('./ThinkPHP/ThinkPHP.php');?>
     运行效果:
     
     在运行02.php后打开02.php所在的目录,发现多出了很多的文件,如下图所示:
     


     2)通过ThinkPHP框架输出hello,world
     打开在运行02.php之后产生的Lib目录下的Action目录中的IndexAction.class.php文件:C:\AppServ\www\TP\Lib\Action\ IndexAction.class.php,可以看到文件内如下,这其实就是在引入ThinkPHP框架后默认显示的效果页面。
<?php// 本类由系统自动生成,仅供测试用途class IndexAction extends Action {    public function index(){        header("Content-Type:text/html; charset=utf-8");        echo '<div style="font-weight:normal;color:blue;float:left;width:345px;text-align:center;border:1px solid silver;background:#E8EFFF;padding:8px;font-size:14px;font-family:Tahoma">^_^ Hello,欢迎使用<span style="font-weight:bold;color:red">ThinkPHP</span></div>';    }}
     修改成:
<?phpclass IndexAction extends Action {    public function index(){        header("Content-Type:text/html; charset=utf-8");        echo 'hello,world';    }}
     再次运行02.php文件就会在页面输出hello,world。可以判断,输出的hello,world是调用了IndexAction.class.php中的index方法得到的结果。



     2:疑问:
     我们在地址栏中输入的是02.php在服务器下的地址,并没有输入IndexAction.class.php,那么IndexAction.class.php中的index方法是怎样被调用执行的呢?
     我们在IndexAction.class.php中自定义一个test方法,怎样才能调用这个test方法呢?

     修改IndexAction.class.php,如下:
<?php// 本类由系统自动生成,仅供测试用途class IndexAction extends Action {    public function index(){        header("Content-Type:text/html; charset=utf-8");        echo "hello,world";    }public function test(){header("Content-Type:text/html; charset=utf-8");    echo "测试!";    }}
     在浏览器地址栏中输入:http://localhost/tp/02.php/Index/test,可以看到运行效果如下:

     也就是说,我们自定义的test方法通过这种方式成功地被调用了!
     类比的,我们输入http://localhost/tp/02.php/Index/index,来调用IndexAction.class.php中的index方法。
     (调用IndexAction.class.php中的index方法时可以省略地后面的/Index/index,在运行02.php时会默认调用IndexAction.class.php中的index方法。也就是说,输入http://localhost/tp/02.php/Index/index和输入http://localhost/tp/02.php的运行结果是一样的,对比上面的运行效果也证实了这一点)



     小结:
     Ⅰ.我们从上面的运行结果初步可以得出,http://localhost/tp/02.php/Index/index中的“/Index”表是IndexAction(也就是IndexAction.class.php),而“/index”则表示IndexAction中的index方法。
     Ⅱ.地址栏中,输入的页面访问地址后紧跟着的两个参数,第一个参数对应Lib目录下的Action中的XXAction.class.php,第二个参数对应XXAction.class.php中的XXX方法。

    我们总结的是否是正确的呢?
     验证:
     我们在C:\AppServ\www\TP\Lib\Action中仿照IndexAction.class.php创建一个UserAction.class.php,在该文件中编写一个test方法,测试是否能够通过输入http://localhost/tp/02.php/User/test成功调用UserAction.class.php中的test方法。
     ①创建UserAction.class.php文件:
     

     ②在UserAction.class.php中编写一个test方法:
     UserAction.class.php(位于C:\AppServ\www\TP\Lib\Action目录下)
<?phpclass UserAction extends Action {    public function test(){    echo "测试2!";    }}
     ③浏览器地址栏输入:http://localhost/tp/02.php/User/test


     从运行结果可以看出成功调用了UserAction.class.php中的test方法。

     3:规律总结
     URL与方法调用的规律(从运行规律的角度分析ThinkPHP的执行流程):
     xx.php/XXAction类名/方法名,通过这种地址栏url的输入方式,可以去调用XXAction.class.php中的相应方法。

     在使用ThinkPHP之前,以完成用户注册功能为例,我们可能会编写2个文件reg.php和regOk.php,其中reg.php用于接收POST方式提交过来的用户注册信息,regOk.php用户返回注册成功后返回给用户的提示信息。而在ThinkPHP框架中,reg.php中的业务逻辑写入UserAction.class.php中的reg方法下,regOk.php中的业务逻辑,写入到UserAction.class.php中的regOk方法下。
     这两个方法,再通过URL中的参数来调用.这样,URL中始终只看到一个PHP文件.而不是分别去运行多个PHP文件。这个PHP文件,就是入口文件.这种设计方式---叫做单入口模式。

     如:http://localhost/reg.php,http://localhost/regOk.php,就只需通过http://localhost/tp/02.php/User/reg、http://localhost/tp/02.php/User/regOk,分为2次来调用。

     附:ThinkPHP框架中的Action就相当于MVC模式中的controller控制器。

     4:controller层(Action类)如何去编写
     1)Action类文件所放位置
     Controller层的PHP文件存放在项目目录中的Lib/Action目录下。

     2)controller的命名规范
     以UserAction为例:
     文件名,大驼峰写法,UserAction.class.php;
     类名,大驼峰写法,和文件名保持一致,class UserAction;
     继承关系:最终应该继承自Action类,class UserAction extends Action{};

     说明:
     注意,这里的“最终”,并不需要直接继承Action类,也可以是间接地继承于Action类。如,class BaseAction extends Action,这时,编写一个UserAction继承于BaseAction也是允许的。即,class UserAction extends BaseAction。

     3)controller的源码分析——Action类的源码的初步分析
     以UserAction为例, UserAction类继承于Action类,那么这个Action类(Action.class.php)究竟在哪呢?

     我们进入到C:\AppServ\www\TP\ThinkPHP\Lib目录(ThinkPHP是解压ThinkPHP源码包得到的)下,并没有看到运行02.php后生成的Lib目录中类似的Action目录,而是在Core目录中找到了Action.class.php。

     ①ThinkPHP\Lib目录下的文件
     
    
      ②ThinkPHP\Lib\Core目录下的文件
     

     UserAction类继承于Action类,自然就有Action类的一些属性和方法。UserAction类继承Action类会有那些方法可以使用呢?

     Action.class.php(位于C:\AppServ\www\TP\ThinkPHP\Lib\Core \目录下),部分代码如下:
abstract class Action {    // 视图实例对象    protected $view   =  null;    // 当前Action名称    private $name =  '';    public function __construct() {        tag('action_begin');        //实例化视图类        $this->view       = Think::instance('View');        //控制器初始化        if(method_exists($this,'_initialize'))            $this->_initialize();}…}

     可以看出,Action类的构造函数中会去判断_initialize()方法是否存在,如果存在的话便调用。

     UserAction类继承于Action类,能否调用_initialize()方法呢?
     验证:
     ①修改C:\AppServ\www\TP\Lib\Action中的UserAction.class.php,如下:
<?phpclass UserAction extends Action {    public function test(){    echo "测试2!";    }    protected function _initialize(){    echo "我是控制器,我被调用了!<br>";    }}

     ②测试:浏览器地址栏输入http://localhost/tp/02.php/User/test

     说明:
     Ⅰ._initialize()方法在父类Action类的构造函数中被调用,所以会先显示“我是控制器,我被调用了!”;
     Ⅱ.controller(XXAction类)在实例化时,会首先试图调用自身的_initialize()方法。这是很有用的一个处理方式。
     Ⅲ.举例:
     通过在UserAction类中添加_initialize()方法,在用户进行其他操作之前,在_initialize()方法中增加一个session或cookie检验。这样就可以在用户进行每一个操作之前都对用户的身份进行自动检验。
     用户进行的相关操作,自然是通过/User/reg、/User/login、/User/buy等方式来实例化UserAction类,即:http://localhost/tp/02.php/User/xx。然后再调用UserAction类中的相应的方法,而每一次实例化UserAction类都会自动地去调用_initialize()方法。



0 0