Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Złożenie zamówienia oparte o transakcje
Forum PHP.pl > Forum > Przedszkole
anka_skakanka
Witam,
mój problem jest taki, że mam sklep WWW, w momencie składania zamówienia, sprawdza czy istnieje dostępna ilość na stanie, no i tu się pojawia problem, gdyż w momencie liczba_dostepnych<liczba_wybranych pojawia sie komunikat, ale zamiast cały proces zamowienia sie cofnąć to jest przyjmowany ale bez tej pozycji, która objawiła się błędem. a tak być nie powinno. W momencie błędu ilości powinno cofnąć cały proces i tj "nakazać kupującemu zmianę ilości"
  1. -- -- Struktura tabeli dla `koszyk_klienta`--
  2. CREATE TABLE IF NOT EXISTS `koszyk_klienta` (
  3. `id_koszyk` int(11) NOT NULL AUTO_INCREMENT,
  4. `id_user` int(11) NOT NULL,
  5. `id_sesji` varchar(32) CHARACTER SET latin2 NOT NULL,
  6. `id_wyb_rab` int(11) NOT NULL,
  7. `ilosc_wyb_rab` int(10) NOT NULL,
  8. `data_dodania` date NOT NULL,
  9. PRIMARY KEY (`id_koszyk`)
  10. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;
  11. ---- Struktura tabeli dla `szczegoly_zamowienia`--
  12. CREATE TABLE IF NOT EXISTS `szczegoly_zamowienia` (
  13. `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  14. `id_zam` int(10) UNSIGNED NOT NULL,
  15. `id_wyb_rab` int(10) NOT NULL,
  16. `ilosc_wyb_rab` int(10) NOT NULL,
  17. `cena_wyb_rab` float(6,2) NOT NULL,
  18. `suma_wyb_rab` float(6,2) NOT NULL,
  19. PRIMARY KEY (`id`),
  20. KEY `szczegoly_zamowienia_FKIndex1` (`id_zam`)
  21. ) ENGINE=InnoDB DEFAULT CHARSET=latin2 AUTO_INCREMENT=5 ;
  22. ---- Struktura tabeli dla `zamowienia`--
  23. CREATE TABLE IF NOT EXISTS `zamowienia` (
  24. `id_zam` int(11) NOT NULL AUTO_INCREMENT,
  25. `idklienta` int(11) NOT NULL,
  26. `rab_suma` float(6,2) NOT NULL,
  27. `stan` enum('oczekujace','zrealizowane') NOT NULL,
  28. `id_sesji` varchar(32) NOT NULL,
  29. `data_zam` datetime NOT NULL,
  30. `sposob_zaplaty` varchar(13) NOT NULL,
  31. `uwagi` longtext NOT NULL,
  32. PRIMARY KEY (`id_zam`)
  33. ) ENGINE=InnoDB DEFAULT CHARSET=latin2 AUTO_INCREMENT=4 ;

Więc tak ogólnie w bazie mam kategorie, uslugi, rabat (rabat laczy sie z usluga poprzez iduslugi), klienci, koszyk_klienta, zamowienia, szczegoly_zamowienia... i dwie tabele akurat w tym aspekcie mnie istotne.. Projekt bazy robiony w DBdesigner typ bazy innodb, z uzyciem kluczy obcych..
i teraz tak nie wiem czy do kazdej instrukcji napisanej w kodzie zamowienia.php musze zastosować te commit i rollback ? czy wystarczy jedna ale cofając każde insert update delete ?
  1. <?php
  2. if (isset($_SESSION['user_id']) and isset($_SESSION['login'])) {
  3. if (isset($_POST["sposob_zaplaty"])) { //zmienna przesylana z formularza do zamowienia
  4. $data = date("Y-m-d H:m:s");
  5. require('config.php');
  6. $zamow = "INSERT INTO zamowienia (idklienta,data_zam, sposob_zaplaty,stan,id_sesji,uwagi)
  7. VALUES ( '".$_SESSION['user_id']."', '".$data."', '".$_POST["sposob_zaplaty"]."', 'oczekujace', '".$_COOKIE["PHPSESSID"]."', '".$_POST["uwagi"]."')";
  8.  
  9. mysql_query("START TRANSACTION");
  10. $wynik_zamow = mysql_query($zamow, $lacze);
  11. if( (!$wynik_zamow)) {
  12. mysql_query("ROLLBACK");
  13. echo "<span class='blad'>zamówienie nie zostało zrealizowane. </span>";
  14. mysql_close($lacze);
  15. echo "<META HTTP-EQUIV=Refresh CONTENT=3;URL=index.php>";
  16. }
  17. else{
  18. $id_zapytanie="SELECT id_zam FROM zamowienia WHERE id_sesji = '".$_COOKIE["PHPSESSID"]."'
  19. AND idklienta = '".$_SESSION['user_id']."' AND data_zam= '".$data."'";
  20. $id_zam = mysql_query($id_zapytanie, $lacze) or die(mysql_error($mysql));
  21. $temp=mysql_fetch_array($id_zam);
  22. $id_zamow=$temp['id_zam'];
  23. $pobierz_koszyk_sql = "select id_koszyk, id_wyb_rab, nazwa_uslugi, cena_z_rabatem, ilosc_wyb_rab from koszyk_klienta
  24. Join rabat on rabat.idrabat=koszyk_klienta.id_wyb_rab
  25. Join uslugi on rabat.iduslugi=uslugi.iduslugi WHERE id_sesji = '".$_COOKIE["PHPSESSID"]."' OR id_user = '".$_SESSION['user_id']."' ";
  26. $pobierz_koszyk_rez = mysql_query($pobierz_koszyk_sql, $lacze) or die(mysql_error($mysql));
  27. while ($koszyk_info = mysql_fetch_array($pobierz_koszyk_rez)) {
  28. $idrab = $koszyk_info['id_wyb_rab'];
  29. $nazwa_uslugi = stripslashes($koszyk_info['nazwa_uslugi']);
  30. $cena_rab = $koszyk_info['cena_z_rabatem'];
  31. $ilosc_rab = $koszyk_info['ilosc_wyb_rab'];
  32. $suma = sprintf("%.02f", $cena_rab * $ilosc_rab);
  33. $wartosc_zam = $wartosc_zam + $suma;
  34. $id_kosz_usun = $koszyk_info['id_koszyk'];
  35. $rab_zam = "INSERT INTO szczegoly_zamowienia (id_zam,id_wyb_rab,ilosc_wyb_rab,cena_wyb_rab,suma_wyb_rab)
  36. VALUES( '".$id_zamow."',
  37. '".$idrab."',
  38. '".$ilosc_rab."','".$cena_rab."','".$suma."')";
  39.  
  40. $usun_koszyk = "DELETE FROM koszyk_klienta WHERE ((id_sesji = '".$_COOKIE["PHPSESSID"]."') OR (id_user = '".$_SESSION['user_id']."')) AND id_koszyk = '".$id_kosz_usun."' ";
  41.  
  42. $update_artykuly = "UPDATE rabat SET ilosc_dostepnych=(ilosc_dostepnych - '".$ilosc_rab."') WHERE idrabat='".$idrab."'";
  43. $ilosc_art_mag ="SELECT ilosc_dostepnych from rabat WHERE idrabat='".$idrab."'";
  44. $wynik_ilosc= mysql_query($ilosc_art_mag, $lacze) or die(mysql_error($mysql));
  45.  
  46. if( (!$wynik_ilosc))
  47. {
  48. echo "<span class='blad'> Wystapił błąd podczas zapisu. </span>";
  49. }
  50. else {
  51. $ilosc_magazyn = mysql_fetch_array($wynik_ilosc);
  52. $ilosc_mag = $ilosc_magazyn['ilosc_dostepnych'];
  53.  
  54. if ($ilosc_mag>=$ilosc_rab) {
  55. $wynik_zamow_art=mysql_query($rab_zam, $lacze) or die(mysql_error($mysql));
  56. $update_art= mysql_query($update_artykuly, $lacze) or die(mysql_error($mysql));
  57. $delete_koszyk= mysql_query($usun_koszyk, $lacze) or die(mysql_error($mysql));
  58. // mysql_close($lacze);
  59. }
  60. else {
  61. echo " <span class='blad'> Nie ma takiej ilości rabatów dla usługi: ".$nazwa_uslugi;
  62. echo " Zamówienie nie może zostać przyjęte.</span>";
  63. }
  64. }
  65. }
  66.  
  67. $wartosc_zam="SELECT SUM(suma_wyb_rab) as suma FROM szczegoly_zamowienia WHERE id_zam='".$id_zamow."'";
  68. $wartosc_rez = mysql_query($wartosc_zam, $lacze) or die(mysql_error($mysql));
  69. $wartosc_zamowienia = mysql_fetch_array($wartosc_rez);
  70. $suma_rab = $wartosc_zamowienia['suma'];
  71. // echo $suma_rab;
  72. $update_wartosc="UPDATE zamowienia SET rab_suma='".$suma_rab."' WHERE id_zam='".$id_zamow."'";
  73. $zapisz_wartosc = mysql_query($update_wartosc, $lacze) or die(mysql_error($mysql));
  74. mysql_query("COMMIT");
  75. echo('<span class="powodzenie">Zamówienie zostało przyjete do realizacji. </span>');
  76. // mysql_close($lacze);
  77. include("mail.php");
  78. echo "<META HTTP-EQUIV=Refresh CONTENT=5;URL=index.php>";
  79. }
  80. }
  81. else {
  82. require('config.php');
  83. echo " <h2> W momencie potwierdzenia zamówienia, zostaje ono przyjęte do realizacji.</h2><br>
  84. <p> W tym miejscu możesz wybrać sposób zapłaty lub wpisać dodatkowe uwagi. </p>
  85.  
  86. <form method=\"post\" action=\"index.php?id&potw\">
  87. <fieldset>
  88. <legend align=\"center\">Dane dodatkowe</legend>
  89.  
  90. <table border=\"0\" align=\"center\">
  91.  
  92. <tr><td><strong>Sposób zapłaty:</strong></td><td>
  93. <select name='sposob_zaplaty'>
  94. <option value='na miejscu'>na miejscu</option>
  95. <option value='przelew'>przelew</option>
  96. </select>
  97. <br /></td></tr>
  98. <tr><td><TEXTAREA NAME=\"uwagi\" ROWS=\"3\" COLS=\"25\">Wpisz dodatkowe uwagi</TEXTAREA></td></tr>
  99. </table>
  100. <br /> <br />
  101. <input type=\"hidden\" name=\"wartosc\" value=$wartosc_zam>
  102. <p class='submit2'>
  103. <input type=\"submit\" value=\"Potwierdź zamówienie\" />
  104. </p>
  105. </fieldset>
  106. </form>";
  107. mysql_close($lacze);
  108. }
  109. }
  110. else {
  111. echo " <br /><center><span class=blad>Tylko zalogowani użytkownicy mogą dokonać zamówienia
  112. <br> wybranych rabatów na usługi. </span><br /><br />";
  113. echo "Jeśli masz już u Nas konto zaloguj się w lewej części, wypełniając pola login i hasło podane przy rejestracji. <br /> <br><br>";
  114. echo "Jeśli jesteś u Nas pierszy raz i nie masz jeszcze konta przejdź do rejestracji.
  115. <a href=\"index.php?id&rejestracja\">REJESTRACJA</a><br /> </center>";
  116. }
  117. ?>
CuteOne
To raczej błąd "struktury" skryptu a nie błąd sam w sobie. Naucz się PHP lub zleć to komuś zamiast szukać łosia, który odwali za darmo cała robotę...
Zyx
Transakcję zakłada się na cały blok operacji, które mają być wykonane atomowo, tj. albo wykonają się w całości, albo w ogóle.

PS. Kod jest masakryczny.
sadistic_son
Szczerze mówiąc to też mi ciężko się odnaleźć w Twoim kodzie. A nie możesz przed każdą transakcją sprawdzać ile masz w bazie kupowanego produktu, porównywać z zamówieniem i jeśli $zamówiony<$na_stanie to wykonujesz resztę kodu ; else{ nie wykonujesz. Nie będzie tak łatwiej? Po co bawić się w ROLLBACK i COMMIT?
anka_skakanka
No więc wykonałam że najpierw sprawdza stan magazynu, jesli brak ilosci to jest komunikat i koniec... teraz tylko działa mi dodawanie , ale nie wiem dlaczego tylko dla jednego artykulu... wywala mi blad : Warning: mysql_query(): 8 is not a valid MySQL-Link resource in C:\xampp\htdocs\okazje\zamowienie.php on line 73 Warning: mysql_error() expects parameter 1 to be resource, null given in C:\xampp\htdocs\okazje\zamowienie.php on line 73
bedzie błąd w zapytaniu, tylko wg mnie pola się zgadzają, poza tym przy 1wszym towarze te zapytanie działa popranie.. to dla kolejnego towaru ma problem
sprawdzenie czy jest na stanie taka ilosc
  1. $kosz = "select * from koszyk_klienta WHERE id_user = '".$_SESSION['user_id']."' ";
  2. $w_kosz = mysql_query($kosz, $lacze) or die(mysql_error($mysql));
  3. while ($koszyk_info = mysql_fetch_array($w_kosz)) {
  4. $idrab = $koszyk_info['id_wyb_rab']; echo "<br>idrabat z koszyka".$idrab;
  5. $ilosc_rab=$koszyk_info['ilosc_wyb_rab']; echo "<br>ilosc z koszyka".$ilosc_rab; }
  6. $wynik_ilosc=mysql_query("select ilosc_dostepnych from rabat where idrabat='$idrab'",$lacze) or die(mysql_error($mysql));
  7. $ilosc_magazyn = mysql_fetch_array($wynik_ilosc);
  8. $ilosc_mag = $ilosc_magazyn['ilosc_dostepnych'];
  9. if ($ilosc_mag<$ilosc_rab) {
  10. echo " <span class='blad'> Nie ma takiej ilości rabatów"; echo " Zamówienie nie może zostać przyjęte.
  11. <br> W kolumnie dostępna ilość jest wskazana liczba dostępnych kuponów. </span>"; exit;
  12. }
i ta część dział poprawnie , natępnie jesli ilosc na magazynie umozliwia zakup to wstawienie rekordów do tableli zamówienia, pobranie id_zam, pobranie danych z koszyka < będa potrzben do uzupelnienia tabeli szczegoly_zam
  1. else {
  2. $data = date("Y-m-d H:m:s");
  3. $zamow = "INSERT INTO zamowienia (idklienta,data_zam,sposob_zaplaty,stan,id_sesji,uwagi)
  4. VALUES ( '".$_SESSION['user_id']."', '".$data."', '".$_POST["sposob_zaplaty"]."', 'oczekujace', '".$_COOKIE["PHPSESSID"]."', '".$_POST["uwagi"]."')";
  5. $wynik_zamow = mysql_query($zamow, $lacze);
  6. if( (!$wynik_zamow)) {
  7. mysql_close($lacze);
  8. echo "<span class='blad'>zamówienie nie zostało zrealizowane. </span>";echo "<META HTTP-EQUIV=Refresh CONTENT=3;URL=index.php>";
  9. } else {
  10. $id_zapytanie="SELECT id_zam FROM zamowienia WHERE id_sesji = '".$_COOKIE["PHPSESSID"]."'
  11. AND idklienta = '".$_SESSION['user_id']."' AND data_zam= '".$data."'";
  12. $id_zam = mysql_query($id_zapytanie, $lacze) or die(mysql_error($mysql));
  13. $temp=mysql_fetch_array($id_zam);
  14. $id_zamow=$temp['id_zam']; echo $id_zamow;
  15. $kosz = "select id_koszyk, id_wyb_rab, nazwa_uslugi, cena_z_rabatem, ilosc_wyb_rab from koszyk_klienta
  16. Join rabat on rabat.idrabat=koszyk_klienta.id_wyb_rab Join uslugi on rabat.iduslugi=uslugi.iduslugi
  17. WHERE id_sesji ='".$_COOKIE["PHPSESSID"]."' OR id_user = '".$_SESSION['user_id']."' ";
  18. $w_kosz = mysql_query($kosz, $lacze) or die(mysql_error($mysql));
  19. if( (!$w_kosz)) {
  20. echo "<span class='blad'> Wystapił błąd podczas zapisu. </span>";
  21. } else {
  22. while ($koszyk_info = mysql_fetch_array($w_kosz)) {
  23. $idrab = $koszyk_info['id_wyb_rab']; //$nazwa_uslugi = stripslashes($koszyk_info['nazwa_uslugi']);
  24. $cena_rab = $koszyk_info['cena_z_rabatem'];
  25. $ilosc_rab = $koszyk_info['ilosc_wyb_rab'];
  26. $suma = sprintf("%.02f", $cena_rab * $ilosc_rab);
  27. $wartosc_zam = $wartosc_zam + $suma;
  28. $id_kosz_usun = $koszyk_info['id_koszyk'];

wstawienie danych do tabeli szczegoly_zamowienia, o ta linię kodu ma warning przy kolejnym towarze w koszyku
  1. $rab_zam = "INSERT INTO szczegoly_zamowienia (id_zam,id_wyb_rab,ilosc_wyb_rab,cena_wyb_rab,suma_wyb_rab)
  2. VALUES('".$id_zamow."', '".$idrab."', '".$ilosc_rab."', '".$cena_rab."', '".$suma."')";
  3. echo "zam".$id_zam." rab".$idrab." ilosc".$ilosc_rab." cena".$cena_rab." suma".$suma;
  4. $wynik_zamow_art=mysql_query($rab_zam, $lacze) or die(mysql_error($mysql));

potem następuje usunięcie zawartości koszyka, aktualizacja ilosc _dostepnych i sumy wybranych rab
  1. $usun_koszyk = "DELETE FROM koszyk_klienta WHERE ((id_sesji = '".$_COOKIE["PHPSESSID"]."') OR (id_user = '".$_SESSION['user_id']."')) AND id_koszyk = '".$id_kosz_usun."' ";
  2. $delete_koszyk= mysql_query($usun_koszyk, $lacze) or die(mysql_error($mysql));
  3.  
  4. $update_artykuly = "UPDATE rabat SET ilosc_dostepnych=(ilosc_dostepnych - '".$ilosc_rab."') WHERE idrabat='".$idrab."'";
  5. $update_art= mysql_query($update_artykuly, $lacze) or die(mysql_error($mysql));
  6.  
  7. $wartosc_zam="SELECT SUM(suma_wyb_rab) as suma FROM szczegoly_zamowienia WHERE id_zam='".$id_zamow."'";
  8. $wartosc_rez = mysql_query($wartosc_zam, $lacze) or die(mysql_error($mysql));
  9. $wartosc_zamowienia = mysql_fetch_array($wartosc_rez);
  10. $suma_rab = $wartosc_zamowienia['suma'];
  11. echo "suma_rabt".$suma_rab;
  12.  
  13. $update_wartosc="UPDATE zamowienia SET rab_suma='".$suma_rab."' WHERE id_zam='".$id_zamow."'";
  14. $zapisz_wartosc = mysql_query($update_wartosc, $lacze) or die(mysql_error($mysql));
  15. echo('<span class="powodzenie">Zamówienie zostało przyjete do realizacji. </span>');
  16. mysql_close($lacze);
  17. include("mail.php");
w wyniku poprawnego wykonania mail z informacją o przyjęciu zamówienia... Czy teraz będzie łatwiej nakierować na ewetualne nakierowanie na zlikidowanie błędu ?


wiewiorek
WoW ale kod exclamation.gif
co to ma być to:
  1. or die(mysql_error($mysql))


Czymże jest '$mysql' ? Dlaczego nie '$lacze' ?
gino
W błędzie masz odpowiedz, parser php wywali Ci, że oczekuje (słówko expects) identyfikatora łącza. Jak napisał wiewiorek zmienna $mysql nie jest nim na pewno.

PS. Zdaniem moim i przedmówców, zamiast później przepisywać to jeszcze raz, albo i więcej razy poszukaj na forum postów o organizacji kodu, rozdzieleniu warstwy php od html-a albo zleć to komuś.

gino
CuteOne
Po pierwsze - trudno wytłumaczyć komuś kto zna podstawy podstaw PHP jak ma rozwiązać swój problem.
Po drugie - trudno połapać się w Twoim "kodzie"
Po trzecie jak już wcześniej mówiłem tu nie ma błędu jako takiego. Widzę tu jedynie błąd w postaci źle zaplanowanej aplikacji a szukanie łosia, który poprawi coś takiego za darmo droga Panno to zwykłe zdzierstwo...

Przechodząc do meritum - nauczysz się PHP albo zleć to komuś
anka_skakanka
Cytat(CuteOne @ 22.03.2011, 01:09:36 ) *
Po pierwsze - trudno wytłumaczyć komuś kto zna podstawy podstaw PHP jak ma rozwiązać swój problem.
Po drugie - trudno połapać się w Twoim "kodzie"
Po trzecie jak już wcześniej mówiłem tu nie ma błędu jako takiego. Widzę tu jedynie błąd w postaci źle zaplanowanej aplikacji a szukanie łosia, który poprawi coś takiego za darmo droga Panno to zwykłe zdzierstwo...

Przechodząc do meritum - nauczysz się PHP albo zleć to komuś

1. Te podstawy podstaw są wyciągnięte z książek php mysql apache ...
2. Kod też jest utowrzony na podstawie tychże książek np cały rozdział 15 , php5, mysql apache. od podstaw
3. trzeba było podać od razu cene Was Pan
4. akcentowaie płci nie ma tu znaczenia
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.