我的一亩三分地 我就喜欢!
13fen  设为主页
 收藏本站
 
当前位置: > 一亩三分地:首页 > 网络学院 > 网络编程 > PHP专区 > php应用/技巧 > 用PHP4 和 PostgreSQL 构建一个电子商务应用
热门文章排行
热门文章排行 检查email地址格式的代码(01-11)
PHP操作文件问答(01-11)
PHP安装攻略:安装并配置PHP(10-23)
PHP的十个高级技巧 4(10-23)
PHP控制语句(10-12)
精采文章排行
精采文章排行 PHP连接MYSQL的两种方法(11-15)
PHP和MySQL开发的8个技巧(10-23)
PHP安装攻略:安装并配置PHP(10-23)
php+mysql扎实个人基本功(10-23)
PHP编程常用技巧四则(10-23)
技术专题推荐
网管论坛交流
 

用PHP4 和 PostgreSQL 构建一个电子商务应用 

作者:佚名   来源:本站资源   点击:   日期:2007-01-11

本文通过一个简单的web 应用,演示了 PHP 和 PostgresSQL 在电子商务中的应用。

不久以前,如果要架构一个严肃的Web应用的话,意味着购买价格不菲的Cold Fusion 许可,以及一个商业的数据库服务程序像Sybase 加上Sun 服务器。幸运的是,这样的日子一去不复返了。随着日渐成熟的免费数据库市场以及Apache 使用者的大量增长,一些替代产品已经具有相当,甚至超过了这些专有软件的能力。

比较好的开放源码软件的一种是 PHP,一个很像Perl 的脚本语言,以及PostgreSQL,一个很强大的面向对象的数据库。如果把两者结合起来的话,你可以设计从简单的留言簿到一个巨大的基于Web 的财务软件。PHP 提供大脑而Postgres 提供发达的肌肉。

下面介绍一个很基本的 PHP 购物车和库存应用,充分利用 Postgres 的事务功能。源码推渌柿峡梢源?PHPBuilder.com 下载。

首先要提到的是应用程序的结构,在我的PHP Web 应用中,我总是首先设置一个综合库,网站的每一个页面都会用到它,取名叫common.php 存放在include 目录。

这个库会处理日常任务,例如数据库连接,用户鉴别,站点的头部/尾部文件等。把这些函数放在一个地方,我们的应用看上去很干净,容易维护。

表一:示范的库代码

common.php:
<?php

//连接 postgres 数据库
$conn=pg_pconnect("user=tim dbname=db_example");

//看连接是否成功
if (!$conn) {
//如果失败则报告出错
echo pg_errormessage($conn);
exit;
}

//站点的头文件

function site_header ($title) {
return '<HTML>
<HEAD>
<TITLE>'.$title.'</TITLE>
</HEAD>
<BODY>';
}

// 页面结尾的 HTML 代码

function site_footer () {

return '</BODY></HTML>';

}

//一个简单的查询执行函数,用来减少代码

function query($sql) {
global $conn;
return pg_exec($conn,$sql);
}

//让每一个页面自动启动session或者保存 session 状态

session_start();

?>


因此,我们的第一个版本的库已经可以用了,它连接数据库,提供了简单的 HTML
代码。

我们站点上每一个页面都包括:

<?php<n>

require ($DOCUMENT_ROOT.'/include/common.php');

echo site_header('示范页面');

/*
页面逻辑处理
*/

echo site_footer();

?>

一般说来,在构建应用程序时,把逻辑和实际的表示(在我们这里就是HTML)分开是很明智的。因此,我把逻辑放到函数里面。但是PHP 使用函数调用的方法,缺点是没有标准的出错处理过程,如果函数内部有错的话,呼叫函数的程序不能把把错误信息传递给用户。在其他的语言,例如Java 里面,你可以使用try/catch语句来处理。

