Основы PHP
  Что такое PHP?
  Возможности PHP
  Преимущества PHP
  История развития
  Что нового в PHP5?
  «Движок» PHP
  Переход на PHP 5.3
New Переход на PHP 5.6
  Введение в PHP
  Изучение PHP
  Основы CGI
  Синтаксис PHP
  Типы данных PHP
  Переменные в PHP
  Константы PHP
  Выражения PHP
  Операторы PHP
  Конструкции PHP
  Ссылки в PHP
  PHP и ООП
  Безопасность
  Функции PHP
  Функции по категориям
  Функции по алфавиту
  Стандартные функции
  Пользовательские
  PHP и HTTP
  Работа с формами
  PHP и Upload
  PHP и Cookies
  PHP и базы данных
  PHP и MySQL
  Документация MySQL
  Учебники
  Учебники по PHP
  Учебники по MySQL
  Другие учебники
  Уроки PHP
  Введение
  Самые основы
  Управление
  Функции
  Документация
  Математика
  Файлы
  Основы SQL
  Дата и время
  CURL
  Изображения
  Стили
  Безопасность
  Установка
  Проектирование БД
  Регулярные выражения
  Подготовка к работе
  Быстрый старт
  Установка PHP
  Установка MySQL
  Конфигурация PHP
  Download / Скачать
  Скачать Apache
  Скачать PHP
  Скачать PECL
  Скачать PEAR
  Скачать MySQL
  Редакторы PHP
  Полезные утилиты
  Документация
  PHP скрипты
  Скачать скрипты
  Инструменты
  PHP в примерах
  Новости портала
 Главная   »  Сборник статей
 
 

Виртуальный магазин? Всего 3 часа работы и 5 Kb кода

Автор: Дмитрий Бородин

Что это?

Это так называемый виртуальный магазин, т.е. прайс лист некой организации с наименовнием товаров, часть из которых можно ПОМЕТИТЬ и занести в корзину, чтобы в дальнейшем можно было заполнить анкету (ФИО, адрес и т.д.) для покупки этих товаров. Все проще простого. Дизана нет никакого, только "скелет".

Требования: где ЭТО будет работать?

На win/unix в PHP версии не ниже 4.0 с поддержкой сессий. Включенных cookies от поcетителей не требуется. Надо лишь правильно настроить некоторые опции PHP, чтобы программа получила доступ к сессиям (будет написано ниже).

А почему размер файла 10Кб, а не 5Кб?

Если выкинуть все комментарии, вот и будет 5 кб :-) Программа (без комментариев) была написана за 3 часа в присутствии человека, изучающего ПХП. Комментарии, на самом деле были, но только устные :-)

Подготовка сервера

1. Возможный глюк: у вас не настроен временный каталог на сервере для размещения временных файлов.

2. Программа подразумевает, что PHP поместит в переменную $SID номер сесии. По умолчанию, возможно, этого не произойдет.

Для решения проблемы 1) и 2) пунктов надо изменить опции PHP. Это можно сделать в php.ini или файлах httpd.conf/.htaccess.

Вариант 1 - php.ini

    Если править php.ini, то в нем уже есть те переменные, что надо изменить
    • ищем строку session.save_path и пишем путь к своему временному каталогу. В этот каталог Apache/PHP будут писать свои файлы, след. для них там должен быть доступ. Если у вас Unix, то пишем /tmp, если Windows, то \temp (не забудьте создать C:\TEMP или X:\TEMP, смотря где находится Апач)
    • ищем строку session.name и заменяем на SID (большими буквами)

Вариант 2 - .htaccess или httpd.conf

    Если вносить те же измения в указанные файлы, то надо написать так:

    • вариант для unix: php_value session.save_path /tmp и для windows: php_value session.save_path \temp
    • и имя сессии: php_value session.name SID

Итак, нам надо для 1) и 2) пунктов подправить переменные PHP-процессора: session.save_path (временный каталог) и session.name (присвоить знаначение "SID").

