第20章 PHP框架简介
在Web应用领域,随着MVC设计方法、敏捷开发理念的流行,产生了大量的开发框架。使用这些框架来搭建Web应用,可以更快更好地完成项目需求,降低项目开发成本,缩小开发周期。
在PHP方面也出现了大量的MVC开发框架,本章主要介绍几种比较流行的PHP开发框架:Zend Framework、CakePHP、Symfony Project、ThinkPHP、QeePHP和CodeIgniter。最后,着重介绍如何使用PHP“官方”的框架Zend Framework来实现。
20.1 PHP框架的现状和发展
现在的PHP框架状况,就像当时的春秋战国诸子百家齐相争鸣,可谓盛况空前。当然万事都有起因,引发当今PHP框架盛世的却是得益于另外一门语言的框架——RoR(Ruby on Rails)。
当然在RoR流行之前,PHP领域也有不少开发框架,例如Mojavi、WACT、PHPMvc和Seagull等。这些框架虽然也采用了MVC模式、数据库抽象层等技术。但由于当时PHP本身不像现在这样流行,所以这些框架都没有得到大量应用,最终归于沉寂。
但是随着Ruby on Rails的流行,PHP这个流行的Web应用脚本语言也出现了大量的新一代开发框架。与此同时,国内PHP开发者也开始紧跟国外发展,推出了不同的开发框架。
首先出现的第一批框架几乎都是RoR的克隆,例如PHP on Trax(连名字都借鉴Ruby on Rails)和TaniPHP、Akelos等。这些框架最大的特点就是力求100%克隆RoR,不管是采用的架构、设计模式,还是使用方法。这几个框架一开始确实吸引了开发者的注意,但随着开发者的深入了解,这些框架头上的光环逐步褪色。晦涩难懂的架构、糟糕的性能,以及太多的限制,让这些框架难以在实际项目中运用。
此时,许多PHP开发者认为可以借鉴RoR的设计思想,但不应照搬RoR的结构和实现。为此,一些同样推崇快速开发的框架开始在PHP社区出现。这些框架中,CakePHP和Symfony可谓是佼佼者。
看到PHP开发框架的潜在商业价值后,Zend.com联合IBM宣布将要推出一个真正能够发挥PHP优势的开发框架。于是就有了Zend Framework。
在众多框架中,有凭借着独特的架构理念和小巧灵活的特点而异军突起的CodeIgniter,有由我国自主开发并发展势态良好的QeePHP和ThinkPHP。
当然这些框架都有各自的特点与不足,而且它们有各自的设计目标和设计理念,这决定了它们有其适应的范围。在实际开发中,应该根据具体的需求和应用环境选择适合的开发框架。
未来,PHP将成为Web开发领域中越来越重要的平台,因此相信会出现更多更好的开发框架。虽然作为开发者来说,并不一定需要采用某一个框架来解决问题。但正是因为这些不断出现的框架,对使用PHP开发Web应用的理解和把握有了一次次的推动。
20.2 常见PHP框架
在如此多的PHP框架中,如何选择一个适合自己项目的框架是一个很重要的问题。下面就对当前几个流行的框架分别做一个介绍,便于读者更好地选择。
20.2.1 Zend Framework框架
Zend Framework(ZF)是一个开放源代码的PHP开发框架,可用于开发Web程序和服务。ZF100%用面向对象代码实现。ZF中的组件非常独立,每个组件几乎不依赖于其他组件。这样的松耦合结构可以让开发者独立使用组件。我们常称此为“use-at-will”设计。
ZF中的组件可以独立使用,但如果将它们组合起来,就形成了一个强大而可扩展的Web开发框架。ZF提供了强壮而高效的MVC实现,有易于使用的数据库摘要和实现HTML表单解析、校验和过滤的表单组件,这样开发者可以通过这些易用的、面向对象的接口联合所有这些操作。其他组件如Zend_Auth和Zend_Acl通过通用的证书(credential)存储提供用户认证和授权。还有其他实现的客户库来简化访问最流行的可用的Web服务。不论程序需要什么,都可能从Zend Framework中找到经过全面和严格测试的组件来使用,可以极为有效地减少开发时间。
Zend Framework项目的主要赞助者是Zend Technologies,但许多其他公司也贡献了组件或重大功能,例Google、Microsoft和StrikeIron作为伙伴提供了Web服务接口和其他希望给Zend Framework开发者使用的技术。
其含有的主要特性如下:
- 代码完全采用PHP 面向对象编写
- 丰富完善的组件支持
- 模块化的结构设计,易于扩展
- 完善的文档资料
- 灵活的架构设计
- 代码经过严格的单元测试
它包含有很多实用的组件,可以帮助更快速地完成一些常用功能。这里非常简单地介绍了Zend Framework,读者可以通过Zend Framework的官方网站http://framework.zend.com/获取更多的信息,也可从官方网站获取最新版本的Zend Framework。
20.2.2 CakePHP框架
CakePHP是一个运用了诸如ActiveRecord、Association Data Mapping、Front Controller和MVC等著名设计模式的快速开发框架。该项目主要目标是提供一个可以让各种层次的PHP开发人员快速地开发出健壮的Web应用,而又不失灵活性。主要特性有:
- 基于MVC架构
- 视图支持AJAX
- 内置校验框架
- 提供应用程序的基础模块和CRUD代码自动生成功能
- 提供处理session,request,security的组件
- 灵活的视图缓存功能
- 面向对象
- 无须配置:只要安装好数据库
- 兼容PHP 4和PHP 5
CakePHP也有一些不足,就是Model实现得过于复杂,CakePHP中的Model不但尝试封装行数据集,甚至连数据库访问也包含在内。随着应用开发的展开,Model类的高度复杂性和几乎无法测试的特性,使得项目的重构变得困难重重,大大降低了开发效率和应用的可维护性。
可以通过CakePHP的官方网站(http://www.cakephp.org/)了解关于这个框架更多的内容,从其官方网站上也可以下载最新版本和稳定版本的CakePHP。
20.2.3 Symfony Project框架
Symfony是一款用于开发PHP 5项目的Web应用框架,其目的在于加速Web应用的开发及维护,减少重复的编码工作,Symfony对系统需求不高,可以运行在UNIX或Windows系统上,并将敏捷开发的原理(如DRY、KISS或XP等)应用其中。
Symfony的扩展性好,可以整合很多开源项目。它旨在建立企业级的完善应用程序。也就是说,拥有整个设置的控制权:从路径结构到外部库,几乎一切都可以自定义。为了符合企业的开发条例,Symfony还绑定了一些额外的工具,以便于项目的测试、调试及归档。它基于如下的概念:
- 尽可能地兼容所有的应用环境
- 简单安装和配置
- 易于学习
- 支持企业开发
- 依靠惯例而不是配置,支持回滚调用
- 尽量使多数情况简单,但是当需要复杂时,依然能够支持
- 包括大多数通用的Web特性
- 遵从大多数的Web最佳实践和Web设计模式
- 非常易读的代码,非常高的可维护性
- 开源
所以对于一个企业级的应用项目,使用Symfony Project框架是非常合适的。更多的信息可以进入它的官方网站(http://www.symfony-project.org/)了解,并可以下载到最新的框架版本。
20.2.4 ThinkPHP框架
ThinkPHP是一个性能卓越并且功能丰富的轻量级PHP开发框架,本身具有很多的原创特性,并且倡导“大道至简,开发由我”的开发理念,用最少的代码完成更多的功能,宗旨就是让Web应用开发更简单、更快速。从1.*版本开始就放弃了对PHP 4的兼容,因此整个框架的架构和实现能够得以更加灵活和简单。2.0版本更是在之前的基础上,经过全新的重构和无数次的完善及改进,达到了一个新的阶段,足以达到企业级和门户级的开发标准。
ThinkPHP值得推荐的特性包括。
- 类库导入:ThinkPHP是首先采用基于类库包和命名空间的方式导入类库,让类库导入看起来更加简单清晰,而且还支持冲突检测和别名导入。为了方便项目的跨平台移植,系统还可以严格检查加载文件的大小写。
- URL模式:系统支持普通模式、PATHINFO模式、REWRITE模式和兼容模式的URL方式,支持不同的服务器和运行模式的部署。
- 编译机制:独创的核心编译和项目的动态编译机制,有效减少OOP开发中文件加载的性能开销。
- ORM:简洁轻巧的ORM实现,配合简单的CURD及AR模式,让开发效率大大提高。
- 查询语言:内建丰富的查询机制,包括组合查询、复合查询、区间查询、统计查询、定位查询、动态查询和原生查询。
- 动态模型:无须创建任何对应的模型类,轻松完成CURD操作,支持多种模型之间的动态切换。
ThinkPHP是我国自主开发的一套框架,并且有越来越多的人在使用它,呈现出一个后来者居上的形势。如果需要了解更多信息,或者下载框架版本,可以去它的官方网站(http://www.thinkphp.cn/)。
20.2.5 QeePHP框架
QeePHP的前身是FleaPHP,是总结经验并且运用各种最新技术开发的新一代框架。它是一个快速、灵活的开发框架。应用各种成熟的架构模式和创新的设计,帮助开发者提高开发效率、降低开发难度。
它的主要目标是为开发者创建更复杂、更灵活、更大规模的Web应用程序提供一个基础解决方案。运用QeePHP创建应用程序,开发者可以获得更高的开发效率,并且更容易保持应用程序良好的整体架构和细节实现,同时为今后的扩展提供了充分的灵活性。主要特征包括。
- 完全“面向接口”架构,大部分组件都可以单独使用。
- 具有一个微内核。该内核提供各种基础服务,帮助开发者将各个组件组装起来形成完整的应用程序。
- 简单易用、功能强大、高性能的数据库抽象层和表数据入口。
- 为面向对象应用量身打造的Active Record实现,让 PHP 应用程序充分利用面向对象技术带来的优势。
- Web Controls机制,提供了将用户界面组件化的能力,帮助开发者创建复杂易用的用户界面。
- 支持多种流行的模板引擎,保护开发者现有的知识和技能。
- 基于角色的访问控制,以及高度可定制的访问控制组件。
- 丰富的辅助功能,解决开发中最常见的问题。
- 采用限制最少的BSD协议,让企业可以充分利用QeePHP带来的利益。
并且拥有丰富的中文文档和活跃的社区,比较合适中国国民。同样,如果想要继续了解或者下载框架可以访问它的官方网站(http://www.qeephp.com/)。
20.2.6 CodeIgniter框架
CodeIgniter是一个非常小,但很有前景的PHP开发框架。它提供了一个丰富的代码库,其中封装了开发Web应用系统常用到的一些功能,并为访问代码库提供简单的接口与逻辑结构。CodeIgniter主要目的是尽量精减代码量。
CodeIgniter是一个简单快速的PHP MVC框架。EllisLab的工作人员发布了CodeIgniter。许多企业尝试体验过所有PHP MVC框架之后,CodeIgniter都成为赢家,主要是由于它为组织提供了足够的自由支持,允许开发人员更迅速地工作。
自由意味着使用CodeIgniter时,不必以某种方式命名数据库表,也不必根据表命名模型。这使CodeIgniter成为重构遗留PHP应用程序的理想选择,在此类遗留应用程序中,可能存在需要移植的所有奇怪的结构。
CodeIgniter不需要大量代码,也不会要求用户插入类似于PEAR的庞大的库。它在PHP中表现同样良好,允许创建可移植的应用程序。最后,不必使用模板引擎来创建视图,只需沿用旧式的HTML和PHP即可。
除此之外,CodeIgniter拥有全面的开发类库,可以完成大多数Web应用的开发任务。例如,读取数据库、发送电子邮件、数据确认、保存session、对图片的操作等。而且CodeIgniter提供了完善的扩展功能,可以有效帮助开发人员扩展更多的功能。更多的关于CodeIgniter框架的内容,可以访问其官方网站,网址是http://www.codeigniter.com,从这里也可以下载最新版本和稳定版本的CodeIgniter。
20.3 CodeIgniter框架应用
对于一些复杂的Web项目,如果本身没有很好的解决方案的话,选择一款合适的PHP框架或许能起到一个很好的作用,它提供一整套的机制和处理方法。使用它可以帮助用户节省很多的时间,并且易于维护又适合团队合作。本节就来介绍使用一个简单且易用的PHP框架“CodeIgniter”。
20.3.1 CodeIgniter下载安装
CodeIgniter可以直接从其官方网站(http://www.codeigniter.com)下载得到,现在的最新版本是1.7.2版本。解压缩后得到的目录结构如图20.1所示。只要解压缩其中的system目录和index.php文件到网站的根目录下即可完成框架的安装。通过浏览器访问安装的目录,得到的页面如图20.2所示。
图20.1 CodeIgniter压缩包目录 | 图20.2 欢迎页面 |
如果看到以上的欢迎界面表示CodeIgniter已经安装成功。
说明 可以在application/config/config.php文件中,设置基本URL等基本参数。如果需要使用数据库,编辑application/config/database.php即可在这个文件中设置数据库参数。
20.3.2 CodeIgniter的控制器机制
什么是控制器?简而言之,一个控制器就是一个类文件,是以一种能够和URI关联在一起的方式来命名的。在CodeIgniter中,控制器所属的类和普通的PHP类几乎没有区别,唯一有特点的是Controller类的命名方式,它所采用的命名方式可以使该类和URI关联起来。例如下面的URL地址就说明了这个问题。
www.example.com/index.php/blog/
当访问到上面这个地址时,CodeIgniter会尝试找一个名叫blog.php的控制器(controller),然后加载它。当一个controller的名字匹配URI段的第一部分,即blog时,它就会被加载。代码20-1演示创建一个简单的Controller类。
代码20-1 使用CodeIgniter的Controller
<?php class Blog extends Controller //继承自Controller类 { function Blog() //构造函数 { parent::Controller(); //调用父类的构造函数 } function index() //默认的index方法 { echo '你好,世界!'; //你好,世界! } } ?>
以上代码定义了一个Blog,它继承于Controller类,Controller类是CodeIgniter控制器基类,所有的控制器都是需要从这个类派生的。这个例子中用到的方法名是index(),也是CodeIgniter的默认方法。把它保存在system/application/controllers/目录下,以本书的访问地址为例,通过浏览器访问地址http://localhost/php/20/index.php/blog,可以看到如图20.3所示的执行结果。
图20.3 控制器的使用
注意 如果URI的第2部分为空,会默认载入index方法,也就是说,可以将地址写成http://localhost/php/20/index.php/blog/index来访问blog.php。
代码20-2演示了在Blog控制器中加入其他方法,此时的Blog.php如下所示。
代码20-2 为Controller添加方法
<?php class Blog extends Controller //继承自Controller类 { function Blog() //构造函数 { parent::Controller(); //调用父类的构造函数 } function index() //默认的index方法 { echo '你好,世界!'; //你好,世界! } function comments() //新增的方法 { echo "这是新添加的方法!"; //输出 } } ?>
此时通过地址http://localhost/php/20/index.php/blog/comments访问blog.php可以看到如图20.4所示的效果。
图20.4 为Blog控制器新添加的方法
如果URI超过两个部分,那么超过的部分将被作为参数传递给相关方法。如地址www.example.com/index.php/fruit/add/apple/123,URI中的apple和123将被当做参数传递给fruit类的方法add。代码20-3演示了这种用法,仍然以Blog.php为例,完整代码如下所示。
代码20-3 向视图中添加动态数据
<?php class Blog extends Controller //继承自Controller类 { function Blog() //构造函数 { parent::Controller(); //调用父类的构造函数 } function index() //默认的index方法 { echo '你好,世界!'; //你好,世界! } function comments() //新增的方法 { echo "这是新添加的方法!"; //输出 } function write($word) //带参数的方法 { echo "传入的参数值为:{$word}"; } } ?>
假设为方法write()传递参数为“banana”,通过地址http://localhost/php/20/index.php/blog/write/banana访问blog.php,可以看到如图20.5所示的结果。
图20.5 向方法传递参数
20.3.3 CodeIgniter的模型机制
Model是专门用来和数据库打交道的PHP类。在CodeIgniter中,模型对于那些想用传统MVC方式的人来说是可选的。例如,假设读者想用CodeIgniter来做一个Blog。包含可以写一个模型类,里面包含插入、更新、删除Blog数据的方法。下面的例子展示一个普通的模型类:
<?php class Blogmodel extends Model { var $title = ''; var $content= ''; var $date = ''; function Blogmodel() { parent::Model(); //兼容PHP 4,构造函数 } function get_last_ten_entries() { $query = $this->db->get('entries', 10); return $query->result(); } function insert_entry() { $this->title= $_POST['title']; //取得标题 $this->content= $_POST['content']; //取得内容 $this->date = time(); $this->db->insert('entries', $this); } function update_entry() { $this->title=$_POST['title']; $this->content=$_POST['content']; $this->date =time(); $this->db->update('entries', $this, array('id' => $_POST['id'])); } } ?>
说明 上面用到的函数是Active Record数据库函数。为了简单一点,这里直接使用了$_POST。不过,这不太好,平时应该使用输入类:$this->input->post('title')。
CodeIgniter中的Model类文件存放在application/models/目录,也可以在里面建立子目录。最基本的模型类必须像这样:
class Model_name extends Model { function Model_name() { parent::Model(); } }
其中Model_name是模型类的名字,类名的首字母必须大写,并且确保自定义的Model类继承了基本Model类。Model类的文件名应该是Model类名的小写版,一个Model类的代码如下所示。
class User_model extends Model { function User_model() { parent::Model(); } }
那么该Model类对应的文件名是application/models/user_model.php。Model通过Controller载入,如下代码所示。
$this->load->model('Model_name');
其中Model_name是要载入的Model类的名字。模型载入后,就可以通过如下代码所示的方法使用它。
$this->load->model('Model_name'); $this->Model_name->function();
20.3.4 CodeIgniter的视图机制
在CodeIgniter中,视图不直接调用,必须被一个控制器来调用。使用文本编辑器创建一个名为blogview.php的文件,如代码20-4所示。
代码20-4 视图文件
<html> <head> <title>我的博客</title> </head> <body> }h1 <h1>欢迎来到我的博客!</h1> </body> </html>
将该代码保存到application/views/目录下。然后,需要使用某个方法载入该视图文件。这个方法的用法如下所示:
$this->load->view('name')
上面的代码中,name是需要载入的视图文件的名字,文件的后缀名没有必要写出。接下来,在blog控制器的文件blog.php中,写入这段用来载入视图的代码,此时完整的blog.php如代码20-5所示。
代码20-5 在Controller中载入视图
<?php class Blog extends Controller //继承自Controller类 { function Blog() //构造函数 { parent::Controller(); //调用父类的构造函数 } function index() //默认的index方法 { $this->load->view('blogview'); //载入视图 } function comments() //新增的方法 { echo "这是新添加的方法!"; //输出 } function write($word) //带参数的方法 { echo "传入的参数值为:{$word}"; } } ?>
此时再通过地址http://localhost/php/20/index.php/blog浏览blog.php,将看到如图20.6所示的执行结果。
图20.6 在控制器中载入视图
通过这段代码,读者了解了如何载入一个视图。但视图中经常需要动态数据的内容,下面就介绍如何处理含有动态数据的视图。动态数据通过控制器以一个数组或对象的形式传入视图,这个数组或对象作为视图载入方法的第二个参数。下面便是使用数组的示例:
$data = array( 'title' => '我的标题', 'heading' => '头部信息', 'message' => '信息内容' ); $this->load->view('blogview', $data);
这里是使用对象的示例:
$data = new Someclass(); $this->load->view('blogview', $data);
注意 如果传入的是一个对象,那么类变量将转换为数组元素。
下面打开控制器并添加以下代码:
<?php class Blog extends Controller { function index() { $data['title'] = "我定义的标题"; //定义标题 $data['heading'] = "我定义的头部信息"; //定义头部文字 $this->load->view('blogview', $data); //引入到视图中 } } ?>
现在,打开原来的视图文件,将其中的文本替换成与数组对应的变量:
<html> <head> <title><?php echo $title;?></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head> <body> }h1 <h1><?php echo $heading;?></h1> </body> </html>
此时浏览器访问http://localhost /php/20/index.php/blog会看到如图20.7所示的执行结果。
图20.7 向视图添加动态数据
由上图可以看出浏览器上的页面标题和页面的heading文字都更换成动态数据内容。
至此,已经介绍了CodeIgniter的最简单的用法,离实际应用开发还很远,读者需要通过CodeIgniter提供的手册进一步学习、理解CodeIgniter框架。
20.4 典型实例
【实例20-1】本章前面介绍了ThinkPHP框架,本实例演示该框架的下载、安装和使用。
通过访问ThinkPHP的官方网站(thinkphp.cn),可以下载到最新的ThinkPHP开发框架的代码,本章使用的ThinkPHP的版本是2.2完整版,其下载地址是:http://www.thinkphp.cn/donate/ download/id/86.html。
下载后将解压文件进行解压,并将解压后文件夹中的ThinkPHP文件夹复制到项目文件夹下等待使用。
要在项目中使用ThinkPHP,需要注意以下几个问题:
- 硬件:ThinkPHP对硬件没有特别的要求。
- 操作系统:支持Windows、UNIX、Linux等操作系统。
- PHP版本:需要PHP 5.0以上版本。
- 数据库:支持MySQL、PgSQL、Sqlite 以及PDO等多种数据库。
在满足以上条件后,就可以在软件项目使用ThinkPHP了。要创建一个ThinkPHP项目,需要先创建一个接口文件,下面列出一段ThinkPHP官方提供的入门代码,代码如下所示。
代码20-6 ThinkPHP官方入门代码
<?php <?php define('THINK_PATH', 'ThinkPHP/'); //定义ThinkPHP框架路径 define('APP_NAME', 'book'); //定义项目名称和路径 define('APP_PATH', 'book'); require(THINK_PATH."/ThinkPHP.php"); //加载框架入口文件 $App = new App(); //实例化一个网站应用实例 $App->run(); //应用程序初始化 ?>
运行该程序后,运行结果如图20.8所示。
图20.8 程序运行结果
ThinkPHP的项目运行需要目录存放相关数据,因为ThinkPHP支持自动生成目录,所以在创建ThinkPHP项目后,只需要运行一次接口文件,就可以自动创建项目所需要的目录。生成的目录结构如图20.9所示。
图20.9 ThinkPHP目录
在图20.9中显示的目录结构里,book目录以及其子目录,都是在运行接口文件Ch20-1.php所自动生成的。下面详细介绍一下book目录下各个目录的作用。
- Cache:存放系统运行时产生的缓存文件,默认为空。
- Common:存放公共数据,默认为空。
- Conf:存放配置文件,默认为空。
- Data:存放相关数据,默认为空。
- Lang:存放语言文件,默认为空。
- Lib:包括两个目录,分别存放控制器和模型相关的类文件。
- Logs:存放日志文件,默认为空。
- Temp:存放临时文件,包括编译后的编译文件。
- Tpl:存放模板文件,默认包含空目录default。
ThinkPHP默认的字符集是UTF-8,所以在使用THinkPHP开发软件项目时,在使用编辑器编辑代码时,需要注意字符集编码之间的转换问题。
【实例20-2】ThinkPHP框架生成的主要代码,保存在Lib目录下,Lib目录下的两个文件夹Action和Model,分别保存着控制器与模型的相关代码。本实例将通过修改控制器代码,来创建新的方法。
关于命名规则,在ThinkPHP框架的规范中,对于命名是有要求的:
- 类名与文件名需要一致。
- 类文件名的扩展名都是“.class.php”。
要在已有的控制器中添加方法,只需要在类中定义新的函数就可以了。
下面通过修改IndexAction.class.php,为已经生成的项目添加一个新的方法,添加的代码如下所示。
…… //新添加的方法 public function newAction(){ header("Content-Type:text/html; charset=utf-8"); //输出字符编码 echo "这是新添加的方法"; } ……
在添加完新方法后,就可以通过浏览器进行访问了。因为ThinkPHP支持不同的URL模式访问模块,所以在浏览器中输入以下的URL地址,都能访问到新添加的方法。
普通模式:
http://127.0.0.1/src/ch20/ch20-1.php?m=index&a=newAction
PATHINFO模式:
http://127.0.0.1/src/ch20/ch20-1.php/index/newAction
REWRITE模式:
http://127.0.0.1/src/ch20/book/index/newAction
默认使用的是PATHINFO模式,而REWRITE模式需要通过配置才可以使用。访问以上3个URL地址中任何一个,都会显示同一个结果,如图20.10所示。
图20.10 控制器中新添加的方法
【实例20-3】在掌握了ThinkPHP关于控制器部分的知识后,接下来将介绍ThinkPHP访问数据库,以及模型方面的内容。
本实例主要介绍两个知识点,使用ThinkPHP访问数据库,以及模型文件。
(1)使用ThinkPHP访问数据库,需要先配置数据库的访问参数,数据库的访问参数保存在项目目录下的Conf文件夹下的config.php文件中。
(2)ThinkPHP项目的模型文件保存在项目目录的Lib/Model目录下,模型文件的名称和控制器文件的名称是一样的,后缀都是“.class.php”。
A)创建数据库
创建一个示例数据库examples,创建一个供ThinkPHP访问的表,名称为think_book,创建表的SQL语句如下所示。
CREATE TABLE `think_book` ( `id` int(4) NOT NULL auto_increment, `name` varchar(20) default NULL, `sex` varchar(20) default NULL, `IP` varchar(50) default NULL, `email` varchar(100) default NULL, `http` varchar(200) default NULL, `detail` text, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO `think_book` VALUES ('1', ' 赵一', ' 男 ', '127.0.0.1', 'zhao@mail.com', 'http://www.mail.com', '赵一留言内容'); INSERT INTO `think_book` VALUES ('2', ' 钱二', ' 男 ', '192.168.1.1', 'qian@mail.com', 'http://www.mail.com', '钱二留言内容');
B)创建配置文件
在项目中的Conf目录下,创建一个名为config.php的文件,用于保存配置内容,config.php文件的内容如下所示。
<?php return array( //定义数据库连接信息 'DB_TYPE'=> 'mysql', //数据为类型 'DB_HOST'=> 'localhost', //数据库服务器地址 'DB_NAME'=>'examples', //要操作的数据库 'DB_USER'=>'root', //数据库用户名 'DB_PWD'=>, //数据库密码 'DB_PORT'=>'3306', //数据库访问端口 'DB_PREFIX'=>'think_', //数据表前缀 ); ?>
C)创建模型文件
在创建完数据库和配置文件后,需要创建一个模型文件,来配合控制器访问数据库。ThinkPHP已经在模型基类中内置了相关代码,所以在创建模型时,只需要扩展这个模型基类,就可以完成对数据库的相关操作了。
在项目的Lib/Model目录下,创建一个名为bookModel.class.php的模型文件,代码如下所示。
<?php //创建一个空的模型文件 class bookModel extends Model{} ?>
D)为控制器添加方法
在做完准备工作后,就可以使用ThinkPHP内置的数据库模块的相关功能访问数据库了。为Lib/Action目录下的IndexAction.class.php添加一个新方法,用于读取数据库,代码如下所示。
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){} public function newAction(){} //读取数据库 public function listbook(){ $book = new bookModel(); //实例化模型 $book->query('set charset latin1'); //设置数据库默认字符编码 $list = $book->findAll(); //使用findAll()方法,取得表中所有记录 dump($list); //使用DUMP方法,显示返回的数组 } } ?>
在添加完方法后,在浏览器中输入http://localhost/Ch20/Ch20-1.php/index/listbook后按回车键,运行结果如图20.11所示。
图20.11 保存有数据库数据的数组
20.5 小结
本章介绍了PHP中的MVC模型。首先介绍了什么是MVC模型,以及MVC模型中控制器、视图和数据模型的概念。然后介绍了PHP中的模板技术,包括什么是模板、如何在PHP程序中使用模板、Smarty模板引擎的基本用法。接着,介绍了几款目前比较流行的PHP基于MVC的Web开发框架,包括CodeIgniter、CakePHP、Zend Framework及国产优秀框架FleaPHP。最后,以CodeIgniter为实例,介绍了使用CodeIgniter开发PHP网络应用程序的基本思路和用法。
20.6 习题
1. 写出你知道的5个PHP框架。
2. 说说CodeIgniter框架的缺点和优点。