PostgreSQL电子商务
由 徐永久 发表于 2001年10月16日 09:06。本文通过一个简单的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:
//连接 postgres 数据库
$conn=pg_pconnect("user=tim dbname=db_example");
//看连接是否成功
if (!$conn) {
//如果失败则报告出错
echo pg_errormessage($conn);
exit;
}
//站点的头文件
function site_header ($title) {
return '
';
}
// 页面结尾的 HTML 代码
function site_footer () {
return '';
}
//一个简单的查询执行函数,用来减少代码
function query($sql) {
global $conn;
return pg_exec($conn,$sql);
}
//让每一个页面自动启动session或者保存 session 状态
session_start();
?>
因此,我们的第一个版本的库已经可以用了,它连接数据库,提供了简单的 HTML
代码。
我们站点上每一个页面都包括:
\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 方法调用函数的例子:
$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 '$0.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 管理中注册。
表三、建立一个新顾客
function cart_new() {
global $conn, $customer_id, $feedback;
// 启动一个事务
query("BEGIN WORK");
//查询下一个顾客号码
$res=query("SELECT nextval('seq_customer_id')");
//检查错误
if (!$res || pg_numrows($res)
$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)
$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 ,那么,建立新顾客的记录也就泡汤,接下来就是不能更新她的地址,不能往购物车里添加物品,对吧?
现在,我们看看添加物品的过程,这个步骤相对比较容易,在添加物品之前,要先检查物品是否在数据库中。这样比较安全,因为物品号码来自浏览器,可能被篡改。一旦知道物品存在,我们就能测试它是否已经在购物车里,如果已经放入,那么数量加一,而不是另外插入一行,否则,插入一条数量为一的记录到购物车。
表四、添加物品到购物车
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)
//如果没有该物品,新插入一条
$res=query("INSERT INTO cart_items ".
"(customer_id,part_number,quantity)".
"VALUES ($customer_id,$item_id,$quantity)");
if (!$res || pg_cmdtuples($res)
$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)
$feedback .= pg_errormessage($conn);
$feedback .= ' Error-couldn\'t increment quantity in cart ';
query("ROLLBACK");
return false;
} else {
// 提交改变,正式更新数据库。
query("COMMIT");
return true;
}
}
}
}
?>
现在我们能建立新顾客,并且他们添加物品了。我们现在需要结账,并减掉库存。这一部分是最复杂的,充分利用了Postgres 的事务功能和先进锁机制。
我们用Postgres 的 SELECT...FOR UPDATE 语法作为开始,这个语句能有效地对当前选择的行加锁使你能在一个事务里更新并提交改变。
通过在一个事务里使用这个语句,你可以保证数据的一致性。在其他的一些数据库,例如MySQL ,就不能锁定指定的数据行,而得到不正确的数据以及没用的库存统计。
这个语句也能利用子查询,另外一个数据库的标准特性。子查询可以让你很省事地把两个查询结合在一起,
锁定行以后,我们需要按照购物车的物品减少对应的库存量。为简便起见,我们对库存不够不报告错误,并把库存变为负数。你可以自己写一个管理页面,查看负数库存的物品,并去订购。
最后,我们更新顾客表中的信用卡,购买信息,合计购买金额,撤掉这个顾客的session。
表五、结账,减库存
function cart_checkout($credit_card,$address,$name) {
global $conn, $customer_id, $feedback;
// 事务开始
query("BEGIN WORK");
// 锁住库存表的对应行,用一个简单的子查询来处理。
$sql="SELECT * FROM item_inventory ".
"WHERE part_number ".
"IN (SELECT part_number FROM cart_items ".
"WHERE customer_id='$customer_id') ".
"FOR UPDATE";
$res=query($sql);
if (!$res || pg_numrows($res)
$feedback .= pg_errormessage($conn);
$feedback .= ' Error - no items locked ';
query("END WORK");
return false;
} else {
// 库存的某几行已被锁定,从购物车取得物品以及数量。
$sql="SELECT part_number,quantity ".
"FROM cart_items ".
"WHERE
customer_id='$customer_id' ".
"ORDER BY part_number DESC";
$res2=query($sql);
if (!$res2 || pg_numrows($res2)
$feedback .= pg_errormessage($conn);
$feedback .= ' Error - no items in cart ';
query("END WORK");
return false;
} else {
$rows=pg_numrows($res2);
// 更新库存余额
for ($i=0; $i
// 读取购物车数据
$quantity=pg_result($res2,$i,'quantity');
$item_id=pg_result($res2,$i,'part_number');
$res3=query("UPDATE item_inventory".
"SET inventory =inventory-$quantity ".
"WHERE part_number='$item_id'");
if (!$res3 || pg_cmdtuples($res3)
$feedback .= pg_errormessage($conn);
$feedback .= ' Error - updating inventory failed ';
query("ROLLBACK");
return false;
}
}
// 库存更新结束,得到这个订单的合计金额并更新顾客记录
$res=query("SELECT sum(cart_items.quantity*item_inventory.price) ".
"FROM cart_items,item_inventory ".
"WHERE cart_items.customer_id='$customer_id' ".
"AND cart_items.part_number=item_inventory.part_number");
if (!$res || pg_numrows($res)
//couldn't get order total
$feedback .= pg_errormessage($conn);
$feedback .= ' Error - couldn\'t get order total ';
query("ROLLBACK");
return false;
} else {
// 更新顾客表
$total=pg_result($res,0,0);
$res=query("UPDATE customers ".
"SET address='$address',name='$name',".
"total_order='$total',credit_card='$credit_card'".
"WHERE customer_id='$customer_id'");
if (!$res || pg_cmdtuples($res)
$feedback .= pg_errormessage($conn);
$feedback .= ' Error - updating customer information ';
query("ROLLBACK");
return false;
} else {
// 改变正式生效
query("COMMIT");
// 删除 session
$customer_id=0;
session_destroy();
return true;
}
}
}
}
}
?>
理论上,这是一个很复杂的交易,每一步必须正确执行,否则,整个事务必须回滚到正确的顺序。
如果你没有使用本例的事务处理,那么万一在更新过程中失败的话,麻烦就大了。可能你只是更新了库存的一部分,如果访问者刷新页面的话,你怎么知道那个库存需要减少呢?
本文不想提供一个购物车的综合解决方案(如果这样的话,只要我有时间,完全可以写一本书了),但是,本文演示了最基本的设计和运行的方法,建议每一位Web 开发人员使用。更深入的讨论可以访问 PHPBuilder.com.
文中所有的代码可以从http://www.phpbuilder.com/columns/linuxjournal200009.php3 下载。
译者注:
作者 Tim Perdue (tim@perdue.net) 是 SourceForge.net 的建设者,以及 PHPBuilder.com 和
Geocrawler.com 的创立?