Настройка каталога

  • создать файл shop.txt по такому образцу (здесь файл *.zip). Если вы захотите добавить новые колонки, то не забудьте, что первой кононкой должны идти ID товаров (например числа от 1 до ..), а последней - цена товара. Разделитель товаров - слеш (\).

  • создать файл shop.phtml (имя не принципиально), код программы приведен ниже.

Текст программы

<?php

// символы "<?" должны быть первыми(!) в файле. Т.е. ни пустых строк, ни
// пробелов до символов "<?" ставить нельзя, иначе не будет работать
// header - появятся warning'и

unset($t);
session_start();


/*
   функция прибавляет в корзину новый товар, где $n - это номер строки
   в shop.txt. Далее, в сессиях сохраняется не номер строки, а число ID
   из shop.txt и используется повсеместно. Если товар уже существует,
   то корзина никак не меняется.
*/
function tadd($n) {
   global $t;

   // открыли файл
   $f=file("./shop.txt") or die("файл не найден");
   // и получили нужную строку с товаром (в массив $o)
   $o=explode("\\",$f[$n]);

   $id=$o[0];
   if (isset($t[all][$id])) return; // если товар уже в корзине - выход

   $t[all][$id]=$id;    // флаг, благодаря которому, двумя строчками выше
                        // мы определили, что товар уже есть в корзине
   $t[$id][name]=$o[1]; // наименование
   $t[$id][info]=$o[2]; // инфо
   $t[$id][cena]=$o[3]; // и д.р. не значащие данные
   $t[$id][kol]=1;      // кол-во в начале равно "1 штуке"

   session_register("t"); // записали переменную в сессию
}


/*
   Рисует таблицу с товарами в корзине. Из файла shop.txt мы читаем только
   названия колонок и не более. Названия товара (в данном случае только
   название/цена/кол-во) берется из сессии.
*/
function korzina() {
   global $t,$PHP_SELF,$SID;

   $f=file("./shop.txt") or die("файл не найден");
   $ogl=explode("\\",$f[0]);

   echo "<form action=$PHP_SELF method=POST>".
        "<input type=hidden name=SID value='$SID'>". // передаем сесиию
        "<input type=hidden name=c value=kolvo>".
   // рисуем заголовок таблицы с корзиной:
        "<table border=2><tR><td>$ogl[1]</td></td><td>$ogl[3]</td>".
        "<td>кол-во</td><td>команды</td></tr>";

   // проходим массив $t[all] по списку его ключей
   $k=@array_keys($t[all]);
   for ($i=0; $i<count($k); $i++) {
      $id=$k[$i];
      echo "<tr><td>{$t[$id][name]}</td>".
           "<td>{$t[$id][cena]}</td>".
           "<td><input size=4 type=text name=v[$id] value={$t[$id][kol]}></td>".
           "<td><a href=$PHP_SELF?c=del&id=$id&SID=$SID>удалить</a></td></tr>";
   }

   // внизу таблицы две кнопки:
   //   Измениения - сохранить изменение числа товаров и обновить страницу
   //   Заказ - сорх. изм. + перейти на страницу оформления заказа
   echo "</table><input type=submit name=edit value='Внести изменения'> &nbsp; &nbsp;".
        "<input type=submit name=zakaz value='Оформить заказ'></form>";
}


