ресурс для начинающих веб-разработчиков
комплексные веб-услуги по созданию сайтов

Справочный материал по основным языкам программирования и верстки сайтов.

Готовая методика создания простых и сложных динамичных сайтов, с использованием PHP и MySQL.

Использование веб-редактора Adobe Dreamweaver в разработке сайтов.

Использование графических редакторов Adobe Flash, Adobe Photoshop, Adobe Fireworks в подготовке веб-графики.

Разработка веб-сайтов под "ключ".

Разработка отдельных фрагментов сайтов, консультации по вопросам верстки веб-страниц и веб-программирования.

Выполнение окончательного расчета

Выполнение окончательного расчета

Когда пользователь щелкает на кнопке перехода к окончательному расчету (Перейти в кассу), вызывается сценарий checkout.php. Доступ к странице окончательного расчета и связанным с ней страницам должен осуществляться через SSL-соединение, однако наше демонстрационное приложение этого не требует.

Внешний вид страницы окончательного расчета показан ниже.

Сценарий checkuut.php принимает детальную информацию о клиенте

Данный сценарий требует, чтобы клиент ввел свой почтовый адрес (а также адрес доставки, если они отличаются).

checkout.php — сценарий принимающий детальную информацию о клиенте

<?php
// Включить наш набор функций
require ('book_sc_fns.php');

// Для покупательской тележки необходимо запустить сеанс
session_start();
$pagename = "Окончательный расчет";
$keywords= "";
$description="Окончательный расчет";
do_html_header($pagename, $keywords, $description);
echo "<section class=blok>";
echo "<div class=col1>";
echo "<header>";
echo "<h5>Категория книг</h5>";
echo "</header>";
echo "<nav>";
// Извлечь категории из базы данных
$cat_array = get_categories();
display_categories($cat_array);
echo "</nav>";
echo "</div>";
echo "<div class=col2>";
echo "<header>";
echo "<h2>$pagename</h2>";
echo "</header>";
echo "<article class=checkout>";
if($_SESSION['cart']&&array_count_values($_SESSION['cart']))
{
display_cart($_SESSION['cart'], false, 0);
display_checkout_form();
}
else
echo '<p>Ваша тележка пуста</p>';

display_button('show_cart.php', 'continue-shopping', 'Продолжить покупки');
echo "</article>";
echo "</div>";
echo"</section>";
do_html_footer();
?>

Сценарий не содержит ничего особо примечательного. Если тележка пуста, об этом выводится соответствующее уведомление. В противном случает отображается форма, показанная выше.

display_checkout_form()— функция из библиотеки output_fns.php, которая запрашивает ФИО и почтовый адрес клиента

<?php
function display_checkout_form()
{
// Выводит форму, которая запрашивает ФИО и адрес

?>
<br>
<table border = 0 width = '100%' cellspacing = 0>
<form action = 'purchase.php' method = 'post'>
<tr><th colspan = 2 bgcolor='#cccccc'>Информация о вас</th></tr>
<tr>
<td>ФИО</td>
<td><input type = 'text' name = 'name' value = "" maxlength = 40 size = 40></td>
</tr>
<tr>
<td>Адрес</td>
<td><input type = 'text' name = 'address' value = "" maxlength = 40 size = 40></td>
</tr>
<tr>
<td>Город/село</td>
<td><input type = 'text' name = 'city' value = "" maxlength = 20 size = 40></td>
</tr>
<tr>
<td>Область</td>
<td><input type = 'text' name = 'state' value = "" maxlength = 20 size = 40></td>
</tr>
<tr>
<td>Почтовый индекс</td>
<td><input type = 'text' name = 'zip' value = "" maxlength = 10 size = 40></td>
</tr>
<tr>
<td>Страна</td>
<td><input type = 'text' name = 'country' value = "" maxlength = 20 size = 40></td>
</tr>
<tr><th colspan = 2 bgcolor='#cccccc'>Адрес для доставки (не заполняйте поля, если совпадает с указанным выше)</th></tr>
<tr>
<td>ФИО</td>
<td><input type = 'text' name = 'ship_name' value = "" maxlength = 40 size = 40></td>
</tr>
<tr>
<td>Адрес</td>
<td><input type = 'text' name = 'ship_address' value = "" maxlength = 40 size = 40></td>
</tr>
<tr>
<td>Город/село</td>
<td><input type = 'text' name = 'ship_city' value = "" maxlength = 20 size = 40></td>
</tr>
<tr>
<td>Область</td>
<td><input type = 'text' name = 'ship_state' value = "" maxlength = 20 size = 40></td>
</tr>
<tr>
<td>Почтовый индекс</td>
<td><input type = 'text' name = 'ship_zip' value = "" maxlength = 10 size = 40></td>
</tr>
<tr>
<td>Страна</td>
<td><input type = 'text' name = 'ship_country' value = "" maxlength = 20 size = 40></td>
</tr>
<tr>
<td colspan = 2 align = 'center'>
<b>Пожалуйста, щелкните на кнопке "Купить" для того, чтобы подтвердить покупку,
либо на кнопке "Продолжить покупки" для продолжения покупок.</b>
<?php display_form_button('purchase', 'Приобрести выбранное'); ?>
</td>
</tr>
</form>
</table><hr>
<?php
}
?>

