直播中
介紹
如果你還沒(méi)有用PHP 實(shí)現(xiàn)你自已的購(gòu)物籃,在讀完這篇文章之后你應(yīng)該可以創(chuàng)建一個(gè)了。甚至你可能已經(jīng)有了一個(gè)購(gòu)物籃,我在這里所提供的一些技巧可能會(huì)幫助你改善你的系統(tǒng)。
我將給你一些提示,關(guān)于如何去做也許才能減少對(duì)購(gòu)物籃表的無(wú)限的查詢(xún),或減少無(wú)限的文本文件填充你的文件系統(tǒng),因?yàn)閼?yīng)用程序只會(huì)做但不會(huì)刪除它們。
如果你對(duì)這類(lèi)的題目是個(gè)新手,不要害怕。它實(shí)際上相當(dāng)簡(jiǎn)單和有效,你只需要一個(gè)支持php4的主機(jī),象notepad或vi之類(lèi)的html編輯器,你寶貴的幾分種,和這個(gè)小例子。
想法
在1998年,我有一個(gè)在硬件商店工作的朋友要求我為他們編寫(xiě)一個(gè)在線商店。需要快速和簡(jiǎn)單,同時(shí)還要有在線管理。當(dāng)我發(fā)著39度高燒的時(shí)候我變得想當(dāng)有創(chuàng)建力,所以我用perl寫(xiě)了那個(gè)東西,使用minisql作為后端。在整個(gè)處理中我插入了我所提到的迷你購(gòu)物籃。
這個(gè)迷你購(gòu)物籃與平常的購(gòu)物車(chē)只有很小的不同,它會(huì)在每一頁(yè)顯示你的購(gòu)物車(chē)的東西,不需要在放入一件東西后在購(gòu)物車(chē)來(lái)回跳轉(zhuǎn)。這就是我寫(xiě)這篇文章的初衷。
目標(biāo)
人們喜歡控制,那么為什么不給他們些透明度,以便讓他們相信擁有了控制?這個(gè)迷你購(gòu)物籃演示了一個(gè)完美的方法:它提供給人們所必須的信息,并且節(jié)省了他們一次點(diǎn)擊,接近了在線商店的3擊范例。
所以,目標(biāo)就是在任何時(shí)候?qū)⑦@個(gè)迷你購(gòu)物籃顯示為你的頁(yè)面上的一部分,在結(jié)尾處提供一個(gè)摘要用以修改購(gòu)物籃中的物品,接著在最后發(fā)送一個(gè)訂單。
要求
你應(yīng)該知道什么是session。如果不知道,這里有一個(gè)快速的綱要。已經(jīng)有很多文章關(guān)于這個(gè)話(huà)題,你可以從中找到所有你需要的代碼例子。在你的開(kāi)始頁(yè)面打開(kāi)一個(gè)session,使用
<?php
session_start();
?>
這樣將創(chuàng)建一個(gè)session名字和一個(gè)session id。你現(xiàn)在既可以使用缺省的通過(guò)基于cookie的設(shè)置session的方式,通過(guò)一個(gè)表單來(lái)傳遞session id,或把它作為一個(gè)變量附在你的鏈接上(get方法)的方法。不要忘記在最后釋放session。:)
你的商品應(yīng)該有一個(gè)名字,價(jià)格和唯一標(biāo)識(shí),以便能用在這個(gè)例子中,如果不這樣,你可能需要做一點(diǎn)修改。這里我使用mysql作為后端以便建立頁(yè)面及其它,為了讓購(gòu)物能工作這不是必須的。:)
你應(yīng)該了解數(shù)組?,F(xiàn)在如果有人有時(shí)間利用我的代碼并且創(chuàng)建一個(gè)它的類(lèi),我理所當(dāng)然地要感激得到它。
定義
為了簡(jiǎn)化這個(gè)例子,我使用了四個(gè)獨(dú)立的數(shù)組和一些額外的變量。代碼可以被優(yōu)化。這樣可以很容易地顯示想法和閱讀代碼??梢允褂妙?lèi)更好的完成,但是我不能十分肯定是否能夠把對(duì)象保存到session 里。有人想對(duì)此發(fā)表評(píng)論嗎?
我們還需要一個(gè)項(xiàng)目計(jì)數(shù)器。當(dāng)然可以使用count() 命令來(lái)實(shí)現(xiàn),我只不過(guò)認(rèn)為它足夠好,以便總能知道有多少的項(xiàng)目,并且它也為循環(huán)提供了一個(gè)好的計(jì)數(shù)器。
工作
讓我們假設(shè)在你的HTML頁(yè)中有一個(gè)商品列表
ID Name Price
1 Mouse 25.00 add
2 Key 100.00 add
3 Car 5000.00 add
4 Game 25.00 add
向你的頁(yè)面增加鏈接
上面的'add'字段應(yīng)該是一個(gè)鏈接,用來(lái)將商品放到迷你購(gòu)物籃中。使用$PHP_SELF將這個(gè)鏈接指向它自已。然后向它增加商品信息。這里是商品1的例子。
<A HREF="<?echo $PHP_SELF;?>?id=1&price=25&basket=Mouse">add</A>
商品的名稱(chēng)能夠包含空格,所以將它放在鏈接的最后。Get方法好象對(duì)這個(gè)很挑剔。
準(zhǔn)備迷你購(gòu)物籃
為了代碼重用,讓我們創(chuàng)建一個(gè)額外的文件minibasket.inc。我使用.inc擴(kuò)展名來(lái)標(biāo)識(shí)我的包括文件。
使用這個(gè)外部文件的原因是,盡管你將使用session變量來(lái)傳遞給購(gòu)物籃,代碼仍然需要有效。這個(gè)文件將
包含顯示迷你購(gòu)物籃的代碼,也包話(huà)增加項(xiàng)目的函數(shù)。實(shí)現(xiàn)它的最好的地方是將 <?php include ("minibasket.inc"); ?> 命令放在你需要的地方。
minibasket.inc的邏輯
花些時(shí)間考慮一下這個(gè)。迷你購(gòu)物籃應(yīng)該是個(gè)什么樣子,它需要些什么特性?這里顯示的迷你購(gòu)物籃應(yīng)
該看上去象這樣:
# Name Price
1 Mouse 25.00
3 Game 75.00
Total 100.00
你可以很容易的通過(guò)使用一個(gè)外部樣式表格式化這個(gè)輸出??墒?,它不應(yīng)該太大。這個(gè)迷你購(gòu)物籃是一
個(gè)信息,然而它不應(yīng)該成為你所顯示頁(yè)面的焦點(diǎn)。
這個(gè)文件的邏輯非常簡(jiǎn)單。
檢查是否需要增加一個(gè)新的項(xiàng)目。
如果true,增加項(xiàng)目
在加入中,它要檢查復(fù)重的記錄,通過(guò)更新數(shù)量和價(jià)格來(lái)更新存在的記錄。
片段1。檢查將要增加的新的項(xiàng)目
這是一個(gè)正常的IF語(yǔ)句,用于檢查$basket變量的值。
<?php
if ($basket!=""){
//向籃子中加入項(xiàng)目
}
?>
片段2。在瀏覽器中顯示籃子
<?php
if ($ses_basket_items>0){
// 如果在籃子中有項(xiàng)目
for ($basket_counter=0;$basket_counter<$ses_basket_items;$basket_counter++){
// 遍歷籃子,打印出每一行
// 你當(dāng)然可以用格表來(lái)格式化顯示
// 需要通過(guò)格式化來(lái)顯示價(jià)格的分值。如果沒(méi)有格式化,則.00是不會(huì)顯示出來(lái)的
$price=sprintf("%01.2f",$ses_basket_price[$basket_counter]);
$amount=$ses_basket_amount[$basket_counter];
$name=$ses_basket_name[$basket_counter];
echo "$amount $name $price";
echo "<BR>\n";
}
} else {
// 在籃子中沒(méi)有商品
// 設(shè)置項(xiàng)目計(jì)數(shù)為0,且清除所有的變量
// 這是一個(gè)清除處理。它防止人們得到舊的數(shù)組
$ses_basket_items=0;
unset($ses_basket_name);
unset($ses_basket_amount);
unset($ses_basket_price);
unset($ses_basket_id);
}
?>
這段代碼不會(huì)產(chǎn)生任何結(jié)果。項(xiàng)目還沒(méi)有被填充,籃子總是空的,所以籃子不會(huì)被顯示。那么讓我們向這個(gè)籃子中加些項(xiàng)目吧。
[Page]
片段3。創(chuàng)建新的籃子并向其中增加一條項(xiàng)目
<?php
// 將項(xiàng)目計(jì)數(shù)設(shè)為1
$ses_basket_items=1;
// 填充4個(gè)數(shù)組的第0個(gè)位置,使用從href鏈接傳過(guò)來(lái)的值
// 鏈接是在‘給你的頁(yè)面增加鏈接’部分所講的
$ses_basket_name[0]=$basket;
$ses_basket_amount[0]=1;
$ses_basket_price[0]=$price;
$ses_basket_id[0]=$id;
// 在session中注冊(cè)新的籃子
session_register("ses_basket_items");
session_register("ses_basket_name");
session_register("ses_basket_amount");
session_register("ses_basket_price");
session_register("ses_basket_id");
?>
這樣將創(chuàng)建一個(gè)籃子,將所以的值填在數(shù)組第0個(gè)位置上,并利用session注冊(cè)數(shù)組。一個(gè)籃子誕生了。
片段4。填充籃子
<?php
$basket_position_counter=0; //籃子中的位置
$double=0; //雙重入口標(biāo)志設(shè)為NO
if ($ses_basket_items>0){
// 檢查是否籃子包含的項(xiàng)目中有雙重入口
foreach ($ses_basket_name as $basket_item){
// 遍歷數(shù)組所包含的名字,檢查是否與從href所傳來(lái)的相配匹
if ($basket_item==$basket){
// 如果在籃子中已經(jīng)有了一個(gè)項(xiàng)目,將flag設(shè)為1
$double=1;
// 記住項(xiàng)目的位置,將進(jìn)行更新
$basket_position=$basket_position_counter;
}
$basket_position_counter++; //增加籃子中的實(shí)際位置
}
}
// 更新籃子
if ($double==1){
// 如果項(xiàng)目在你的籃子中已經(jīng)存在則更新在$basket_position處理的數(shù)量和位置
$oldamount=$ses_basket_amount[$basket_position];
$ses_basket_amount[$basket_position]++;
$amount=$ses_basket_amount[$basket_position];
$oldprice=$ses_basket_price[$basket_position];
//更新價(jià)格
$newprice=($oldprice/$oldamount)*$amount;
$ses_basket_price[$basket_position]=$newprice;
}else{
// 如果它不在你的籃子中,則在數(shù)組末尾增加新的項(xiàng)目
$ses_basket_name[]=$basket;
$ses_basket_amount[]=1;
$ses_basket_price[]=$price;
$ses_basket_id[]=$id;
$ses_basket_items++;
}
?>
太好了,現(xiàn)在你可以填充迷你購(gòu)物籃并顯示它了。
將代碼片斷組織到一起
讓我們將代碼組織到一起并且存為minibasket.inc。
<?php
// 記住在代碼片段1中, 決定是不是要增加?
// 讓我們?cè)谶@里重復(fù)它
if ($basket!=""){
// 在這里,項(xiàng)目將要加到籃中。讓我們檢查一下是否存在一個(gè)注冊(cè)過(guò)的籃子
if (session_is_registered("ses_basket_items")){
// 存在一個(gè)注冊(cè)過(guò)的籃子,將代碼片段4放在這里。
// 它增加項(xiàng)目到注冊(cè)過(guò)的籃子中,檢查重復(fù)記錄,更新它們或在數(shù)組的最后增加項(xiàng)目
} else {
// 不存在注冊(cè)過(guò)的籃子,將代碼片段3放在這里。它創(chuàng)建一個(gè)新的籃子,并且
// 通過(guò)session注冊(cè)它。
}
}
// 剩下的都是代碼片段2。如果籃子中有物品時(shí)用于顯示它們。
// 加到這里。
?>
瞧,不錯(cuò)吧。"c'est tout", 法國(guó)人會(huì)這樣說(shuō)。如果都做好了,你可以保存這個(gè)文件為minibasket.inc 并且將其包括到顯示商品的PHP頁(yè)面中。
Zip格式的minibasket.inc和basket.php