/*
   Выводит на экран таблицу с товарами. В таблице автоматом генериться новая
   колонка с checkbox'асами, отметив которые и нажав "добавив", можно
   занести товары в корзину.
*/
function price() {
   global $t, $PHP_SELF,$SID;

   $f=file("./shop.txt") or die("файл не найден"); // читаем файл
   $ogl=explode("\\",$f[0]); // из него берем огравление
   $x=count($ogl); // вычисляем число колонок
   $y=count($f);   //         и число строк
   // форма (не забываем вписать $SID) + начало таблицы:
   echo "<form action=$PHP_SELF method=POST><input type=hidden name=c value=add>".
        "<input type=hidden name=SID value='$SID'><table border=2>";

   // рисуем заголовок таблицы, названия колонок - первая строка файла shop.txt
   echo "<tr>";
   for ($j=0; $j<$x; $j++) {
      if (strlen($ogl[$j])==0) echo "<tD>&nbsp;</td>";
      else echo "<td>$ogl[$j]</td>";
   }
   // рисуем последнюю колонку, где будут checkbox'ы
   echo "<td>x</td></tr>";

   // основной цикл вывода прайса
   for ($i=1; $i<$y; $i++) {

      $a=explode("\\",$f[$i]); // читаем очередную строку файла
      if (count($a)<2) continue; // если она пустая (глюки), пропускаем
      echo "<tr>";
      // цикл вывода всех колонок текущей строки таблицы

      for ($j=0; $j<$x; $j++) {
         // если ячейка пустая, там надо поместить "&nbsp;";
         if (strlen($a[$j])==0) echo "<tD>&nbsp;</td>";
         else echo "<td>$a[$j]</td>";
      }

      // рисуем тот самый checkbox в последней колонке текущей строки
      echo "<td><input type=checkbox name=v[$i] value=$i></td></tr>";
   }

   echo "</table><br><center><input type=submit value='Добавить ".
        "отмеченные товары в корзину'></center></form>";
}


/*
   Выводит на экран несколько чисел (написано). Подсчет значений происходит
   при каджом вызове.
*/
function summa() {
   global $t;
   // традиционный проход массива товаров из корзины
   $k=@array_keys($t[all]);
   for ($i=0; $i<count($k); $i++) {
      $id=$k[$i];
      // если убрать (double), то копейки округляться
      $summ+=(double)$t[$id][kol]*(double)$t[$id][cena];
      $summ2+=$t[$id][kol];
   }
   // просто выводим посчитанные цифры на экран
   echo "Корзина: наименований товаров - $i (в кол-ве $summ2 шт),
   цена -  ".sprintf("%.2f руб.<br>",$summ);
}

/*
   Объявление переменной post, которая содержит поля для заполнения
   посетителем при оформление заказа. Т.к. этот список используется
   2 раза, то описано это именно тут, а не ниже.
*/
   $post=array(
"название организации",
"Ф.И.О. должностного лица",
"должность",
"ИНН организации",
"местонахождение организации",
"контактный телефон",
"e-mail");




/*****************************************************************************/
// основной код программы

// $c - основная переменная, указывающая на нужное действие
if (!isset($c)) $c='';

