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

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

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

Именование полей количества

Раздел страницы заключен в теги <FORM>, так как заказчику дается возможность изменить заказанное количество товара и заново послать форму, чтобы обновить это количество. Для этого необходимо поместить $OrderQuantity для каждого покупаемого объекта в поле формы, как это делается с помощью кода:

<input type="text" name="Q<?php echo $OrderItem ?>" size="2" class="qtybox"
    value="<?php echo $OrderQuantity ?>">

Ключом к тому, чтобы эта форма правильно работала, является соглашение об именах, используемых для этого поля. Обратим внимание, что этому текстовому полю присваивается имя "Q<?php echo $OrderItem ?>", то есть буква "Q" (которая выбрана просто произвольно), — за ней следует код ( $OrderItem ) продукта, значение $OrderQuantity которого выводится в этом поле. Если взять в качестве примера корзину покупателя, показанную выше, то именем поля количества первого товара будет "QBU1111", а именем поля для второго товара будет "QOS1111".

Для использования такого способа именования имеются две причины. Прежде всего, мы не знаем, сколько различных полей количества появится в форме. В ней будет столько полей, сколько будет купленных продуктов. Поэтому в отличие от предыдущего опыта с формами, мы не можем заранее определить и назвать эти поля. Во-вторых, мы не можем использовать одно имя для всех полей. Если, например, мы бы назвали поле просто "Quantity", то было бы столько полей Quantity, сколько было бы купленных продуктов. Это могло бы создать реальные, непреодолимые проблемы при попытке определить, какое поле quantity связано с каким продуктом. Поэтому требуется соглашение об именах, которое, первое, позволяет определить по мере необходимости неопределенное число полей количества, и, второе, уникальным образом определяет продукт, связанный с количеством, представленным в этом поле. Текущее соглашение об именах решает обе проблемы достаточно хорошо. Символ "Q" используется для идентификации поля количества (важный идентификатор, который будет использоваться ниже), а добавленное OrderItem предоставляет уникальное имя, которое идентифицирует также продукт, связанный с указанным в поле количеством. Мы обсудим ниже, как сценарий сортирует эту информацию для обновления полей количества измененными значениями.

Суммарные строки заказа и кнопки

После того как сценарий закончил итерации по объектам корзины покупателя и перечислил все покупки, вычисляется стоимость доставки ( $OrderShipping ) как 2% от OrderTotal и выводится пара суммарных строк.

$OrderShipping = number_format($OrderTotal * .02,2);
$OrderTotal = number_format($OrderTotal + $OrderShipping,2); 
<tr>
    <td colspan="4" style="text-align:right">Shipping </td>
    <td style="text-align:right"><?php echo $OrderShipping ?></td>
</tr>
<tr>
    <th colspan="4" style="text-align:right">Order Total </th>
    <td style="border-style:solid"><b><?php echo $OrderTotal ?></b></td>
</tr>

Наконец, выводятся две кнопки: кнопка "Update" для отправки всех сделанных изменений количества продуктов, и кнопка "Checkout" для оформления заказа. Последняя кнопка обсуждается дальше вместе с оформлением покупки с помощью кредитной карты.

Заказчики могут посещать страницу shopcart.php в любое время, даже до того, как будут сделаны какие-либо покупки. Однако, когда это происходит, вывод кнопок или доступ к ним для посетителя не обязателен. Они нужны только тем заказчикам, которые выбрали продукты для покупки. Поэтому их вывод происходит только для тех заказчиков, которые имеют объекты в своей корзине покупателя, т.е. когда значение OrderTotal не равно $0.00. Это условие используется для определения, будут или нет выводиться кнопки.

<?php if($OrderTotal != 0) {?>
  <div style="width:375px; line-height:8pt">
  <input type="submit" name="UpdateButton" class="buttonM" 
    style="float:left; margin-right:5px" value="Update"
    onMouseOver="OverMouse(this)"; onMouseOut="OutMouse(this)">
  <span class="small">Щелкните, чтобы обновить измененные значения количества. Введите новое значение количества или введите 0, чтобы отменить покупку товара.</span>
  </div>
<?php } ?>

</form>

