Опубликован: 08.05.2007 | Доступ: свободный | Студентов: 12881 / 3013 | Оценка: 4.13 / 3.77 | Длительность: 12:58:00
Дополнительный материал 1:

Приложение PHP E-Commerce

< Лекция 12 || Дополнительный материал 1: 123456789101112 || Дополнительный материал 2 >

Создание заказа на продажу

Мы приходим теперь на первую страницу, которую видит заказчик, когда покидает компанию кредитных карт. Эта страница salesorder.php представляет сводку подтвержденного заказа (или сообщение "простите" при отвергнутом заказе), которую заказчик может распечатать для справки. Также, поскольку заказ был завершен, выводится новый номер заказа, на тот случай, если заказчик захочет продолжить покупки.


Основной раздел этой страницы начинается с заголовка страницы и получения строки запроса Approval, переданной со страницы ordercapture.php. Если подтверждение заказа будет "true", то начинается процесс вывода информации о заказе.

<div style="position:absolute; top:75px; left:200px; width:550px">

<span class="head1">Sales Order</span><br>
<span class="head4">Date: </span><?php echo date('n/d/y') ?><br>
<span class="head4">Order No: </span><?php echo $_SESSION[OrderNo] ?><br>
<br>
<?php
$Approval = $_GET[Approval]

