Wednesday, October 10, 2012

Виртуальный PHP магазин? Всего 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>    <? }   ?> 



    SpyLOG TopList
  • No comments:

    Post a Comment