Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] KOSZYK SKLEPU
Forum PHP.pl > Forum > Przedszkole
kielich
Witam,
Tworzę koszyk i mam błąd który nie wiem jak obejść mianowicie o to kod:

  1. $koszyk = new Zend_Session_Namespace('koszyk'); //Zmienna sesyjna koszy
  2.  
  3. $dane['id'] = $id;
  4. $dane['sztuk'] = 1;
  5. $koszyk->dane[] = $dane;
  6.  
  7.  
  8. if($id==1): //sprawdzamy czy juz jest to id (ja sprawdzałem tylko na ID 1 - dla większego komfortu tongue.gif )
  9. foreach($koszyk->dane as $dane => $k):
  10. $koszyk->dane[$dane]['sztuk'] ++; //zwiekszamy liczbe sztuk o jeden
  11. endforeach;
  12. endif;
  13.  
  14. print_r($koszyk->dane);

i błąd polega na tym że dodaje tę 1 sztukę więc tak jak ma dodawać ale dodatkowo tworzy nowe rekordy w tablicy a ja bym chciał aby zmienił tylko ilość w danym produkcie.
Gdzie się zakręciłem questionmark.gif
nospor
$koszyk->dane[] = $dane;
przeciez ten kod zawsze dodaje do tablicy kolejny wpis.
kielich
tak wiem . Wypisałem tak

  1. echo $koszyk->dane['0']['sztuk'];


I jest OK jeśli mam 1 produkt i kilka razy dodany wiec sztuki się zwiększaja ale jest problem kiedy jest wiecej niz 2 produkty wtedy nie wiem jak znaleźć dany rekord


Więc jak mogę to rozwiązać?
dr_bonzo
Do koszyka wstawiaj strukture/obiekt ktor bedzie zawieraj ID produktu i jego ilosc. Wtedy przegladajac zawartosc koszyka mozesz sprawdzic jaki produkt akurat przegladasz i do niego dodac kolejna sztuke itp.
kielich
napisałem tak

  1. $koszyk = new Zend_Session_Namespace('koszyk');
  2.  
  3. if(isset($id)):
  4. $ok = true;
  5. foreach ($koszyk->dane as $kosz => $opcja):
  6. echo 'To jest ID: '.$opcja['id'].' ma sztuk: '.$opcja['sztuk'].'<br />';
  7. if($opcja['id']==$id):
  8. $koszyk->dane[$kosz]['sztuk']++;
  9. $ok = false;
  10. endif;
  11. endforeach;
  12.  
  13. if($ok):
  14. $dane['id'] = $id;
  15. $dane['sztuk'] = 1;
  16. $koszyk->dane[]= $dane;
  17. endif;
  18. endif;


I działa to już znacznie lepiej ale jest gdzieś błąd ponieważ wpisuje w url id 4 i enter i dodaje mi do tablicy klikam jeszcze raz dodaje mi następną sztukę czyli tak jak chce smile.gif
Wpisuje id 6 klikam i dodaje się do tablicy z tym że dodatkowo dodaje jedna sztukę do poprzedniej czyli do ID 4 ale kiedy odświeżę to normalnie dodaje do 6 jak należy .
Co jest tu nie tak questionmark.gif?

Moim zdaniem problem leży w if' w foreach ponieważ zawsze będzie spełniony a muszę sprawdzić czy id jest już w tablicy analogicznie mogę użyć array_key_exists lecz kiedy zrobie tak

  1. if(array_key_exists($id,$opcja['id'])):


wywala błędy array_key_exists() expects parameter 2 to be array, integer given

