原文:http://www.onlamp.com/pub/a/php/2004/12/09/three_tier.html Three-Tier Development with PHP 5 by Luis Yordano Cruz 12/09/2004 PHP程序员站--PHP程序员之家
此文演示了PHP三层开发的强大功能,PEAR::DB_DataObject用于业务逻辑,Smarty用于显示逻辑,这里假设你熟 phperz.com
悉了HTML,Smarty,PEAR::DB_DataObject,Mysql和PHP5.如果你需要补充知识,下面的文章解释了一些原理: PHP程序员站--PHP程序员之家
用PHP DataObject简化业务逻辑 Smarty简介:一个PHP模板引擎 PHP可伸缩性:Myth PHP程序员站
你应该已安装和配置好了Apache,MySQL,和PHP5(或者IIS,MySQL5和PHP) www phperz com
PEAR::DB_DataObject PEAR::DB_DataObject 是一个用户数据库访问的抽象API.它是一个基于PEAR::DB的SQL构建器和数据建模层.它 PHP程序员站
把数据库表映射到PHP类并且提供像SELECT,INSERT,UPDATE,和DELETE这样的公共SQL函数.这使即使不了 www~phperz~.com
解SQL的开发者也可以写出好的数据库访问代码,并且鼓励演示逻辑和业务逻辑有一个清晰的分离. phperz.com
(DB_OO已经移动到的PEAR,现在是DB_DataObject,如果你有老的代码要更新,查看关于从老的db_oo代码更新到 www phperz com
DB_DataObjects的注释). www.phperz.com
相关阅读 Upgrading to PHP 5 By Adam Trachtenberg www phperz com
Table of Contents Index Sample Chapter www phperz com
Read Online--Safari Search this book on Safari: Only This Book All of Safari Code Fragments only DataObject performs two tasks. First, it builds SQL statements based on the object's variables and the builder PHP程序员站--PHP程序员之家
methods. Second, it acts as a datastore for a table row. There's a core class, which you extend for each of www~phperz~.com
your tables so that you put the data logic inside the data classes. There's also an included Generator to make PHP程序员站--PHP程序员之家
your configuration files and your base classes. PHP程序员站
DataObject 执行两个任务.第一,它构建基于对象变量的SQL语句和构建器方法.第二,它作为数据库表的数据存 PHP程序员站
储.这里有个核心类,对于每个表继承它,以使你把数据逻辑放入数据类中.这里还包括一个生成器, PHP程序员站--PHP程序员之家
DataObject 极大的简化了数据库访问代码,它使开发大型的,数据驱动的站点更加容易.
phperz.com
At present, Alan Knowles, the lead developer of PEAR::DB_DataObject, is working on a new project called DBDO, PHP程序员站--PHP程序员之家
a C implementation of the PEAR package DB_DataObjects, based on libgda. His goal is to create the next www phperz com
generation of PEAR::DB_DataObjects. www.phperz.com
SMARTY www~phperz~.com
Smarty是一个从web页演示中分离内容的PHP模板引擎.它使用GPL许可. www phperz com
Large projects commonly separate the role of the graphic designer from that of the programmer. However, PHP程序员站--PHP程序员之家
programming in PHP has the tendency to combine those two roles in a person and inside the code. This can bring www~phperz~.com
difficulties when it comes time to change some part of the page's design. If the page mixes content and www phperz com
presentation, the developer has to crawl through the program to find the presentation. Smarty helps to solve PHP程序员站--PHP程序员之家
this problem. www~phperz~.com
Combining the Two The first thing to do when starting this project is to create a workspace in which to store the project's code. PHP程序员站--PHP程序员之家
Then it's time to configure PEAR::DB_DataObject to connect to the MySQL database MySQL (name: example), www~phperz~.com
map the database tables to PHP classes, and then configure Smarty for the presentation tier for the user. Here www phperz com
are those steps in more detail: PHP程序员站--PHP程序员之家
创建工作环境
www~phperz~.com
创建一个叫做dataobjects的目录. phperz.com
PHP程序员站--PHP程序员之家
从命令行安装PEAR::DB_DataObject,键入: >pear install Date >pear install DB_DataObject >pear list phperz.com
INSTALLED PACKAGES: =================== PACKAGE VERSION STATE Archive_Tar 1.2 stable Console_Getopt 1.2 stable DB 1.6.5 stable DB_DataObject 1.7.1 stable *(Goal) Date 1.4.3 stable Mail 1.1.3 stable Net_SMTP 1.2.6 stable Net_Socket 1.0.2 stable PEAR 1.3.1 stable PHP程序员站--PHP程序员之家 PHPUnit 1.0.1 stable XML_Parser 1.2.0 stable XML_RPC 1.1.0 stable PHP程序员站
安装和配置Smarty
PHP程序员站
从下载开始,(我使用2.6.5版的Smarty)解压到你自己的目录.从它的libs目录中把Smarty.class.php, PHP程序员站
Smarty_Compiler.class.php, Config_File.class.php, and debug.tpl文件复制到dataobjects目录中. PHP程序员站--PHP程序员之家
还要复制core和plugins目录和其中所有的内容.创建几个新的目录,命名为templates, templates_c, configs, PHP程序员站--PHP程序员之家
和cache. www phperz com
最后dataobjects目录包含:
phperz.com
|---- cache |---- configs |---- core |---- plugins |---- templates |---- templates_c www~phperz~.com
11/10/2004 11:17 a.m. <DIR> . 11/10/2004 11:17 a.m. <DIR> .. 11/10/2004 11:17 a.m. <DIR> cache 11/10/2004 11:17 a.m. <DIR> configs 11/10/2004 11:17 a.m. <DIR> core 11/10/2004 11:17 a.m. <DIR> plugins 11/10/2004 11:17 a.m. <DIR> templates 11/10/2004 11:17 a.m. <DIR> templates_c 07/09/2004 09:48 a.m. 13,105 Config_File.class.php 16/04/2004 03:03 a.m. 5,117 debug.tpl 10/09/2004 02:15 p.m. 65,350 Smarty.class.php 10/09/2004 07:14 p.m. 90,924 Smarty_Compiler.class.php 4 archivos 174,496 bytes 8 dirs 6,699,454,464 bytes libres www phperz com
创建数据库 创建一个名为example的数据库,它包含一个名为User的表,不必担心模式,稍后我们会创建.
PHP程序员站
配置PEAR::DB_DataObject 要构建数据对象,创建下面的文件 www phperz com
configDB.php <?php require_once 'DB/DataObject.php'; $config = parse_ini_file('example.ini',TRUE); phperz.com
foreach($config as $class=>$values) { $options = &PEAR::getStaticProperty($class,'options'); $options = $values; } ?> www.phperz.com
此脚本基于example配置文件中的值创建一个到数据库的连接,显示如下. www phperz com
example.ini [DB_DataObject] database = mysql://root:@localhost/example schema_location = /dataobjects/schema/ class_location = /dataobjects/ require_prefix = /dataobjects/ class_prefix = DataObjects_ extends_location = DB/DataObject.php extends = DB_DataObject PHP程序员站--PHP程序员之家
自动构建数据库模式
www phperz com
包含两个过程,构建数据库的对象-关系映射,和从example数据库user表中自动创建一个类.在表中的所有字段 www phperz com
名将成为类成员变量. PHP程序员站--PHP程序员之家
创建适当的模式:
www.phperz.com
C:\PHP\PEAR\DB\DataObject>C:\PHP\php.exe createTables.php \ C:\dataobjects\example.ini www phperz com
这将生成User.php文件:
www phperz com
<?php /** * Table Definition for user * www.mhzc.cn */ require_once 'DB/DataObject.php'; PHP程序员站
class DataObjects_User extends DB_DataObject { ###START_AUTOCODE phperz.com
/* the code below is auto generated do not remove the above tag */ var $__table = 'user'; // table name var $user_Id; // int(11) not_null primary_key auto_increment var $first_Name; // string(30) not_null var $last_Name; // string(40) not_null var $email; // string(100) not_null PHP程序员站--PHP程序员之家
/* Static get */ function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('DataObjects_User',$k,$v); } PHP程序员站
/* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE } ?> www phperz com
它还会为user表模式生成example.ini配置文件: phperz.com
[user] user_Id = 129 first_Name = 130 last_Name = 130 email = 130 PHP程序员站
[user__keys] user_Id = N PHP程序员站--PHP程序员之家
Smarty files It's time to create several files for Smarty:
www phperz com
Smarty文件 现在是创建几个Smarty文件的时候了: PHP程序员站--PHP程序员之家
include.php 1 <? 2 require('Smarty.class.php'); 3 $smarty = new Smarty; 4 $smarty->template_dir = 'templates/'; 5 $smarty->compile_dir = 'templates_c/'; 6 $smarty->config_dir = 'configs/'; 7 $smarty->cache_dir = 'cache/'; ?> PHP程序员站--PHP程序员之家
此脚本实例化了一个新Smarty对象.设置Smarty属性. www phperz com
index.php 1 <? 2 require("include.php"); 3 $smarty->assign('TITLE','ACCESS MySQL DATABASE IN THREE TIERS WITH PHP'); 4 $smarty->assign('HEADER','WHAT WISH DO ?'); 5 $smarty->display('index.tpl'); ?> www phperz com
给Smarty模板分配变量. www~phperz~.com
insert.php 1 <? 2 require("include.php"); 3 $smarty->assign('TITLE','INSERT DATA'); 4 $smarty->assign('HEADER','Insert Data'); 5 $smarty->assign('data1','First Name'); 6 $smarty->assign('data2','Last Name'); 7 $smarty->assign('data3','email'); 8 $smarty->display('insert.tpl'); ?> www.phperz.com
添加将在insert.tpl 使用的变量.调用模板insert.tpl . phperz.com
save.php 1 <? 2 require_once('DB/DataObject.php'); 3 require('configDB.php'); 4 $user = DB_DataObject::factory('user'); 5 $user->first_Name = $x; 6 $user->last_Name = $y; 7 $user->email = $z; 8 $user_Id = $user->insert(); 9 $user->update(); 10 echo "<script>location.href='index.php'</script>"; 11 ?> www phperz com
This script saves data by using a PEAR::DataObject for the user table. Line 2 loads the class DataObject, and www phperz com
line 3 calls configdb.php to connect to the database. Line 4 creates an instance of a user object (see User.php). PHP程序员站
Lines 5 through 7 pass the variables collected from the form in insert.tpl ($x, $y, and $z) in order to save the PHP程序员站
data in the database. The primary key of the table is an autoincrement column, so it doesn't need a value there. PHP程序员站
Line 8 inserts the object, and line 9 carries out an update. PHP程序员站
view.php 1 <? 2 require_once('DB/DataObject.php'); 3 require('configDB.php'); 4 require("include.php"); 5 $user = DB_DataObject::factory('user'); 6 $user->find(); 7 while ($user->fetch()) { 8 $smarty->append('users', array( 'ID' => $user->user_Id, 'FIRSTNAME' => $user->first_Name, 'LASTNAME' => $user->last_Name, 'EMAIL' => $user->email, )); } 9 $smarty->assign('TITLE','List Users'); www phperz com 10 $smarty->assign('HEADER','List User'); 11 $smarty->assign('data0','User_Id'); 12 $smarty->assign('data1','First Name'); 13 $smarty->assign('data2','Last Name'); 14 $smarty->assign('data3','email'); 15 $smarty->display('view.tpl'); 16 ?> www~phperz~.com
此脚本显示所有存储在user表中的数据.它加载PEAR::DataObject 和include.php文件(给smarty模板分配变量). 第5行创建一个user对象的工厂.第6行执行find()方法.SELECT * FROM user从数据库中检索出了数据,通 phperz.com
过fetch()方法为模板保存数据,一次返回一条记录. www phperz com
9 到14行是分配其他的变量给Smarty. PHP程序员站
这些文件都应当放在dataobjects目录中. PHP程序员站
对于模板,这里有index.tpl,list.tpl,和save.tpl.这里是他们的代码: phperz.com
index.tpl 1 <html> 2 <head> 3 <title>{$TITLE}</title> 4 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 5 </head> 6 <table align="center"> 7 <tr> 8 <td> 9 <b>{$HEADER}</b> 10 </td> 11 </tr> 12 </table> 13 <table width="250" border="1" align="center" > 14 <tr> 16 <td align="center"> 17 <input type="button" name="insert" value="Insert" onclick="javascript:location.href='insert.php';"> www~phperz~.com 18 </td> 19 </tr> 20 <tr> 21 <td align="center"> 22 <input type="button" name="view" value="View" onclick="javascript:location.href='view.php';"> 23 </td> 24 </tr> 25 </table> 26 </body> 27 </html> www~phperz~.com
站点主页,它在的3行和第9行分别显示$TITLE 和$HEADER,这些变量值是从index.php传递过来的. phperz.com
这个脚本在web浏览器上生成两个按钮,Insert和View,他们有相应的行为.如果用户点击Insert,系统将调 www~phperz~.com
用Insert.php.如果用户点击View,那么view.php将被调用 www phperz com
insert.tpl 1 <html> 2 <head> 3 <title>{$TITLE}</title> 4 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 5 </head> 6 <body> 7 <form name="form1" action="save.php" method="post"> 8 <table width="300" border="1" align="center" > 9 <tr> 10 <td align="center"> 11 <b>{$HEADER}</b> 12 </td> 13 </tr> 14 <tr> 15 <td> www.phperz.com 16 {$data1} 17 <input type="text" name="x"> 18 </td> 19 </tr> 20 <tr> 21 <td> 22 {$data2} 23 <input type="text" name="y"> 24 </td> 25 </tr> 26 <tr> 27 <td> 28 {$data3} 29 <input type="text" name="z"> www phperz com 30 </td> 31 </tr> 32 <tr> 33 <td align="center"> 34 <input type="submit" name="Submit" value="Add"> 35 <input type="button" name="Reset" value="Return/Cancel" onclick="javascript:location.href='index.php';"> 36 </td> 37 </tr> 38 </table> 39 </form> 40 </body> 41 </html> www~phperz~.com
这个模板有一个表单和两个按钮,Add 和Return/Cancel. www phperz com
用户输入数据,first name,last name 和电子邮件字段.insert.php期望在名为x,y,z的变量中接收这些信息,用户点 PHP程序员站--PHP程序员之家
击Add按钮将运行save.php.如果用户点击Return/Cancel,将会执行index.php. www~phperz~.com
view.tpl 1 <html> 2 <head> 3 <title>{$TITLE}</title> 4 </head> 5 <body> 6 <table align="center"> 7 <tr> 8 <td align="center"> 9 <b>{$HEADER}</b> 10 </td> 11 </tr> 12 </table> 13 <table width="500" border="1" align="center"> 14 <tr> 16 <td align="center"> 17 <b>{$data0}</b> 18 </td> 19 <td align="center"> www~phperz~.com 20 <b>{$data1}</b> 21 </td> 22 <td align="center"> 23 <b>{$data2}</b> 24 </td> 25 <td align="center"> 26 <b>{$data3}</b> 27 </td> 28 </tr> 29 {section name=display loop=$users} 30 <tr> 31 <td> 32 {$users[display].ID} 33 </td> 34 <td> 35 {$users[display].FIRSTNAME} www.phperz.com 36 </td> 37 <td> 38 {$users[display].LASTNAME} 39 </td> 40 <td> 41 {$users[display].EMAIL} 42 </td> 43 </tr> 44 {/section} 45 <br> 46 </table> 47 <br> 48 <table align="center"> 49 <tr> 50 <td align="center"> 51 <input name="vol" type="button" value="Return" onclick="javascript:location.href='index.php';"> www.phperz.com 52 </td> 53 </tr> 54 </table> 55 </body> 56 </html> PHP程序员站
这个模板显示所有存储在example数据库中的所有数据. PHP程序员站
最后,Return按钮把用户带回到主页.
phperz.com
所有的这些(*.tpl)文件必须放在templates目录下. PHP程序员站--PHP程序员之家
www~phperz~.com
|