我的解决办法是,每个函数总是返回 true 或者 false ,设置一个$feedback全局变量,这样的话,结果就可以测试。现在有一个叫做PEAR (http://pear.php.net/) 的项目在做标准化错误处理以及数据库存取的努力,
但是到目前为止,还不能稳定运行。

下面是一个使用我的 true/false 方法调用函数的例子:

<?php

$result=function_call_name();

if (!$result) {
//显示错误
echo $feedback;
} else {
//没有错误,继续
}

?>

好了,现在让我们开始想想购物车吧! 我们需要一些基本的数据结构存储购物车的数据。例如,我们需要一个库存数据库列出物品名字,部件号码,价格以及数量,同时,我们
还需要记录顾客购买的物品......太复杂了,就写这些吧。

表二、购物车数据结构

Cart.sql:

# 建立一个顺序表用来产生顾客号码。
# 每个id 之间用随意的一个数字分开,以防别人猜测购物车号码。
create sequence seq_customer_id increment 26 start 1;

create table customers (
customer_id int not null default 0 primary key,
name text,
address text,
credit_card text,
total_order MONEY DEFAULT '{CONTENT}.00'
);

create table cart_items (
cart_item serial,
customer_id int,
part_number int,
quantity int
);

create index idx_cart_customer on cart_items(customer_id);

create table item_inventory (
part_number serial,
name text,
price float,
inventory int
);


这个结构给我们一个基本的购物车,为了规范数据库模式,我建立一个独立的表,用于列出顾客的购物车里的内容。这样,让顾客的购物车可以有多项物品,并且可以很容易
地和库存数据库连接。

现在我们需要考虑桓鲈谙呱痰甑母髦止δ芰恕R桓鲎罨镜墓δ芫褪侨〉靡徊抗何锍担道锾砑游锲罚缓蠼嵴恕5比灰桓鍪导什僮鞯脑谙呱痰辏剐枰芏喙δ埽皲?物品,调整数量等。这些就等你自己来完成了。

我从一个简单的生成一个顾客的功能开始,所有这些其实就是在排队的顾客中取得下一个顾客的资料,插入顾客表,把顾客号码在PHP4 内置的session 管理中注册。

表三、建立一个新顾客
<?php

function cart_new() {

global $conn, $customer_id, $feedback;

// 启动一个事务
query("BEGIN WORK");

//查询下一个顾客号码
$res=query("SELECT nextval('seq_customer_id')");

//检查错误
if (!$res || pg_numrows($res)<1) {
$feedback .= pg_errormessage($conn);
$feedback .= ' Error - Database didn't return next value ';
query("ROLLBACK");
return false;
} else {
$customer_id=pg_result($res,0,0);

// 登记到 session
session_register('customer_id');

// 插入新顾客
$res=query("INSERT INTO customers (customer_id)
VALUES ('$customer_id')");

//检查错误
if (!$res || pg_cmdtuples($res)<1) {
$feedback .= pg_errormessage($conn);
$feedback .= ' Error - couldn't insert new customer row ';
query("ROLLBACK");
return false;
} else {
//commit this transaction
query("COMMIT");
return true;
}
}
}

?>

这段代码比较长,虽然我不是很喜欢,但是它演示了怎样正确开始和结束Postgres 的事务以及怎样检查查询语句的错误。我要在所有的代码用到同样的错误监测程序,我想,你也应该如此。

需要计划好如果查询出错的处理办法,你是直接终止程序呢?还是重新运行查询语句,抑或继续执行,就当什么也没有发生?仔细考虑每种选择的结果。例如,如果不能得到下一个顾客的customer_id ,那么,建立新顾客的记录也就泡汤,接下来就是不能更新她的地址,不能往购物车里添加物品,对吧?

现在,我们看看添加物品的过程,这个步骤相对比较容易,在添加物品之前,要先检查物品是否在数据库中。这样比较安全,因为物品号码来自浏览器,可能被篡改。一旦知道物品存在,我们就能测试它是否已经在购物车里,如果已经放入,那么数量加一,而不是另外插入一行,否则,插入一条数量为一的记录到购物车。

表四、添加物品到购物车
<?php

function cart_add_item($item_id,$quantity=1) {
global $customer_id, $feedback, $conn;

$res=query("SELECT * FROM item_inventory WHERE part_number='$item_id'");

if (!$res || pg_numrows($res)<1) {
$feedback .= pg_errormessage($conn);
$feedback .= ' Error-item not found ';
return false;
} else {
// 检查物品是否放入购物车,如果是,增加数量
// 开始事务
query("BEGIN WORK");

$res=query("SELECT * FROM cart_items ".
"WHERE part_number='$item_id' AND customer_id='$customer_id' FOR UPDATE");

if (!$res || pg_numrows($res)<1) {

//如果没有该物品,新插入一条
$res=query("INSERT INTO cart_items ".
"(customer_id,part_number,quantity)".
"VALUES ($customer_id,$item_id,$quantity)");

if (!$res || pg_cmdtuples($res) < 1) {
$feedback .= pg_errormessage($conn);
$feedback .= ' Error-couldn't insert into cart ';
//尽管没有东西被改变,但是最好还是回滚事务
query("ROLLBACK");
return false;
} else {
query("COMMIT");
return true;
}
} else {
//购物车中已经存在该物品
$res=query("UPDATE cart_items SET quantity = quantity + $quantity ".
"WHERE part_number='$item_id' AND
customer_id='$customer_id'");
if (!$res || pg_cmdtuples($res) < 1) {
$feedback .= pg_errormessage($conn);
$feedback .= ' Error-couldn't increment quantity in cart

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【论坛讨论

   相关文章:
·将OICQ数据转成MYSQL数据 ·用PHP实现ODBC数据分页显示一例
·php生成WAP页面 ·PHP与Javascript的两种交互方式
·PHP+Javascript模拟Matrix画面 ·WHOIS类的修改版

   文章评论:(条)
  
 请留名: 匿名评论   点击查看所有评论 网管论坛
 

  责任编辑:一分  声明:刊登此文章是为了传递更多信息,文章内容仅供参考,转载请注明出处。