“这是我目前听过关于AI最好、最治愈的一个应用。”到底是什么应用,能让网友给出如此高度的评价?原来,一个脑洞大开的网友Michelle,用GPT-3造了一个栩栩如生的“童年Michelle”。然后她和童年的自己聊起了天,对方甚至还写来一封信。“童年Michelle”的“学习资料”也很有意思——是Michelle本人的日记,而且是连续十几年,几乎每天都写的那种。日记内容中有她的快乐和梦想,也有恐惧和抱怨;还有很多小秘密,包括和Crush聊天时紧张到眩晕…(不爱写日记的我真的给跪了……)厚厚一叠日记

PHP框架通过以下方式简化电子商务网站的维护和管理:采用MVC架构,将业务逻辑、用户界面和用户交互分离,实现独立管理;提供预构建组件和模块,减少代码重复并简化网站开发;集成内容管理系统(CMS),使非技术人员轻松管理网站内容;提供辅助工具和命令,自动化任务并简化部署、更新和维护;以Laravel为例,通过EloquentORM、ArtisanCLI工具、Scout搜索引擎集成和Cashier支付网关集成等功能,进一步加强网站管理效率。

新的电子商务模式有O2O模式、C2M模式、社交电商模式、跨境电商模式和订阅电商模式。详细介绍:1、O2O模式,这是一种将线上和线下商业结合起来的模式,通过线上平台,商家可以推广自己的产品和服务,吸引消费者到线下实体店面进行购买和体验,这种模式可以充分利用互联网的优势,提高线下店面的曝光度和销售量;2、C2M模式:传统的供应链模式是生产商将产品销售给批发商等等。

随着人工智能的真正潜力刚刚开始显现,技术将帮助电子商务行业实现更高的生产力和卓越的客户服务。随着电子商务初创企业和独角兽企业面临盈利压力和应对客户流失的压力,提高运营效率和提供卓越的客户体验是该行业企业的首要任务之一。人工智能的使用及其通货紧缩效应对于实现这两个目标非常有帮助。集成人工智能的企业可以利用全系统数据,以及基于音频/文本的人工智能自然对话,将其客户服务提升到更高的水平。生成式人工智能可以进一步彻底改变电子商务利益相关者之间的互动原则,这是一组新兴的应用:彻底改变客户支持:客户支持是电

如何使用Go语言和Redis开发电子商务网站引言:随着互联网的发展,电子商务网站已成为购物的主要方式之一。要开发一个高效可靠的电子商务网站,合适的技术选择至关重要。本文将介绍如何使用Go语言和Redis构建一个功能完备的电子商务网站,并提供具体的代码示例。第一部分:搭建环境安装Go语言环境:在Go官网(https://golang.org/dl/)下载并安装

c2c的特点:1、辅助性;C2C对于人类的日常活动来说,是一种互换有无,互相方便的一种买卖关系,对人类正常购买行为的辅助。2、节约性;C2C交易主要应该是二手商品,对二手商品的再次利用本身就是对地球资源的节约。3、繁杂性;C2C中消费者的信息,还是C2C上海量的虚拟商品信息以及少量的消费者的言论评价信息,都说明了C2C的繁杂性。4、创造性;c2c是广大消费者具有创意的交易形式。

昨天,淘宝发布公告,计划修改淘宝平台争议处理规则的相关规定。根据新规定,如果买家满足相关条件发起售后申请,将会进行快速退款或退货退款处理。这与拼多多的“仅退款”政策相似,相信大部分用户对此已有所了解。京东对其开放平台的售后服务管理规则和交易纠纷处理总则进行了修订,新增了用户退款不退货的执行标准。此外,京东还支持用户仅退款,而以前只能申请换货和退货退款。这意味着国内三大电商平台都已加入“仅退款”阵营,不仅淘宝,京东也提供了相应的服务。京东指出,商家交付给消费者的商品存在大量劣质、描述不符、包裹异常

PHP框架在电子商务中发挥重要作用,提升网站性能和转化率。具体而言,PHP框架可提高性能、可维护性、安全性并简化开发。以Laravel为例,可创建一个简单的电子商务网站,包括商品和类别设置、购物车和订单处理、用户界面设计和部署配置。此外,通过缓存、图像优化和跟踪系统等,可进一步优化网站性能和转化率。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

Atom编辑器mac版下载
最流行的的开源编辑器

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

Dreamweaver CS6
视觉化网页开发工具