KURDE NIKT NIE JEST W STANIE MI POMÓC questionmark.gif;:(
zegarek84
zwróć uwagę jak wstawiasz do koszyka kolejne produkty:
$koszyk->dane[]= $dane;
tutaj kolejne produkty będą miały kolejne klucze... w sumie tak też może być ale mogło być np.
$koszyk->dane[$id_produktu]= $dane; - okej, pomińmy to idźmy dalej... w $opcja['id'] trzymasz ten identyfikator, niech i tak będzie, ale funkcja array_key_exists($id,$opcja['id']) dokładnie sprawdza czy istnieje klucz w tablicy (która u Ciebie nie jest tablicą bo to identyfikator...) $opcja['id'] o nazwie $id... czyli prawie jakby to samo co sprawdzać czy istnieje zmienna w lokalizacji $opcja['id'][$id]...
Cytat(kielich @ 8.08.2010, 20:08:33 ) *
I działa to już znacznie lepiej ale jest gdzieś błąd ponieważ wpisuje w url id 4 i enter i dodaje mi do tablicy klikam jeszcze raz dodaje mi następną sztukę czyli tak jak chce smile.gif
Wpisuje id 6 klikam i dodaje się do tablicy z tym że dodatkowo dodaje jedna sztukę do poprzedniej czyli do ID 4 ale kiedy odświeżę to normalnie dodaje do 6 jak należy .
Co jest tu nie tak questionmark.gif?
nie napisałeś jak wyświetlasz sobie ten koszyk... założę się, że dodajesz kolejny produkt od razu wyświetlając zawartość koszyka i zapewne robisz coś na styl:
$i=2;
echo $i++; // ile się wyświetli - 2 a zmienna ma 3, czyli niżej
echo $i; // 3, zaś:
echo ++$i; // 4 i zmienna jest 4
kielich
Dziękuje za opowiedz ale szczerze mówiąc do niczego mnie to nie nakierowało sad.gif
zegarek84
pokaż gdzieś ale w całości skrypt którym dodajesz produkty i którym wyświetlasz zawartość koszyka - z tego co pisałeś na 99% jest to ten sam skrypt gdzie wszystko się dzieje w jednej akcji...
kielich
O to cały kod

  1. public function koszykAction()
  2. {
  3. $filtr = new Application_Model_statyczne_filtry();
  4. $id = $filtr->filtrowanie_id($this->getRequest()->getParam('id'));
  5. $koszyk = new Zend_Session_Namespace('koszyk');
  6. $koszyk->setExpirationSeconds(7200);
  7.  
  8. if($id):
  9.  
  10. if(isset($id)):
  11. $ok = true;
  12. foreach ($koszyk->dane as $kosz => $opcja):
  13. echo 'To jest ID: '.$opcja['id'].' ma sztuk: '.$opcja['sztuk'].'<br />';
  14. if($opcja['id']==$id):
  15. $koszyk->dane[$kosz]['sztuk']++;
  16. $ok = false;
  17. endif;
  18. endforeach;
  19.  
  20. if($ok):
  21. $dane['id'] = $id;
  22. $dane['sztuk'] = 1;
  23. $koszyk->dane[]= $dane;
  24. endif;
  25. endif;
  26.  
  27. endif;


Jeśli nie pracujesz z zendem a chcesz mi pomóc smile.gif do zapodaj to sobie normalnie na localu zmien tylko $id na GET oraz pozostałe zmienne
zegarek84
Cytat(kielich @ 9.08.2010, 11:30:53 ) *
O to cały kod...
Prawie, jednak nie cały bo i metoda nie domknięta a i nie ma przykładu użycia tej metody winksmiley.jpg - ale wystarczy winksmiley.jpg
Cytat(kielich @ 9.08.2010, 11:30:53 ) *
...Jeśli nie pracujesz z zendem a chcesz mi pomóc smile.gif do zapodaj to sobie normalnie na localu zmien tylko $id na GET oraz pozostałe zmienne
w ogóle przy komputerach nie pracuję ^^ - a do zenda czasem zaglądam coby nieraz podpatrzeć zależności klas - jednak z samego zenda jakoś nigdy nie korzystałem - ale jestem wzrokowcem to i tego kodu nie musiałem odpalać winksmiley.jpg...

skoro to prawie działa to zamień ten foreach:
  1. foreach ($koszyk->dane as $kosz => $opcja):
  2. echo 'To jest ID: ' . $opcja['id'] . ' ma sztuk: ' . $opcja['sztuk'] . '<br />'; //zauważ, że w pierwszej kolejności wyświetliłeś a dopiero potem dodałeś do koszyka - nie miałeś tego na ekranie to tego nie zauważyłeś...
  3. if ($opcja['id'] == $id):
  4. $koszyk->dane[$kosz]['sztuk']++;
  5. $ok = false;
  6. endif;
  7. endforeach;

na ten:
  1. foreach ($koszyk->dane as $kosz => $opcja):
  2. if ($opcja['id'] == $id):
  3. $koszyk->dane[$kosz]['sztuk']++;
  4. $ok = false;
  5. endif;
  6. echo 'To jest ID: ' . $opcja['id'] . ' ma sztuk: ' . $opcja['sztuk'] . '<br />';
  7. endforeach;

oczywiście od tak tylko piszę, że ten ciąg powinien być w tej metodzie zwrócony a nie wyświetlony od razu na ekran winksmiley.jpg...
PS.
chyba dawniej sporo pisałeś w czymś w stylu VBA winksmiley.jpg... - a i przy okazji w językach skryptowych szybsze jest ++$i od $i++, w językach kompilowalnych w zasadzie to różnicy nie robi... a różnica jest taka, że przy $i++ tworzona jest dodatkowa zmienna a dopiero po użyciu starej zmiennej bądź w następnych linijkach kodu zastępowana przez nową wartość...
kielich
No jednak to nic nie dało kiedy dodam do koszyk wyjde wybieram nowy produkt i klikam do koszyk to dodaje ale wartość poprzednio dodanego zwiększa o jeden sad.gif
zegarek84
to podaj gdzieś cały kod - zmienić się zmieniło bo wcześniej echo wyświetlało Ci zawartość koszyka przed dodaniem +1, teraz echo się wyświetla po dodaniu +1...

podaj cały kod z przykładem urzycia gdzieć - czy to na wklej czy gdziekolwiek... podaj w komentarzu u góry jeszcze adres koszyka przykładowy i przykładowy adres produktu - może metodę tą masz także w określonym produkcie użytąquestionmark.gif - gdyż jeśli tak to tam też dodajesz produkt o ile jest ta zmienna w adresie...
kielich
Napisałem cały kod już jest po prostu użyty poprzez kontroler np. localhost/koszyk/5
gdzie 5 do ID
zegarek84
czy na pewno zamieniłeś sobie te pętle foreach??... nie masz tam czasem redirecta gdzieś [np. po dodaniu pierwszego produktu, gdyz kod podałeś bez domknięcia...]questionmark.gif, co jest zwracane tutaj [czy na pewno liczba??]:
$id = $filtr->filtrowanie_id($this->getRequest()->getParam('id'));
dlaczego niby twierdzisz??:
Cytat
Moim zdaniem problem leży w if' w foreach ponieważ zawsze będzie spełniony

wpisz może var_dump($id) zaraz po przypisaniu jej wartości?? - czy to string czy liczba...
kielich
$id jest liczba(integer) jak widać jest filtrowane i jest to id produktu dodane do koszyka a o to cały kod

  1. public function koszykAction()
  2. {
  3. $filtr = new Application_Model_statyczne_filtry();
  4. $id = $filtr->filtrowanie_id($this->getRequest()->getParam('id'));
  5. $koszyk = new Zend_Session_Namespace('koszyk');
  6. $koszyk->setExpirationSeconds(7200);
  7. if($id):
  8. $ok = true;
  9. foreach ($koszyk->dane as $kosz => $opcja):
  10. if ($opcja['id'] == $id):
  11. $koszyk->dane[$kosz]['sztuk']++;
  12. $ok = false;
  13. endif;
  14. echo 'To jest ID: ' . $opcja['id'] . ' ma sztuk: ' . $opcja['sztuk'] . '<br />';
  15. endforeach;
  16.  
  17. if($ok):
  18. $dane['id'] = $id;
  19. $dane['sztuk'] = 1;
  20. $koszyk->dane[]= $dane;
  21. endif;
  22. endif;
  23.  
  24.  
  25. }


Odpal to sobie jest możesz ponieważ kompilujesz wzrokowo i może coś pominąłeś sad.gif Może jakieś inne działające rozwiązanie . Kurcze od kilku dni się z tym meczę a błąd pewnie banalny .sad.gif
zegarek84
zamień tą metodę na inną - trochę mi tu coś nie gra - nie wiem, czy masz gdzieś redirekta czy co [akurat nie w metodzie], jeśli już to wcześniej zobaczysz skok o 2 [zamieniłem też tutaj strukturę tabeli koszyka]:
  1. public function koszykAction() {
  2. $filtr = new Application_Model_statyczne_filtry();
  3. $id = (integer) $filtr->filtrowanie_id($this->getRequest()->getParam('id'));
  4. $koszyk = new Zend_Session_Namespace('koszyk');
  5. $koszyk->setExpirationSeconds(7200);
  6.  
  7. if (isset($id) && $id !== 0):
  8. if (!isset($koszyk->dane[$id])) { //DODAWANIE
  9. $dane = array('sztuk'=>1);
  10. $koszyk->dane[$id] = $dane;
  11. } else { //ZWIĘKSZANIE LICZBY
  12. ++$koszyk->dane[$id]['sztuk'];
  13. }
  14. // WYŚWIETLANIE
  15. foreach ($koszyk->dane as $id_key => $info_produkt):
  16. echo 'To jest ID: ' . $id_key . ' ma sztuk: ' . $info_produkt['sztuk'] . '<br />';
  17. endforeach;
  18. endif;
  19. }
  20. // KOSZYK O STRUKTURZE
  21. //$koszyk->dane=array(
  22. // INTEGER_klucz_produktu => ARRAY_dodatkowe_dane_produktu
  23. //);

a wogóle to bym to podzielił na 2 części razem z redirektem gdyż różne rzeczy o indexacji słyszałem...
  1. class koszyk {
  2.  
  3. private $koszyk;
  4.  
  5. public function __construct() {
  6. $this->koszyk = new Zend_Session_Namespace('koszyk');
  7. $this->koszyk->setExpirationSeconds(7200);
  8. }
  9.  
  10. public function dodajAction() {
  11. $filtr = new Application_Model_statyczne_filtry();
  12. $id = (integer) $filtr->filtrowanie_id($this->getRequest()->getParam('id'));
  13. $this->koszyk = new Zend_Session_Namespace('koszyk');
  14. $this->koszyk->setExpirationSeconds(7200);
  15.  
  16. if (isset($id) && $id !== 0):
  17. if (!isset($this->koszyk->dane[$id])) { //DODAWANIE
  18. $dane = array('sztuk'=>1);
  19. $this->koszyk->dane[$id] = $dane;
  20. } else { //ZWIĘKSZANIE LICZBY
  21. ++$this->koszyk->dane[$id]['sztuk'];
  22. }
  23. endif;
  24. // PRZEKIEROWUJEMY NA KOSZYK COBY WYŚWIETLIĆ ZAWARTOŚĆ
  25. header('Location: ' . $ADRES_DO_KOSZYKA);
  26. }
  27.  
  28. public function koszykAction() {
  29. // WYŚWIETLANIE ZAWARTOŚCI
  30. $str = '';
  31. foreach ($this->koszyk->dane as $id_key => $info_produkt):
  32. $str .= 'To jest ID: ' . $id_key . ' ma sztuk: ' . $info_produkt['sztuk'] . '<br />';
  33. endforeach;
  34. return $str;
  35. }
  36. }
  37.  
  38. //a tak najlepiej to by było dane przekazywać metodą POST gdzie jeszcze dodatkowo mógłbyś zdefiniować ile sztuk ktoś chce kupić
  39. class koszyk2 {
  40.  
  41. private $koszyk;
  42.  
  43. public function __construct() {
  44. $this->koszyk = new Zend_Session_Namespace('koszyk');
  45. $this->koszyk->setExpirationSeconds(7200);
  46. }
  47.  
  48. public function dodajAction() {
  49. $id = (integer) $_POST['id'];
  50. $ile = (integer) $_POST['ile'];
  51. // PASUJE SPRAWDZIĆ ALBO TUTAJ ALBO PRZY WYŚWIETLANIU CZY JEST W BAZIE PRODUKT O TYM ID - PROPONUJĘ PRZY WYŚWIETLANIU I JEŚLI W BAZIE NIE MA TO TAKIE INDEKSY POUSUWAĆ
  52. // TRZEBA JESZCZE PAMIĘTAĆ, BY KTOŚ NIE ZAMÓWIŁ WIĘCEJ NIŻ JEST DOSTĘPNYCH PRODUKTÓW
  53. // CENY NIE PRZECHOWUJ W SESJI ZWŁASZCZA JESLI KOSZYK CHOĆ KILKA GODZIN MA ŻYWOTNOŚCI - POBIERAJ PRZY WYŚWIETLANIU Z BAZY...
  54. if ($id !== 0 && $ile !== 0):
  55. if (!isset($this->koszyk->dane[$id])) { //DODAWANIE
  56. $dane = array('sztuk'=>$ile);
  57. $this->koszyk->dane[$id] = $dane;
  58. } else { //ZWIĘKSZANIE LICZBY - o tyle ktoś dokupuje
  59. $this->koszyk->dane[$id]['sztuk'] += $ile;
  60. }
  61. endif;
  62. // PRZEKIEROWUJEMY NA KOSZYK COBY WYŚWIETLIĆ ZAWARTOŚĆ
  63. header('Location: ' . $ADRES_DO_KOSZYKA);
  64. }
  65.  
  66. public function koszykAction() {
  67. if (reset($this->koszyk->dane) === false) return false; //PUSTY KOSZYK I NIC NIE MA - ZWRACAMY JAKIŚ WIDOK PUSTKI...
  68. // POBIERAMY AKTUALNE INFO z bazy w stylu "SELECT * FROM produkty WHERE `id` IN (...)
  69. $in = implode(', ', array_keys($this->koszyk->dane));
  70. // $sql='SELECT * FROM `produkty` WHERE `id` IN ('.$in.')';
  71. //...
  72. //ODPYTUJEMY BAZE O AKTUALNE PRODUKTY;
  73. $produkty_z_bazy = array();//NIE PUSTE JUŻ... I NAJLEPIEJ TAK JUŻ UŁOŻONY JAK W KOSZYKU PO ID PRODUKTU
  74. // CENĘ W BAZIE PRZECHOWYWAĆ JAKO INTEGER A POTEM PODZIELIĆ PRZEZ 100..
  75. // JAK NIE MUSZE TO NIE UŻYWAM FOREACH - ALE RÓŻNICY TO NIE ROBI
  76. $to_del = array();
  77. $bufor = '';
  78. $razem = 0;
  79. do {
  80. $id_key = key($this->koszyk->dane);
  81. if (!isset($produkty_z_bazy[$id_key])) {
  82. $to_del[] = $id_key;
  83. continue; // POMIJAMY NIE POPRAWNE WIERSZE
  84. };
  85. // TRZA BY ZROBIĆ JESZCZE JEDNEGO IFA CZY PRODUKTU W BAZIE NIE MA MNIEJ NIŻ W KOSZYKU I JESLI TAK TO W KOSZYKU ZMIENIĆ LICZBĘ NA MNIEJSZĄ
  86. $sztuk = $this->koszyk->dane[$id_key]['sztuk'];
  87. $za_produkt_razem = $sztuk * $produkty_z_bazy[$id_key]['cena'];//cena dalej jest 100 razy większa.
  88. $razem += $za_produkt_razem;
  89. $bufor .= 'To jest ID: ' . $id_key . ' ma sztuk: '
  90. . $this->koszyk->dane[$id_key]['sztuk'] . ' o łącznej wartości: '
  91. . floor($za_produkt_razem / 100) . ',' . $za_produkt_razem % 100 . '<br />';
  92. } while (next($this->koszyk->dane) !== false);
  93. if (isset($to_del[0]))
  94. for ($i = 0, $count = count($to_del);$i < $count;++$i)
  95. unset($this->koszyk->dane[$i]);
  96. $bufor .= 'RAZEM: ' . floor($razem / 100) . ',' . $razem % 100;
  97. return $bufor;
  98. }
  99. }
kielich
Czy ty na prawdę pisałeś to specjalnie dla mnie questionmark.gif smile.gif Kurcze jak to zobaczyłem to przez 30 sek nie wierzyłem ponieważ nie wszyscy mają takie chęci jak ty. Pierwszy kod (mój przerobiony) działa jak należy oczywiście dodałem jeszcze sprawdzanie czy jest tyle w bazie itd. itd. ale działa jak należy .BARDZO TOBIE DZIĘKUJE na prawdę dzięki. smile.gif
zegarek84
Cytat(kielich @ 9.08.2010, 18:44:49 ) *
Pierwszy kod (mój przerobiony) działa jak należy oczywiście dodałem jeszcze sprawdzanie czy jest tyle w bazie itd. itd. ale działa jak należy...
tylko i tak jak wspomniałem pasowało by ten pierwszy kod uszczuplić a wyświetlanie przerzucić na inną akcję choćby z tego względu, iż user gdy będzie w innej części sklepu to może będzie chciał zajrzeć do koszyka??... albo idąc dalej jak już będziesz dorabiał zarządzanie koszykiem [czyli usuwanie produktów itp.] to też potem pasuje to wyświetlić... a wystarczyło by bez wyświetlania dodawać/usuwać zawartość koszyka a po całej operacji redirektem przekierować na stronę z akcją wyświetlania koszyka - tzn. jego zawartości... w zasadzie przy zarządzaniu koszykiem tam też można by zwiększać i zmniejszać liczbę produktów a czy się zwiększa czy zmniejsza można rozpoznać po odpowiednim klikniętym przycisku formularza... i tą operację usuwania można by dać do metody dodawania tylko bardziej to rozbudować [choć dla wygody można by wydzielić do innej metody a dopiero tamtą metodę usuwania wywołać w metodzie dodawania]...

tak tylko ogólnie piszę, ale z tego co się orientuję to wielu jeśli akcja była przez linki zakupów z botami miało problemy - choćby z indeksacją koszyka w google...

ale w sumie to też pisze tak ogólnie i w zasadzie zrób jak uważasz winksmiley.jpg
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.