В одной из предыдущих заметок я писал, как можно реализовать корзину для Интернет-магазина средствами JavaScript. Давайте сегодня добавим форму для оформления заказа, получив таким образом простой Интернет-магазин. Для начала немного модифицируем файл корзины, добавив в него чтение информации о товарах магазина из таблицы products базы данных:

Корзина для Интернет-магазина (файл shop.php):
<?php
$dblocation = "localhost"; // Имя сервера
$dbuser = "root"; // Имя пользователя
$dbpswrd = ""; // Пароль
$dbname = "catalog"; // Имя базы данных
// Соединение с сервером базы данных
$dblink = mysql_connect( $dblocation, $dbuser, $dbpswrd );
mysql_query( 'SET NAMES cp1251' );
// Выбираем базу данных
mysql_select_db( $dbname, $dblink );
// Формируем запрос на извлечение товарных позиций
$query = 'SELECT code, title, description, price
FROM products
ORDER BY title';
$res = mysql_query( $query );
$cnt = mysql_num_rows( $res );
$goods = '';
for( $i = 1; $prd = mysql_fetch_row( $res ); $i++ ) {
if ( $i == $cnt )
$goods = $goods.' ["'.$prd[0].'","'.$prd[1].'","'.$prd[2].'",'.$prd[3].']'."\n";
else
$goods = $goods.' ["'.$prd[0].'","'.$prd[1].'","'.$prd[2].'",'.$prd[3].'],'."\n";
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<html>
<title>Интернет-магазин</title>
<meta http-equiv="content-type" content="text/html; windows-1251" />
<script type="text/javascript">
var goods = new Array();
goods = [
<?php
echo $goods;
?>
];
var count = goods.length;
var orders = new Array();
for( var i = 0; i < count; i++ ) orders[i] = 0;
var param = getCookie( "basket" );
for( var i = 0; i < count; i++ ) {
pos = param.indexOf( ',' );
if( pos == -1 ) break;
orders[i] = parseInt( param.substring ( -1, pos ) );
param = param.substring ( pos+1 );
}
window.onload = function() {
var table = createTable(goods);
document.getElementById("shop").appendChild(table);
}
function updateTable()
{
var totalGoods = 0;
var totalCosts = 0;
var basket = "";
for ( var i = 0; i < count; i++ ) {
var item = document.getElementById( "item"+i );
var cnt = parseInt( item.value );
if ( isNaN(cnt) || cnt < 0 ) {
cnt = 0;
item.value = "0";
}
if ( cnt > 0 )
item.parentNode.parentNode.setAttribute("bgcolor", "lightblue");
else
item.parentNode.parentNode.removeAttribute("bgcolor")
orders[i] = cnt;
basket = basket + cnt + ",";
totalGoods = totalGoods + cnt;
totalCosts = totalCosts + cnt*goods[i][3];
}
var span = document.getElementById("totalGoods");
var newTextNode = document.createTextNode(totalGoods);
span.replaceChild(newTextNode, span.firstChild);
var span = document.getElementById("totalCosts");
var newTextNode = document.createTextNode(totalCosts);
span.replaceChild(newTextNode, span.firstChild);
setCookie("basket", basket);
}
function createTable(data) {
var table = document.createElement("table");
table.setAttribute("border", "1");
table.setAttribute("cellspacing", "0");
table.setAttribute("cellpadding", "2");
var thead = document.createElement("thead");
var tr = document.createElement("tr");
tr.setAttribute("bgcolor", "lightgrey");
var head = new Array("Код","Наименование","Описание","Стоимость","Количество");
for (var i = 0; i < head.length; i++) {
var th = document.createElement("th");
var newText = document.createTextNode(head[i]);
th.appendChild(newText);
tr.appendChild(th);
}
thead.appendChild(tr);
table.appendChild(thead);
var totalGoods = 0;
var totalCosts = 0.0;
var tbody = document.createElement("tbody");
for (var i = 0; i < data.length; i++) {
var tr = document.createElement("tr");
if ( orders[i] > 0 ) tr.setAttribute("bgcolor", "lightblue");
for (var j=0; j < data[i].length; j++) {
var td = document.createElement("td");
var newText = document.createTextNode(data[i][j]);
td.appendChild(newText);
tr.appendChild(td);
}
var td = document.createElement("td");
var newInput = document.createElement("input");
newInput.setAttribute("type", "text");
newInput.setAttribute("id", "item"+i);
newInput.setAttribute("value", orders[i]);
newInput.setAttribute("size", "3");
newInput.onblur = updateTable;
td.appendChild(newInput);
tr.appendChild(td);
tbody.appendChild(tr);
totalGoods = totalGoods + orders[i];
totalCosts = totalCosts + orders[i]*goods[i][3];
}
var tr = document.createElement("tr");
var td = document.createElement("td");
td.setAttribute("colspan", "3");
td.setAttribute("align", "right");
var textNode = document.createTextNode("Итого:");
td.appendChild(textNode);
tr.appendChild(td);
var td = document.createElement("td");
var span = document.createElement("span");
span.setAttribute("id", "totalCosts");
var textNode = document.createTextNode(totalCosts);
span.appendChild(textNode);
td.appendChild(span);
tr.appendChild(td);
var td = document.createElement("td");
var span = document.createElement("span");
span.setAttribute("id", "totalGoods");
var textNode = document.createTextNode(totalGoods);
span.appendChild(textNode);
td.appendChild(span);
tr.appendChild(td);
tbody.appendChild(tr);
table.appendChild(tbody);
return table;
}
function setCookie(name,value)
{
document.cookie = name + '=' + value;
}
function getCookie(name)
{
var arg = name + "=";
startpos = document.cookie.indexOf(arg, 0);
if (startpos == -1)
return "";
else
startpos += arg.length;
endpos = document.cookie.indexOf(';', startpos);
if (endpos == -1) endpos = document.cookie.length;
return document.cookie.substring(startpos, endpos);
}
</script>
</head>
<body>
<div id="shop"></div>
<p><a href="order.php">Оформить заказ</a></p>
</body>
</html>

Как вы понимаете, совсем не обязательно хранить ассортимент продукции в базе данных. Для этой цели можно использовать XML или Excel-файл. В этом случае нам будет достаточно отредактировать Excel-файл и закачать его на сервер, чтобы обновить цены или добавть новый товар.
Для оформления заказа покупатель должен заполнить форму:

Скрипт отправки сообщения на e-mail о заказе в магазине (файл order.php):
<?php
session_start();
$admin = 'admin@mail.ru';
$dblocation = "localhost"; // Имя сервера
$dbuser = "root"; // Имя пользователя
$dbpswrd = ""; // Пароль
$dbname = "catalog"; // Имя базы данных
// Соединение с сервером базы данных
$dblink = mysql_connect( $dblocation, $dbuser, $dbpswrd );
mysql_query( 'SET NAMES cp1251' );
// Выбираем базу данных
mysql_select_db( $dbname, $dblink );
// Если не установлена cookie-переменная basket -
// значит пользователь попал сюда по ошибке
if ( !isset( $_COOKIE['basket'] ) ) {
header( 'Location: shop.php' );
die();
}
if ( isset($_SESSION['success']) and $_SESSION['success'] ) {
setcookie ('basket', '', time() - 3600);
$notShowForm = true;
}
// Если в корзине нет товаров
$cart = explode( ',', $_COOKIE['basket'] );
if ( array_sum( $cart ) == 0 ) {
echo '<p>Ваша корзина пуста!</p>';
echo '<p><a href="shop.php">Вернуться к покупкам</a></p>';
die();
}
// Формируем запрос на извлечение товарных позиций
$query = 'SELECT code, title, description, price
FROM products
ORDER BY title';
$res = mysql_query($query);
$order = '<table border="1" cellpadding="3" cellspacing="0">';
$order = $order.'<tr>';
$order = $order.'<th>Код</th>';
$order = $order.'<th>Наименование</th>';
$order = $order.'<th>Описание</th>';
$order = $order.'<th>Стоимость</th>';
$order = $order.'<th>Количество</th>';
$order = $order.'</tr>';
$i = 0;
$total = 0;
while( $prd = mysql_fetch_array( $res ) ) {
if ( $cart[$i] > 0 ) {
$order = $order.'<tr>';
$order = $order.'<td>'.$prd['code'].'</td>';
$order = $order.'<td>'.$prd['title'].'</td>';
$order = $order.'<td>'.$prd['description'].'</td>';
$order = $order.'<td align="right">'.$prd['price'].'</td>';
$order = $order.'<td align="center">'.$cart[$i].'</td>';
$order = $order.'</tr>';
$total = $total + $cart[$i]*$prd['price'];
}
$i++;
}
$order = $order.'</table>';
$order = $order.'<p style="font-weight:bold">Итого: '.$total.'</p>';
if ( isset( $_SESSION['orderForm'] ) ) {
echo $_SESSION['orderForm']['error'];
$name = htmlspecialchars ( $_SESSION['orderForm']['name'] );
$email = htmlspecialchars ( $_SESSION['orderForm']['email'] );
$phone = htmlspecialchars ( $_SESSION['orderForm']['phone'] );
$adress = htmlspecialchars ( $_SESSION['orderForm']['adress'] );
unset( $_SESSION['orderForm'] );
} else {
$name = '';
$email = '';
$phone = '';
$adress = '';
}
if ( isset( $_POST['sendOrder'] ) ) {
$name = substr( $_POST['name'], 0, 64 );
$email = substr( $_POST['email'], 0, 64 );
$phone = substr( $_POST['phone'], 0, 64 );
$adress = substr( $_POST['adress'], 0, 250 );
// Проверка правильности заполнеия формы
$error = '';
if ( empty( $name ) ) $error = $error.'<li>Не заполнено поле "Имя"</li>';
if ( empty( $email ) ) $error = $error.'<li>Не заполнено поле "E-mail"</li>';
if ( empty( $phone ) ) $error = $error.'<li>Не заполнено поле "Телефон"</li>';
if ( empty( $adress ) ) $error = $error.'<li>Не заполнено поле "Адрес"</li>';
if ( !empty( $email ) and !preg_match( "#^[0-9a-z_\-\.]+@[0-9a-z\-\.]+\.[a-z]{2,6}$#i", $email ) )
$error = $error.'<li>поле "E-mail" должно соответствовать формату somebody@somewhere.ru</li>';
// Если при заполнении формы были допущены ошибки
if ( !empty( $error ) ) {
$_SESSION['orderForm']['error'] = '<p>При заполнении формы были допущены ошибки:</p><ul>'.$error.'</ul>';
$_SESSION['orderForm']['name'] = $name;
$_SESSION['orderForm']['email'] = $email;
$_SESSION['orderForm']['phone'] = $phone;
$_SESSION['orderForm']['adress'] = $adress;
header( 'Location: '.$_SERVER['PHP_SELF'] );
die();
}
$theme = '=?windows-1251?B?'.base64_encode('Заказ в магазине').'?=';
$headers = "From: ".$_SERVER['SERVER_NAME']." <".$admin.">\r\n";
// Отправляем скрытую копию письма администратору сайта
$headers = $headers."Bcc: <".$admin.">\r\n";
$headers = $headers."Return-path: <".$admin.">\r\n";
$headers = $headers."Content-type: text/html; charset=\"windows-1251\"\r\n";
$headers = $headers."Content-Transfer-Encoding: quoted-printable\r\n\r\n";
$body = '<h1>Заказ в магазине</h1>';
$body = $body.'<table>';
$body = $body.'<tr>';
$body = $body.'<td>Имя:</td><td>'.$name.'</td>';
$body = $body.'</tr>';
$body = $body.'<tr>';
$body = $body.'<td>E-mail:</td><td>'.$email.'</td>';
$body = $body.'</tr>';
$body = $body.'<tr>';
$body = $body.'<td>Телефон:</td><td>'.$phone.'</td>';
$body = $body.'</tr>';
$body = $body.'<tr>';
$body = $body.'<td>Адрес:</td><td>'.$adress.'</td>';
$body = $body.'</tr>';
$body = $body.'</table>';
$body = $body.'<br/><br/>';
$body = $body.$order;
$body = $body.'<p>Спасибо за покупку! В ближайшее время наш менеджер свяжется с Вами.</p>';
$body = quoted_printable_encode( $body );
if ( mail($email, $theme, $body, $headers) ) {
$_SESSION['success'] = true;
} else {
$_SESSION['success'] = false;
}
header( 'Location: '.$_SERVER['PHP_SELF'] );
die();
}
function quoted_printable_encode ( $string ) {
// rule #2, #3 (leaves space and tab characters in tact)
$string = preg_replace_callback (
'/[^\x21-\x3C\x3E-\x7E\x09\x20]/',
'quoted_printable_encode_character',
$string
);
$newline = "=\r\n"; // '=' + CRLF (rule #4)
// make sure the splitting of lines does not interfere with escaped characters
// (chunk_split fails here)
$string = preg_replace ( '/(.{73}[^=]{0,3})/', '$1'.$newline, $string);
return $string;
}
function quoted_printable_encode_character ( $matches ) {
$character = $matches[0];
return sprintf ( '=%02x', ord ( $character ) );
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Оформить заказ</title>
</head>
<body>
<h1>Оформить заказ</h1>
<?php
if ( isset( $_SESSION['success'] ) ) {
if ( $_SESSION['success'] ) {
echo '<p>Спасибо за покупку! В ближайшее время наш менеджер свяжется с Вами.</p>';
} else {
echo '<p>Ошибка при отправке заказа, попробуйте повторить попытку.</p>';
}
unset( $_SESSION['success'] );
}
if ( !isset( $notShowForm ) ) {
echo '<form action="'.$_SERVER['PHP_SELF'].'" method="POST">';
echo '<table>';
echo '<tr><td>Имя:</td><td><input type="text" name="name" maxlength="64" value="'.$name.'" /></td></tr>';
echo '<tr><td>E-mail:</td><td><input type="text" name="email" maxlength="64" value="'.$email.'" /></td></tr>';
echo '<tr><td>Телефон:</td><td><input type="text" name="phone" maxlength="64" value="'.$phone.'" /></td></tr>';
echo '<tr><td>Адрес:</td><td><textarea name="adress" rows="5" cols="30">'.$adress.'</textarea></td></tr>';
echo '<tr><td> </td><td><input type="submit" name="sendOrder" value="Отправить" /></td></tr>';
echo '</table>';
echo '</form>';
}
?>
<p><a href="shop.php">Вернуться в магазин</a></p>
</body>
</html>
Рабочий пример можно посмотреть здесь.