<?php if ($OrderTotal != 0) {?>
  <div style="width:375px; line-height:8pt">
  <form action="http://.../creditcheck.php" method="post">
    <input type="hidden" name="ReturnURL" value="http://.../ordercapture.php">
    <input type="hidden" name="CompanyID" value="WebWarehouse.com">
    <input type="hidden" name="CustomerID" value="<?php echo $_SESSION[OrderNo]?>">
    <input type="hidden" name="Amount" value="<?php echo $OrderTotal ?>">
    <input type="submit" name="CheckoutButton" class="buttonM" 
      style="float:left;margin-right:5px" value="Checkout"
      onMouseOver="OverMouse(this)"; onMouseOut="OutMouse(this)">
    <span class="small">Щелкните, чтобы оформить онлайн покупку с помощью защищенного соединения с кредитной платежной системой.</span>
  </form>
  </div>
<?php } ?>
Пример I.13.

Итерации по отправленной форме

Когда пользователь изменяет значение количества одного или нескольких продуктов и щелкает на кнопке "Update" для отправки формы, то информация снова передается на страницу shopcart.php. Страница shopcart.php содержит сценарий для обновления этих изменений в таблице ShopCart. Этот сценарий находится в начале страницы для перехвата изменений, когда посылается форма.

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

До сих пор мы всегда знали имена и номера полей на формах. Это связано с тем, что мы проектировали формы, именовали поля и определяли, сколько будет полей. Но здесь это не так. Мы не знаем, сколько имеется полей (это зависит от того, сколько объектов имеется в корзине покупателя), и мы не знаем их имен (за исключением того, что они начинаются с буквы "Q" ). Поэтому мы не можем выполнить обработку формы, как это делалось ранее.

Однако с помощью PHP можно решить эту проблему. Можно выполнить итерации по всем элементам $_REQUEST, чтобы определить имена отправленных полей и соответствующие значения. Это реализуется с помощью специального оператора цикла For Each...Next, общая структура которого применительно к формам имеет следующий вид:

foreach($_REQUEST as $key => $value)

где $_REQUEST является ассоциативным массивом, содержащим все пары имя/значение для элементов управления формы на странице. Этот цикл выполняется для каждой пары имя/значение, присланной из формы. На каждой итерации переменная $key содержит имя из пары имя/значение, а $value указывает на значение, связанное с этим именем. Массив имеет следующий формат $_REQUEST[$key] = $value для каждой пары имя/значение, связанной с формой.

Затем можно использовать эту итерационную структуру для просмотра присланных позиций для обновления корзины покупателя и определения имен полей и значений. Когда встречается поле с именем, начинающимся с буквы "Q", то мы знаем, что это поле количества, содержащее значение для обновления таблицы ShopCart. Мы можем также определить из названия продукт, для которого задано значение количества.

Обновление корзины покупателя

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

if ($_POST[UpdateButton]  == "Update")
 
 {

$conn2 = odbc_connect('Driver={Microsoft Access Driver (*.mdb)};DBQ=c:\inetpub\wwwroot\PHPTutorial\Ecommerce\databases\ecommerce.mdb','','');
  
foreach($_REQUEST as $key => $value)
 	
	{
	
	 if (strpos($key,"Q") === 0 )
	 
	 {
	 
		$OrderItem = substr($key,1);
		$OrderQuantity = $value;
		
		if (is_numeric($OrderQuantity))
		
		{
		
			if ($OrderQuantity == 0)
			
			{
			
			$sqlCartUpdate = "DELETE FROM ShopCart WHERE OrderNo='$_SESSION[OrderNo]' AND OrderItem='$OrderItem'";
			
			}
        
        else
        
			{
			
          $sqlCartUpdate = "UPDATE ShopCart SET OrderQuantity='$OrderQuantity' WHERE OrderNo='$_SESSION[OrderNo]' 
          AND OrderItem='$OrderItem'";
			
			}
		$rsCartUpdate = odbc_exec($conn2,$sqlCartUpdate);
		
		}
	}
	
	} 
		odbc_close($conn2);
	}
Пример I.14.

Прежде всего, создается соединение с базой данных eCommerce.mdb. Объект множества записей ( Recordset ) здесь не требуется, так как обновления делаются непосредственно командами SQL, выполняемыми с помощью объекта соединения ( Connection ).

