原文: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三層開發的強大功能,PEAR::DB_DataObject用於商務邏輯,Smarty用於顯示邏輯,這裡假設你熟
悉了HTML,Smarty,PEAR::DB_DataObject,Mysql和PHP5.如果你需要補充知識,下面的文章解釋了一些原理:
用PHP DataObject簡化商務邏輯
Smarty簡介:一個PHP模板引擎
PHP延展性:Myth
你應該已安裝和配置好了Apache,MySQL,和PHP5(或者IIS,MySQL5和PHP)
PEAR::DB_DataObject
PEAR::DB_DataObject 是一個使用者資料庫訪問的抽象API.它是一個基於PEAR::DB的SQL構建器和資料建模層.它
把資料庫表映射到PHP類並且提供像SELECT,INSERT,UPDATE,和DELETE這樣的公用SQL函數.這使即使不了
解SQL的開發人員也可以寫出好的資料庫存取碼,並且鼓勵示範邏輯和商務邏輯有一個清晰的分離.
(DB_OO已經移動到的PEAR,現在是DB_DataObject,如果你有老的代碼要更新,查看關於從老的db_oo代碼更新到
DB_DataObjects的注釋).
相關閱讀
Upgrading to PHP 5
By Adam Trachtenberg
Table of Contents
Index
Sample Chapter
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
methods. Second, it acts as a datastore for a table row. There's a core class, which you extend for each of
your tables so that you put the data logic inside the data classes. There's also an included Generator to make
your configuration files and your base classes.
DataObject 執行兩個任務.第一,它構建基於物件變數的SQL語句和構建器方法.第二,它作為資料庫表的資料存
儲.這裡有個核心類,對於每個表繼承它,以使你把資料邏輯放入資料類中.這裡還包括一個產生器,
DataObject 極大的簡化了資料庫存取碼,它使開發大型的,資料驅動的網站更加容易.
At present, Alan Knowles, the lead developer of PEAR::DB_DataObject, is working on a new project called DBDO,
a C implementation of the PEAR package DB_DataObjects, based on libgda. His goal is to create the next
generation of PEAR::DB_DataObjects.
SMARTY
Smarty是一個從web頁示範中分離內容的PHP模板引擎.它使用GPL許可.
Large projects commonly separate the role of the graphic designer from that of the programmer. However,
programming in PHP has the tendency to combine those two roles in a person and inside the code. This can bring
difficulties when it comes time to change some part of the page's design. If the page mixes content and
presentation, the developer has to crawl through the program to find the presentation. Smarty helps to solve
this problem.
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.
Then it's time to configure PEAR::DB_DataObject to connect to the MySQL database MySQL (name: example),
map the database tables to PHP classes, and then configure Smarty for the presentation tier for the user. Here
are those steps in more detail:
建立工作環境
建立一個叫做dataobjects的目錄.
從命令列安裝PEAR::DB_DataObject,鍵入:
>pear install Date
>pear install DB_DataObject
>pear list
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
PHPUnit 1.0.1 stable
XML_Parser 1.2.0 stable
XML_RPC 1.1.0 stable
安裝和配置Smarty
從下載開始,(我使用2.6.5版的Smarty)解壓到你自己的目錄.從它的libs目錄中把Smarty.class.php,
Smarty_Compiler.class.php, Config_File.class.php, and debug.tpl檔案複製到dataobjects目錄中.
還要複製core和plugins目錄和其中所有的內容.建立幾個新的目錄,命名為templates, templates_c, configs,
和cache.
最後dataobjects目錄包含:
|---- cache
|---- configs
|---- core
|---- plugins
|---- templates
|---- templates_c
11/10/2004 11:17 a.m.
.
11/10/2004 11:17 a.m. ..
11/10/2004 11:17 a.m. cache
11/10/2004 11:17 a.m. configs
11/10/2004 11:17 a.m. core
11/10/2004 11:17 a.m. plugins
11/10/2004 11:17 a.m. templates
11/10/2004 11:17 a.m. 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
建立資料庫
建立一個名為example的資料庫,它包含一個名為User的表,不必擔心模式,稍後我們會建立.
配置PEAR::DB_DataObject
要構建資料對象,建立下面的檔案
configDB.php
require_once 'DB/DataObject.php';
$config = parse_ini_file('example.ini',TRUE);
foreach($config as $class=>$values) {
$options = &PEAR::getStaticProperty($class,'options');
$options = $values;
}
?>
此指令碼基於example設定檔中的值建立一個到資料庫的串連,顯示如下.
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
自動構建資料庫模式
包含兩個過程,構建資料庫的對象-關係映射,和從example資料庫user表中自動建立一個類.在表中的所有欄位
名將成為類成員變數.
建立適當的模式:
C:\PHP\PEAR\DB\DataObject>C:\PHP\php.exe createTables.php \
C:\dataobjects\example.ini
這將產生User.php檔案:
/**
* Table Definition for user
* www.knowsky.com
*/
require_once 'DB/DataObject.php';
class DataObjects_User extends DB_DataObject
{
###START_AUTOCODE
/* 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
/* Static get */
function staticGet($k,$v=NULL) {
return DB_DataObject::staticGet('DataObjects_User',$k,$v);
}
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
}
?>
它還會為user表模式產生example.ini設定檔:
[user]
user_Id = 129
first_Name = 130
last_Name = 130
email = 130
[user__keys]
user_Id = N
Smarty files
It's time to create several files for Smarty:
Smarty檔案
現在是建立幾個Smarty檔案的時候了:
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/';
?>
此指令碼執行個體化了一個新Smarty對象.設定Smarty屬性.
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');
?>
給Smarty模板分配變數.
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');
?>
添加將在insert.tpl 使用的變數.調用模板insert.tpl .
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 "";
11 ?>
This script saves data by using a PEAR::DataObject for the user table. Line 2 loads the class DataObject, and
line 3 calls configdb.php to connect to the database. Line 4 creates an instance of a user object (see User.php).
Lines 5 through 7 pass the variables collected from the form in insert.tpl ($x, $y, and $z) in order to save the
data in the database. The primary key of the table is an autoincrement column, so it doesn't need a value there.
Line 8 inserts the object, and line 9 carries out an update.
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');
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 ?>
此指令碼顯示所有儲存在user表中的資料.它載入PEAR::DataObject 和include.php檔案(給smarty模板分配變數).
第5行建立一個user對象的工廠.第6行執行find()方法.SELECT * FROM user從資料庫中檢索出了資料,通
過fetch()方法為模板儲存資料,一次返回一條記錄.
9 到14行是分配其他的變數給Smarty.
這些檔案都應當放在dataobjects目錄中.
對於模板,這裡有index.tpl,list.tpl,和save.tpl.這裡是他們的代碼:
index.tpl
1
2
3 {$TITLE}
4
5
6
13
14
16
17 onclick="javascript:location.href='insert.php';"> 18 | 19
20
21
22 onclick="javascript:location.href='view.php';"> 23 | 24
25
26
27
網站首頁,它在的3行和第9行分別顯示$TITLE 和$HEADER,這些變數值是從index.php傳遞過來的.
這個指令碼在web瀏覽器上產生兩個按鈕,Insert和View,他們有相應的行為.如果使用者點擊Insert,系統將調
用Insert.php.如果使用者點擊View,那麼view.php將被調用
insert.tpl
1
2
3 {$TITLE}
4
5
6
7
40
41
這個模板有一個表單和兩個按鈕,Add 和Return/Cancel.
使用者輸入資料,first name,last name 和電子郵件欄位.insert.php期望在名為x,y,z的變數中接收這些資訊,使用者點
擊Add按鈕將運行save.php.如果使用者點擊Return/Cancel,將會執行index.php.
view.tpl
1
2
3 {$TITLE}
4
5
6
13
14
16
17 {$data0} 18 | 19
20 {$data1} 21 | 22
23 {$data2} 24 | 25
26 {$data3} 27 | 28
29 {section name=display loop=$users}30
31
32 {$users[display].ID} 33 | 34
35 {$users[display].FIRSTNAME} 36 | 37
38 {$users[display].LASTNAME} 39 | 40
41 {$users[display].EMAIL} 42 | 43
44 {/section}45 46
47
48
49
50
51 onclick="javascript:location.href='index.php';"> 52 | 53
54
55
56
這個模板顯示所有儲存在example資料庫中的所有資料.
最後,Return按鈕把使用者帶回到首頁.
所有的這些(*.tpl)檔案必須放在templates目錄下.