Когда пользователь продолжает работу, щелкнув на кнопке Купить в нижней части формы, запускается сценарий purchase.php.

Сценарий purchase.php вычисляет окончательную сумму заказа и расходы на доставку, а также принимает данные, касающиеся платежа

По сравнению с checkout.php этот сценарий немного сложнее.

purchase.php — сценарий сохраняющий заказ в базе данных и принимающий данные, касающиеся платежа

<?php
// Включить наш набор функций
require_once('book_sc_fns.php');
// Для покупательской тележки необходимо запустить сеанс
session_start();
$pagename = "Окончательный расчет";
$keywords= "";
$description="Интернет-магазин ABC-Book. Книги традиционные и на электронных носителях";
do_html_header($pagename, $keywords, $description);
echo "<section class=blok>";
echo "<div class=col1>";
echo "<header>";
echo "<h5>Категория книг</h5>";
echo "</header>";
echo "<nav>";
// Извлечь категории из базы данных
$cat_array = get_categories();
display_categories($cat_array);
echo "</nav>";
echo "</div>";
echo "<div class=col2>";
echo "<header>";
echo "<h2>$pagename</h2>";
echo "</header>";
echo "<article>";

// Создать короткие имена переменных
$name = $_POST['name'];
$address = $_POST['address'];
$city = $_POST['city'];
$zip = $_POST['zip'];
$country = $_POST['country'];

// Если форма заполнена
if($_SESSION['cart']&&$name&&$address&&$city&&$zip&&$country)
{
// Можно ли вставлять в базу данных?
if( insert_order($_POST)!=false )
{
// Вывести тележку без изображений товаров и не разрешая изменения
display_cart($_SESSION['cart'], false, 0);

display_shipping(calculate_shipping_cost());

// Получить информацию по кредитной карточке
display_card_form($name);

display_button('show_cart.php', 'continue-shopping', 'Продолжить покупки');
}
else
{
echo 'Невозможно сохранить данные. Пожалуйста, повторите попытку позже.';
display_button('checkout.php', 'back', 'Назад');
}
}
else
{
echo 'Вы заполнили не все поля. Пожалуйста, повторите попытку.<hr />';
display_button('checkout.php', 'back', 'Назад');
}
echo "</article>";
echo "</div>";
echo"</section>";
do_html_footer();
?>

Логика сценария довольно-таки проста: выполняется проверка, что клиент заполнил все поля формы, после чего в базе данных сохраняется введенная информация путем вызова функции insert_order(). Эта функция вставляет сведения о клиенте в базу данных.

Функция insert_order() из библиотеки order_fns.php — вставляет в базу данных детальную информацию о заказе

<?php
function insert_order($order_details)
{

// Извлечь детальную информацию о заказе и поместить ее в переменные
extract($order_details);

// Установить адрес доставки равным почтовому адресу
if(!$ship_name&&!$ship_address&&!$ship_city&&
!$ship_state&&!$ship_zip&&!$ship_country)
{
$ship_name = $name;
$ship_address = $address;
$ship_city = $city;
$ship_state = $state;
$ship_zip = $zip;
$ship_country = $country;
}

$conn = db_connect();

// Вставка заказа должна выполняться в виде транзакции,
// поэтому необходимо отключить autocommit
$conn->autocommit(FALSE);

// Вставить почтовый адрес клиента
$query = "select customerid from customers where
name = '$name' and address = '$address'
and city = '$city' and state = '$state'
and zip = '$zip' and country = '$country'"
;
$result = $conn->query($query);
if($result->num_rows>0)
{
$customer = $result->fetch_object();
$customerid = $customer->customerid;
}
else
{
$query= "INSERT INTO customers VALUES(NULL, '$name', '$address', '$city', '$state', '$zip', '$country')";
$result = $conn->query($query);
if (!$result)
return false;
}
$customerid = $conn->insert_id;

$date = date('Y-m-d');
$query = "INSERT INTO orders VALUES(NULL, $customerid, ".$_SESSION['total_price'].", '$date',
'PARTIAL', '$ship_name','$ship_address', '$ship_city', '$ship_state', '$ship_zip', '$ship_country')"
;

$result = $conn->query($query) ;
if (!$result)
return false;

$query = "select orderid from orders where
customerid = $customerid and
amount > "
.$_SESSION['total_price']."-.001 and
amount < "
.$_SESSION['total_price']."+.001 and
date = '$date' and
order_status = 'PARTIAL' and
ship_name = '$ship_name' and
ship_address = '$ship_address' and
ship_city = '$ship_city' and
ship_state = '$ship_state' and
ship_zip = '$ship_zip' and
ship_country = '$ship_country'"
;
$result = $conn->query($query);
if($result->num_rows>0)
{
$order = $result->fetch_object();
$orderid = $order->orderid;
}
else
return false;

// Вставить каждую книгу из числа заказанных
foreach($_SESSION['cart'] as $isbn => $quantity)
{
$detail = get_book_details($isbn);
$query = "DELETE FROM order_items WHERE orderid =$orderid and isbn =$isbn";
$result = $conn->query($query);
$query = "INSERT INTO order_items VALUES($orderid, $isbn, ".$detail['price'].", $quantity)";
$result = $conn->query($query);
if(!$result)
return false;
}

// конец транзакции
$conn->commit();
$conn->autocommit(TRUE);

return $orderid;
}

?>

Код функции insert_order() достаточно длинный, поскольку необходимо выполнить вставку данных о клиенте, заказе, а также информацию о каждой приобретаемой книге.

Следует отметить, что различные части вставки оформлены как транзакция, которая начинается с оператора

$conn->autocommit(FALSE);

и заканчивается операторами

$conn->commit();
$conn->autocommit(TRUE);

Это единственное место в приложении, где должна применяться транзакция. Как избежать их? Посмотрите на код функции db_connect():

<?php
function db_connect()
{

$result = new mysqli('localhost', 'root', 'admin', 'book_sc');
$result->set_charset("utf8");
if (!$result)
return false;
$result->autocommit(TRUE);
return $result;
}
?>

Очевидно, что этот код отличается от применяемого в функции insert_order().

После создания соединения с MySQL включается режим автоматического сохранения транзакций (autocommit). Это гарантирует автоматическое сохранение результатов любого SQL-оператора. Однако если необходимо выдать целую последовательность взаимосвязанных SQL-операторов в виде единственной транзакции, потребуется отключить режим autocommit, выполнить серию вставок, сохранить данные и вновь включить режим autocommit.

Затем определяется стоимость доставки по адресу клиента, которая выводится на экран с помощью строки кода:

display_shipping(calculate_shipping_cost());

function calculate_shipping_cost()
{
// Поскольку доставка осуществляется по всему миру
// посредством телепортирования, стоимость доставки фиксирована
return 200.00;
}

Код вычисления стоимости доставки, оформленный в виде функции calculate_shipping_cost(), всегда возвращает значение 200 рублей. В реальном сайте, реализующем онлайновую торговлю, потребуется предоставить клиенту выбор способа доставки, подсчитать затраты на доставку по разным адресам и соответствующим образом вычислить стоимость доставки.

Далее отображается форма для ввода клиентом данных о кредитной карточке с помощью функции display_card_form() из библиотеки output_fns.php.

Функция display_card_form() из библиотеки output_fns.php

<?php
function display_card_form($name)
{
// Выводит форму, запрашивающую сведения о кредитной карточке
?>
<div class="table_cart">
<table>
<form action = 'process.php' method = 'post'>
<tr><th colspan = 2 bgcolor="#cccccc">Сведения о кредитной карточке</th></tr>
<tr>
<td>Вид</td>
<td><select name = 'card_type'><option>VISA<option>MasterCard<option>American Express</select></td>
</tr>
<tr>
<td>Номер</td>
<td><input type = 'text' name = 'card_number' value = "" maxlength = 16 size = 40></td>
</tr>
<tr>
<td>AMEX-код (если необходим)</td>
<td><input type = 'text' name = 'amex_code' value = "" maxlength = 4 size = 4></td>
</tr>
<tr>
<td>Дата истечения</td>
<td>Месяц <select name = 'card_month'><option>01<option>02<option>03<option>04<option>05<option>06<option>07<option>08<option>09<option>10<option>11<option>12</select>
Год <select name = 'card_year'><option>12<option>13<option>14<option>15<option>16<option>17<option>18<option>19<option>20<option>21<option>22</select></td>
</tr>
<tr>
<td>Держатель карточки</td>
<td><input type = 'text' name = 'card_name' value = "<?php echo $name; ?>" maxlength = 40 size = 40></td>
</tr>
<tr>
<td colspan = 2 align = 'center'>
<b>Пожалуйста, щелкните на кнопке "Купить" для того, чтобы подтвердить покупку,
либо на кнопке "Продолжить покупки" для продолжения покупок.</b>
<?php display_form_button('purchase', 'Приобрести выбранное'); ?>
</td>
</tr>
</table>
</div>
<?php
}
?>