switch($c) {

case "":
// без параметров - рисуем прайс-лист

   summa(); // статистика по корзине
   price(); // прайс
   // ссылка для перехода на корзину
   echo "<li><a href='$PHP_SELF?c=korzina&SID=$SID'>Корзина покупок</a>";
   break;


case "korzina":
// вывод корзины

   summa(); // см. выше
   korzina(); // рисуем таблицу корзины
   // пишем 2 ссылки
   echo "<li><a href='$PHP_SELF?SID=$SID'>Каталог товаров</a>";
   echo "<li><a href='$PHP_SELF?c=delete&SID=$SID'>Очистить корзину (осторожно!)</a>";

   break;


case "add":
// добавление из формы прайса всех товаров

   // в массиве $v скоплены номера строк товаров, которые функция ...
   $k=@array_keys($v);
   for ($i=0; $i<count($k); $i++) {
      // ... tadd() преобразует из файла в данные и поместит в сессии
      tadd($v[$k[$i]]);
   }
   // надо перенаправить браузер на приличный адрес, чтобы:
   // 1) в URL был написан приличный адрес
   // 2) чтобы не было глюка, если посетитель нажмет ОБНОВИТЬ СТРАНИЦУ
   exit(header("Location: $PHP_SELF?c=korzina&SID=$SID"));
   // Ну, а то, что header засунуто в exit... Это просто фича такая :-)
   break;


case "kolvo":
// измение кол-ва товаров, когда а странице КОРЗИНА нажимают СОХРАНИТЬ
// ИЗМЕНЕНИЯ или ОФОРМИТЬ ЗАКАЗ..
// Оцените, насколько короткий код преобразования корзины

   $k=@array_keys($v);
   for ($i=0; $i<count($k); $i++) {
      $t[$k[$i]][kol]=abs(intval($v[$k[$i]]));
   }
   // после изменения переенной сессии ее нужно записать
   session_register("t");

   // Далее важная проверка. Если посетитель нажимает кнопку СОХРАНИТЬ, то
   // у нас устанавливается переменная $edit, которая содержит строку
   // "Сохранить изменения". Если он нажимает ЗАКАЗ, то устанавливается
   // $post. Устанавливается только одна из этих твух переменных.

   // если это было ИЗМЕНИТЬ, то переправить на корзину
   if (isset($edit)) exit(header("Location: $PHP_SELF?c=korzina&SID=$SID"));
   // иначе переправить на страницу с офрмлением заказа
   exit(header("Location: $PHP_SELF?c=zakaz&SID=$SID"));
   break;

case "del":
// удаление товара по его $id

   $id=intval($id);
   unset($t[$id]);
   unset($t[all][$id]);
   session_register("t");
   exit(header("Location: $PHP_SELF?c=korzina&SID=$SID"));
   break;


case "delete":
// удаление всей корзины.. Как и в пред. пункте, только с проходом
// массива id товаров

   $k=@array_keys($t[all]);
   for ($i=0; $i<count($k); $i++) {
      unset($t[$k[$i]]);
      unset($t[all][$k[$i]]);
   }
   session_register("t");
   exit(header("Location: $PHP_SELF?c=korzina&SID=$SID"));


case "zakaz":
// форма для оформления заказа

   echo "<form action=$PHP_SELF method=post><input type=hidden name=c value=post>".
        "<input type=hidden name=SID value='$SID'>".
        "<table border=1>";
   for ($i=0; $i<count($post); $i++) {
      echo "<tr><td>$post[$i]</td><td><input type=text size=40 name='v[$i]'></td></tr>";
   }
   echo "</table><input type=submit value='Отправить заказ'></form>";
   break;


case "post":
// генерим и отправляем анкету посетителя, где указаны данные посетителя
// и список товаров из корзины

   $msg="Анкета посетителя:\n\n";
   for ($i=0; $i<count($post); $i++) {
      $msg.="$post[$i]: ".substr($v[$i],0,500)."\n";
   }
   $msg.="\nСписок покупок:\n\n";
   $k=@array_keys($t[all]);
   for ($i=0; $i<count($k); $i++) {
      $id=$k[$i];
      $msg.=($i+1).") {$t[$id][name]} \\ ".doubleval($t[$id][cena]).
         " руб \\ {$t[$id][kol]} шт. \\ = ".
           sprintf("%.2f",$t[$id][cena]*$t[$id][kol])." руб\n";
   }


   ?>
<table width=100% height=95%><tr><td align=center>
<h2>Ваш заказ отправлен!<br>
Спасибо за покупку!</h2>
<hr width=60%><br>
<a href='/?<?=SID?>'>страница сервера</a><br><br>
<a href='<? echo $PHP_SELF; ?>?<?=SID?>'>прайс-лист</a>
</tD></tr></table>
В переменной $msg хранится анкета посетителя,
с которой можно сделать все, что угодно (послать мылом,
записать в лог-файл, вывести на экран):
<pre><? echo $msg; ?></pre>

  <?
}


?>

 
 » Обсудить эту статью на форуме

 
 Сборник статей 
 Содержание раздела 
Есть еще вопросы или что-то непонятно - добро пожаловать на наш  форум портала PHP.SU 
 

 
Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS