Tuesday, June 10, 2014

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

http://php.spb.ru/php/shop.html

Виртуальный магазин? Всего 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 ПО ТАКОМУ ОБРАЗЦУ. Если вы захотите добавить новые колонки, то не забудьте, что первой кононкой должны идти ID товаров (например числа от 1 до ..), а последней - цена товара. Разделитель товаров - слеш (\). 

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


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

      <?    // символы "<?" должны быть первыми(!) в файле. Т.е. ни пустых строк, ни  // пробелов до символов "<?" ставить нельзя, иначе не будет работать  // 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>      <?  }      ?>
  • No comments:

    Post a Comment