Затем применяется цикл foreach для итераций по именам и значениям, помещенным в массив $_REQUEST[] после отправки формы на сервер. Переменная с именем $key используется для ссылки на имена полей, находящиеся в массиве.

При просмотре элементов массива выполняется проверка того, что имя поля начинается с буквы "Q":

if (strpos($key,"Q") === 0 ) {
}

Функция PHPstrpos() применяется для проверки, что первый символ (или символ в позиции 0) имени элемента управления формы совпадает с "Q". Если первый символ "Q", то это будет поле количества, содержащее значение для обновления корзины покупателя. Здесь важно отметить, что используется оператор сравнения PHP "===" ("идентично"), а не оператор сравнения "==" ("равно"). Это необходимо, потому что функция strpos() требует для проверки своих возвращаемых значений "===".

Затем сценарий определяет, какую надо обновить запись о продукте и каким является фактическое значение количества:

$OrderItem = substr($key,1);
$OrderQuantity = $value;

Мы знаем, что код продукта, связанный с полем количества, содержится в переменной $key. Фактически это будут шесть правых символов имени поля. Поэтому эти шесть символов извлекаются из переменной с помощью функции PHP substr() и помещаются в переменную $OrderItem. Затем значение переменной $value, связанное с этим полем, присваивается переменной $OrderQuantity. Теперь у нас есть два фрагмента информации, необходимых для обновления поля $ItemQuantity этого продукта в таблице ShopCart.

Прежде чем обновлять количество продукта, необходимо проверить, что заказчик ввел число. В поле можно случайно ввести недействительный символ. Поэтому для $OrderQuantity выполняется числовая проверка.

if (is_numeric($OrderQuantity))
{
}

Если в поле находится что-то отличное от числа, то обновление количества для этого продукта пропускается и происходит обращение к следующему полю формы.

Количества, присланные с помощью формы, могут представлять дополнительные купленные количества, или они могут иметь значение 0, указывающее, что товар удален из корзины покупателя. Это значение проверяется, и выполняется один из двух операторов SQL.

if ($OrderQuantity == 0)
{
$sqlCartUpdate = "DELETE FROM ShopCart WHERE OrderNo='
$_SESSION[OrderNo]' AND OrderItem='$OrderItem'";
}

else
{
$sqlCartUpdate = "UPDATE ShopCart SET OrderQuantity='$OrderQuantity' 
WHERE OrderNo='$_SESSION[OrderNo]' AND OrderItem='$OrderItem'";
}

$rsCartUpdate = odbc_exec($sqlCartUpdate,$conn2);

В случае удаления или обновления, действие применяется к записи ShopCart с полем OrderNo соответствующим текущему $_SESSION[OrderNo], и с полем $OrderItem соответствующим $OrderItem из отправленной формы. Оператор DELETE удаляет из таблицы всю запись; оператор UPDATE изменяет поле $OrderQuantity в таблице на значение $OrderQuantity из отправленной формы.

Сценарий выполняет итерации по всем позициям, отправленным через форму, проверяя имя поля на наличие символа "Q". Если символ найден, то из имени извлекается код продукта и присваивается вместе со значением количества переменным, которые используются при обновлении таблицы ShopCart. После завершения обработки массива $_REQUEST[] соединение с базой данных закрывается и сценарий заканчивается.

Итерации по массиву $_REQUEST[]

Может быть полезно использовать пример с отправленными значениями для визуализации массива Request.Form. Предположим, что корзина покупателя содержит объекты, показанные на иллюстрации выше, тогда при нажатии кнопки "Update" будет создан следующий массив Request.Form.

Массив $_REQUEST[]
Имя Значение
QOS1111 2
UpdateButton Update
QBU1111 1

Здесь необходимо отметить один принципиальный момент, а именно, что элементы массива не обязательно находятся в том же порядке, в котором они появляются в форме; кроме того, нажатая кнопка также является частью массива. Рассмотрим теперь итерации по элементам с помощью цикла foreach, в котором переменная $key указывает имя, а $value указывает значение:

foreach($_REQUEST as $key => $value) {

  $key = "QOS1111"
  $value = "2"
  $key = "UpdateButton"
  $value = "Update"
  $key = "QBU1111"
  $value = "1"
}

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

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