if ($Approval) 
{ 

   $conn = odbc_connect('Driver={Microsoft Access Driver (*.mdb)};DBQ=c:\inetpub\wwwroot\PHPTutorial\Ecommerce\databases\ecommerce.mdb','','');

  $sql = "SELECT * FROM OrderHeader WHERE OrderNo='$_SESSION[OrderNo]'";
  $rsHeader = odbc_exec($conn,$sql);

    if (odbc_result($rsHeader,OrderNo) == "")
      {
      odbc_close($conn);
      ob_flush();
      header("Location:home.php")
    }

  $slqOrders = "SELECT * FROM OrderDetail WHERE OrderNo='$_SESSION[OrderNo]'";
  $rsOrder = odbc_exec($conn,$sqlOrders);

  ?>
Пример I.17.

Создается объект соединения для связи с базой данных eCommerce.mdb и используется оператор SQL для извлечения информации из таблиц OrderHeader и OrderDetail. Эти множества записей имеют общий номер заказа, который находится в глобальной переменной $_SESSION[OrderNo]. Тогда будет доступна вся информация для восстановления заказа, начиная с информации о выставленном счете к оплате, извлеченной из таблицы OrderHeader.

Стоит обратить внимание на небольшой раздел кода, следующий за открытием таблицы OrderHeader.

if (odbc_result($rsHeader,OrderNo) == "")
      {
      odbc_close($conn);
      ob_flush();
      header("Location:home.php")
    }

Этот сценарий проверяет условие EOF на множестве записей, которое означает, что для OrderNo не было найдено подходящего значения. Как это может случиться, и зачем проверять? Это может случиться, если заказчик использует кнопку браузера "Back" ("назад") для возврата на предыдущую страницу (страница подтверждения компании кредитных карт), а затем снова нажимает кнопку "вперед" ( "forward" ).

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

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

<?php echo odbc_result($rsHeader,CustomerName) ?><br>
  <?php echo odbc_result($rsHeader,CustomerAddress) ?><br>
  <?php echo odbc_result($rsHeader,CustomerCity) ?>, 
  <?php echo odbc_result($rsHeader,CustomerState) ?> 
  <?php echo odbc_result($rsHeader,CustomerZip) ?><br>
  <br>
  <table border="0" cellpadding="3">
  <tr>
    <th>Item Number</th>
    <th>Title</th>
    <th>Quantity</th>
    <th>Price</th>
    <th>Amount</th>
  </tr>
  <?php
  $OrderTotal = 0
  while ($row = odbc_fetch_array($rsDetail) { 
    $ItemNumber = $row[ItemNumber]
    $ItemTitle = $row[ItemTitle]
    $ItemPrice = $row[ItemPrice]
    $ItemQuantity = $row[ItemQuantity]
    $ItemAmount = $ItemPrice * $ItemQuantity
    $OrderTotal = $OrderTotal + $ItemAmount
    
echo "<tr>
      <td>$ItemNumber</td>
      <td><$ItemTitle</td>
      <td style=\"text-align:right\">$ItemQuantity</td>
      <td style=\"text-align:right\">$number_format($ItemPrice,2)</td>
      <td style=\"text-align:right\">$number_format($ItemAmount,2)</td>
    </tr>";
    
  }
  odbc_close($conn);
  $OrderShipping = number_format($OrderTotal * .02,2);
  $OrderTotal = number_format($OrderTotal + $OrderShipping,2);
     
echo "<tr>
    <td colspan=\"4\" style=\"text-align:right\">Shipping </td>
    <td style=\"text-align:right\">$OrderShipping</td>
  </tr>
  <tr>
    <th colspan=\"4\" style=\"text-align:right\">Order Total </th>
    <td style=\"border-style:solid\"><b>$OrderTotal</b></td>
  </tr>";
?>
  </table>
  <br>
  Спасибо за ваш заказ. Пожалуйста, распечатайте эту страницу и указывайте номер заказа при любых запросах. Ваш заказ будет доставлен немедленно.

<?php } 
else 
{

echo "Простите, но вы не можете завершить свой заказ. Когда вы решите проблему, 
 возвращайтесь, пожалуйста, на <span class=\"head4\">WebWarehouse.com</span> чтобы купить необходимое программное обеспечение."

}
?>
Пример I.17.

Форматирование этого заказа на продажу аналогично тому, которое использовалось при выводе корзины покупателя. Сценарий выполняет цикл по записям, извлеченным из таблицы OrderDetail, создавая строку для каждой записи. Как и раньше, вычисляется каждое значение $ItemAmount, накапливается общая сумма OrderTotal и вычисляется $OrderShipping на $OrderTotal.

(Здесь снова возникает тот случай, когда можно подумать о том, чтобы хранить плату за доставку в записи OrderHeader, а не вычислять ее во время создания заказа. Позже, когда этот заказ будет восстановлен, скорее всего, будет изменение в проценте оплаты и общая стоимость заказа будет отличаться от текущей. Здесь эта проблема рассматриваться не будет.)

Сброс номера заказа

Теперь важная часть этой обработки. Заказ клиента завершен. Поэтому необходимо присвоить новое значение OrderNo на тот случай, если заказчик захочет продолжить покупку. Если он сделает это без нового номера, то в результате получится дублирование номера заказа и возникнет путаница при попытке разделить заказы клиента. Конечный шаг обработки на этой странице состоит тогда в присваивании нового номера с помощью той же процедуры, которая использовалась, когда клиент впервые прибыл на сайт.

<?php
'-- Assign new OrderNo
$OrderNo = rand(1111111111,9999999999)
$_SESSION[OrderNo] =$OrderNo
?>

</div>

Все прошло полный круг. В этой точке бывший заказчик становится новым заказчиком и может начинать покупку с самого начала.

На этом завершается обсуждение базовых механизмов работы онлайнового сайта eCommerce. Можно, конечно, добавить еще множество свойств и функций. Мы рассмотрим еще одно – автоматическое создание подтверждения заказа по e-mail.

Отправка подтверждения по E-mail

Обычно компании посылают подтверждение по e-mail заказов, когда они приняты к выполнению. С помощью сценария множено создавать автоматические сообщения e-mail, и такая возможность будет добавлена в приложение eCommerce. Следующая иллюстрация показывает формат подтверждающего сообщения, которое получит заказчик.


Функция mail()

В PHP имеется функция mail(), предназначенная для создания сообщений email под управлением сценария.

mail() содержит параметры для создания и отправки email, по большей части также, как это происходит в обычной почтовой программе. Среди свойств и параметров нам понадобятся следующие:

Свойство Описание
to Строка, представляющая адрес e-mail получателя сообщения
subject Строка, представляющая строку тему сообщения
message Строка, представляющая основное тело сообщения
headers Строка, представляющая дополнительную информацию, которая включается в начале сообщения e-mail

В простейшем виде сценарий e-mail может выглядеть следующим образом:

<?php
$to      = 'youraddress@domain.com';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: webmaster@example.com' . "\r\n" .
    'Reply-To: webmaster@example.com' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);
				
?>

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

Размещение сценария

Лучшим местом для сценария подтверждения заказа по email является страница ordercapture.php. Эта страница получает информацию от компании кредитных карт и создает для заказчика записи OrderHeader и OrderDetail, а также содержит всю информацию, необходимую для составления сообщения e-mail. Размещение сценария показано на следующем эскизе страницы:

<div style="position:absolute; top:75px; left:200px; width:550px">
  ...

<?php
$Approval = $_POST[Approval];

if ($Approval)

{ 
  
  $sqlInsert = "INSERT INTO OrderHeader (OrderNo,OrderDate,CustomerName,CustomerAddress,
  CustomerCity,CustomerState,CustomerZip,CustomerPhone,CustomerEmail) Values ('$OrderNo','$Date','$Name','$Address','$City','$State','$Zip','$Phone','$Email')";
 
 $rsInsert = odbc_exec($conn,$sqlInsert);
 
//Создание записи OrderDetail 
 
$sqlDetail ="SELECT * FROM OrderDetail WHERE NULL";
$rsDetail = odbc_exec($conn,$sqlDetail);

$sqlShopCart ="SELECT * FROM ShopCart WHERE OrderNo ='$OrderNo'";
$rsShopCart = odbc_exec($conn,$sqlShopCart);

  while ($row = odbc_fetch_array($rsShopCart))
  
  { 
  
  $sqlProd ="SELECT ItemTitle,ItemPrice FROM Products WHERE ItemNumber ='$row[OrderItem]'";
  
  $rsProd = odbc_exec($conn,$sqlProd);
  $ProdTitle = odbc_result($rsProd,ItemTitle);
  $ProdPrice = odbc_result($rsProd,ItemPrice);
  
 $sqlInsertDetail = "INSERT INTO OrderDetail (OrderNo,ItemNumber,ItemQuantity,
 ItemTitle,ItemPrice) Values ('$row[OrderNo]','$row[OrderItem]',
 '$row[OrderQuantity]','$ProdTitle','$ProdPrice')";
	
	$rsInsertDetail = odbc_exec($conn,$sqlInsertDetail);
  
  }

//ВСТАВЬТЕ СЮДА СЦЕНАРИЙ E-MAIL 
----------------------------------------------------------

$to      = 'youraddress@domain.com';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: webmaster@example.com' . "\r\n" .
    'Reply-To: webmaster@example.com' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);
----------------------------------------------------------
				
 //Удаление корзины покупателя   

$sqlDelete = "DELETE FROM ShopCart WHERE OrderNo='$OrderNo'";
$rsDelete = odbc_exec($conn,$sqlDelete);

odbc_close($conn);

//echo $sqlInsertDetail;
header("Location:salesorder.php?Approval=$Approval");
}
?>
Пример I.18.

Программирование сообщения E-mail

Начнем теперь программирование сценария, который вставляется на страницу. Необходимо сделать так, чтобы поле e-mail было не обязательным на форме проверки кредитной карты. Некоторые заказчики могут не предоставлять адрес e-mail, и мы не сможем послать им подтверждающее сообщение. Поэтому весь сценарий находится внутри условного оператора.

if ($Email) {Then

    '—Послать подтверждение заказа по e-mail 
    $to = $Email
    $subject = "Order $OrderNo Confirmation"

Прежде всего, необходимо инициализировать параметры mail() — $to и $subject. Параметру $to присваивается один из элементов информации, посланной из компании кредитных карт и полученной в начале этой страницы. Переменная содержит адрес e-mail заказчика. Это должен быть реальный, действительный адрес e-mail.

Присваивание $subject использует текстовую строку, которая включает для идентификации значение переменной $OrderNo.

Теперь необходимо составить тело сообщения, форматируя его с помощью HTML для создания общей компоновки и внешнего вида. Вспомните из сказанного ранее, что тело должно быть одной строкой текста. Поэтому нельзя написать последовательность отдельных строк HTML и присвоить их параметру $message. Необходимо представить их в виде одной строки. Мы делаем это, задавая переменную $message, а затем помещаем в нее одну длинную строку, собирая ее из отдельных подстрок. Такой подход можно видеть в следующем фрагменте кода.

$message=""
    $message=$message & "<html>"
    $message=$message & "<$message>"
    $message=$message & "<h2>WebWarehouse.com</h2>"
    $message=$message & "Date: date('n/d/y') "<br>"
    $message=$message & "Order No.: $OrderNo "<br>"
    $message=$message & "<br>"
    $message=$message & Name & "<br>"
    $message=$message & Address & "<br>"
    $message=$message & City & ", " & State & " " & Zip & "<br>"
    $message=$message & "<p>"
    $message=$message & "Thank you for your order. We appreciate your shopping at "
    $message=$message & "WebWarehouse.com. If you have any questions about your order, "
    $message=$message & "please email us at "
    $message=$message & "<a href=mailto:orders@WebWarehouse.com>orders@softWarehouse.com</a> "
    $message=$message & "and reference the order number listed above."
    $message=$message & "</p>"
    $message=$message & "<table border=0 cellpadding=3>"
    $message=$message & "<tr>"
    $message=$message & " <th>Item Number</th>"
    $message=$message & " <th>Title</th>"
    $message=$message & " <th>Quantity</th>"
    $message=$message & " <th>Price</th>"
    $message=$message & " <th>Amount</th>"
    $message=$message & "</tr>"
Пример I.19.

Каждая подстрока текста соединяется с переменной $message, создавая постепенно в переменной одну текстовую строку. Эта строка содержит также теги XHTML для форматирования вложенного текста. Отметим, что переменные $Date, $OrderNo, $Name, $Address, $City, $State, и $Zip, полученные из информации кредитной компанией, встраиваются в увеличивающуюся строку. Конечная часть кода создает заголовки таблицы для информации заказа на продажу, которая форматируется далее.

Затем необходимо собрать информацию заказа на продажу из таблицы OrderDetail и сформатировать ее как строки таблицы.

$sqlMail = "SELECT * From OrderDetail WHERE OrderNo = '$OrderNo'";
 $rsMail = odbc_exec($conn,$sqlMail);
 
 while ($row = odbc_fetch_array($rsMail))
 
 {
 
      $ItemNumber =$row[ItemNumber];
        $ItemTitle =$row[ItemTitle];
        $ItemQuantity = $row[ItemQuantity];
        $ItemPrice = $row[ItemPrice];
       $ItemAmount = $ItemQuantity * $ItemPrice;
        $OrderTotal = $OrderTotal + $ItemAmount;
        $message = $message . "<tr>";
       $message = $message ." <td>" . $ItemNumber . "</td>";
       $message = $message . " <td>" . $ItemTitle . "</td>";
       $message = $message . " <td align=right>". $ItemQuantity . "</td>";
       $message = $message . " <td align=right>" . number_format($ItemPrice,2) . "</td>";
       $message = $message . " <td align=right>" . number_format($ItemAmount,2) . "</td>";
       $message = $message . "</td>"
 
 }

Это делается здесь в цикле while: значения полей помещаются в переменные, которые форматируются в ячейки таблицы и соединяются со строкой $message. По мере выполнения цикла накапливается значение переменной $OrderTotal.

$ShippingCharge = $OrderTotal * .02;
    $OrderTotal = $OrderTotal + $ShippingCharge;
     $message = $message . "<tr>";
     $message = $message . "<td colspan=4 align=right>Shipping</td>";
    $message = $message . " <td align=right>" . number_format($ShippingCharge,2) . "</td>";
    $message = $message . "</tr>";
     $message = $message . "<tr>";
     $message = $message . "<td colspan=4 align=right>Order Total</td>";
    $message = $message . "<td align=right>" . number_format($OrderTotal,2) . "</td>";
     $message = $message . "</tr>";
     $message = $message . "</table>";
    $message = $message . "</body>";
    $message = $message . "</html>";

$headers = 'From: sales@webwarehouse.com' . "\r\n" .
    'Reply-To: sales@webwarehouse.com' . "\r\n" .
    'Content-Type:text/html;charset=us-ascii' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);

После того как сценарий выполнил итерации на множестве записей, форматируя отдельные строки таблицы для купленных продуктов, вычисляется и форматируется $ShippingCharge, вместе с $OrderTotal, как две последние строки таблицы. Закрывающие теги HTML присоединяются в конце строки $message, и сообщение e-mail завершается.

После завершения формирования сообщения e-mail мы создаем переменную $headers для хранения заголовочных данных, которые нужны для описания сообщения. В данном случае мы добавляем заголовочные сообщения From (указывает адрес e-mail, откуда было прислано сообщение), Reply-To (адрес e-mail, который появится в поле TO получателя, если он будет отвечать на автоматическое сообщение), Content-Type (определяет формат сообщения) и X-Mailer (определяет версию PHP, используемую для генерации сообщения). Хотя заголовочные сообщения являются необязательными, рекомендуется всегда их включать.

Если сообщение e-mail содержит HTML, который должен интерпретироваться соответствующим образом, то необходимо использовать следующее значение заголовка.

'Content-Type:text/html;charset=us-ascii'

Последний шаг состоит в вызове встроенной функции mail().

Необходимо упомянуть попутно, что прежде чем можно будет послать сообщение e-mail через сценарий PHP, сервер Web должен иметь выполняющуюся службу SMTP (Простой протокол пересылки почты), и может понадобиться внести изменения в файл PHP.ini. Особенности настроек различных серверов можно найти на сайте PHP.

< Лекция 12 || Дополнительный материал 1: 123456789101112 || Дополнительный материал 2 >
Максим Матросов
Максим Матросов
Наталья Джабасова
Наталья Джабасова