Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: koszyk na zakupy
Forum PHP.pl > Forum > PHP > Object-oriented programming
Olimpia_ona
Witam,
na początek powiem, że nie umiem programować obiektowo, ale znalazłam bardzo czytelny kawałek skryptu, który bym chciała dołączyć do swojego strukturalnego kodu.
Na początek wkleje ten piękny skrypt.
plik koszyk.php
  1. <?php
  2. /* koszyk.php - klasa bazowa koszyka na zakupy 
  3. */ 
  4. /* zawiera definicje podstawowych operacji na koszu 
  5. */
  6. /* Zaimplementowane funkcje: 
  7. */ 
  8. /* koszyk  - konstruktor tworzy koszyk z zawartoscia 
  9. */ 
  10. /* dodaj - dodaje $ilosc $elementow do koszyka 
  11. */ 
  12. /* usun  - usuwa $ilosc $elementow z koszyka 
  13. */ 
  14. /* stan  - zwraca zawartosc w postaci hasza 
  15. */ 
  16.  
  17.  
  18. class koszyk 
  19. { 
  20. /* tablica asocjacyjna zawierajaca stan koszyka 
  21. */ 
  22. /* klucz, to wartosc id produktu, wartosc to ilosc elementow 
  23. */ 
  24. var $zawartosc; 
  25.  
  26.  
  27. function dodaj($element, $ilosc) 
  28. { 
  29. $this->zawartosc[$element] += $ilosc; 
  30. } 
  31.  
  32.  
  33. function usun($element, $ilosc) 
  34. { 
  35. if ($this->zawartosc[$element] > $ilosc) 
  36. $this->zawartosc[$element] -= $ilosc; 
  37. else 
  38. unset($this->zawartosc[$element]); 
  39. } 
  40.  
  41.  
  42. function stan() 
  43. { 
  44. return $this->zawartosc; 
  45. } 
  46.  
  47.  
  48.  
  49. }
  50. ?>


plik session.php
  1. <?php
  2. /* klasa koszyka */ 
  3. include('koszyk.php'); 
  4.  
  5.  
  6. /* start sesji */ 
  7.  
  8.  
  9. if (!$koszyk) 
  10. $koszyk = new koszyk; 
  11.  
  12.  
  13. if ($dodaj) 
  14. $koszyk->dodaj($dodaj, 10); 
  15.  
  16.  
  17. if ($usun) 
  18. $koszyk->usun($usun, 10); 
  19.  
  20.  
  21. session_register('koszyk'); 
  22.  
  23.  
  24. $stan = $koszyk->stan(); 
  25. if ($stan) 
  26. while (list($key, $value) = each($stan)) 
  27. echo "$key $value<br>";
  28. ?>



i teraz tak, to co jest pod słowem plik session.php wkleiłam sobie na stronę pomiędzy jakieś tam <td></td> no i wyskakuje mi błąd
Fatal error: Unknown(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition <b>koszyk</b> of the object you are trying to operate on was loaded _before_ the session was started

więc zrobiłam tak jak napisali i wkleiłam fragment include("koszyk.php"); na górze swojej strony index.php
  1. <?php
  2. include ('incl/funkcje.php');
  3. include("koszyk.php");
  4. $status=$_GET['status'];
  5. ..itd
  6. ?>


no ale w tym wypadku wyświetla mi się błąd:
Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at c:\usr\krasnal\www\sexshop\koszyk.php:60) in c:\usr\krasnal\www\sexshop\index.php on line 4

Wiec jak ja mam to rozwiązać? Pomocy
Cysiaczek
session_start() na samiuteńkim początku skryptu, bo musi zostać zainicjowana zanim jakikolwiek znak zostanie wysłany do przeglądarki. Było na forum z 1000 razy.

Pozdrawiam.
Babcia@Stefa
Jak powiedział kolega z góry.

  1. <?php /* start sesji */ session_start(); 
  2. /* klasa koszyka */ 
  3. include('koszyk.php');
  4. if (!$koszyk)  
  5. $koszyk = new koszyk; 
  6. if ($dodaj)  
  7. $koszyk->dodaj($dodaj, 10); 
  8. if ($usun)  
  9. $koszyk->usun($usun, 10); 
  10. session_register('koszyk'); 
  11. $stan = $koszyk->stan(); 
  12. if ($stan)  
  13. while (list($key, $value) = each($stan))  
  14. echo "$key $value<br>";?>

To w razie jakiś nie jasności tongue.gif

Dziekuję, Babcia@Stefa
Sedziwoj
Taki fajny cytacik:
Cytat
If you are using $_SESSION (or $HTTP_SESSION_VARS), do not use session_register(), session_is_registered(), and session_unregister().


Komentarze tyczące się metod powinny być przed tymi metodami.
Czy koniecznie musi być PHP4? obiekty w PHP5 są 'bardziej obiektowe'.
Nazwa 'usun' sugeruje, że robi coś innego niż robi w rzeczywistości.
Do tego najczęściej jest modyfikowana ilość elementów, a nie zmniejszana/powiększana.

Do tego nie do końca rozumiem, co tak na prawdę to ma robić.

EDIT lit.
Olimpia_ona
Mam jeszcze jedno pytanie do tego kodu który wkleiłam na górze:
Jak to przerobić, by w koszu jeszcze przetrzymywać kolor i rozmiar produktu?
Jak by miało wyglądać ciało funkcji dodaj, gdybym zrobiła tak

  1. <?php
  2. function dodaj($element, $ilosc, $kolor, $rozmiar)
  3. {
  4. //?questionmark.gif
  5. }
  6. ?>

wywoływałabym tak:
dodaj($dodaj, 1, $kolor, $rozmiar)

no i jeśli ktoś wie, to w takim razie jak wyświetlić taką tablicę wielowymiarową tym sposobem
while (list($key, $value) = each($stan))
NuLL
Musialaby zamiast ilosci w tej tablicy jako kolejne elementy trzymac tablice i tam w odpowiedni sposob zapisywac takie dane.
Sedziwoj
Mam pytanie to ma być obiektowo? czy bawimy się proceduralnie?
Przecież tan koszyk to nic innego niż kolekcja... (nie wiem czy to ta nazwa)
Ogólnie powinien być np.:
  1. <?php
  2. class Produkt{
  3.  private $intId;
  4.  private $strKolor;
  5.  private $intRozmiar;
  6.  
  7.  public function getId(){
  8.  return $this->intId;
  9.  }
  10.  public function __construct( $intId ){
  11. //chyba najlepiej gdyby tu pobierało (podkreślam chyba, bo można przekazywać przy tworzeniu)
  12.  
  13. //zamiast na sztywno, powinno skądś to pobrać
  14. $this->strKolor = 'czarnr'.$intId;
  15. $this->intRozmiar = 4+$intId;
  16.  }
  17.  
  18.  public function getKolor(){
  19. return $this->strKolor;
  20.  }
  21.  
  22.  public function getRozmiar(){
  23. return $this->intRozmiar;
  24.  }
  25. }
  26. ?>


no i wtedy ten koszyk by wyglądał jakoś tak:
  1. <?php
  2. class Koszyk{
  3.  private $arrProdukt;
  4.  
  5.  public function getByProduktId( $intId ){
  6. return $this->arrProdukt[$intId];
  7.  }
  8.  
  9.  public function getWszystkie(){
  10. return $this->arrProdukt;
  11.  }
  12.  
  13.  public function dodaj( Produkt $objProdukt, $intIlosc ){
  14. if( !isset(this->arrProdukt[$intId]) ){
  15.  this->arrProdukt[$objProdukt->getId] = array(
  16. 'produkt' => $objProdukt,
  17. 'ilosc' => $intIlosc
  18. );
  19. }else{
  20.  $this->arrProdukt[$intId]['ilosc'] += $intIlosc;
  21. }
  22.  }
  23.  
  24.  public function usun( Produkt $objProdukt ){
  25. $this->arrProdukt[$intId]['ilosc'] -= $intIlosc;
  26.  }
  27. }
  28. ?>


co prawda można to jeszcze ładniej... do tego nie dałem żadnej weryfikacji.
Ale teraz wystarczy wiedzieć, że obiekt Produkt ma metodę getId(), która zwraca unikalny identyfikator, a reszta nas nie obchodzi, no bo oprucz co to za element i ile go jest nie powinno nas nic obchodzić.
(sam kod na tej zasadzie można jeszcze lepiej zorganizować, choć się zastanawiam czy warto trzymać coś więcej niż id produktu i ilość, bo PHP i tak to wszystko traci między stronami, a nie ma sensu trzymać całych opisów w danych sesyjnych, więc iloć i id produktu wystarczyło by, a potem kiedy trzeba wyświetlić zawartość to już nie kłopot jedno zapytanie i mamy wszystkie produkty z koszyka)
Olimpia_ona
Cytat(Sedziwoj @ 11.05.2007, 18:21:04 ) *
...no bo oprucz co to za element i ile go jest nie powinno nas nic obchodzić.
(sam kod na tej zasadzie można jeszcze lepiej zorganizować, choć się zastanawiam czy warto trzymać coś więcej niż id produktu i ilość, bo PHP i tak to wszystko traci między stronami, a nie ma sensu trzymać całych opisów w danych sesyjnych, więc iloć i id produktu wystarczyło by, a potem kiedy trzeba wyświetlić zawartość to już nie kłopot jedno zapytanie i mamy wszystkie produkty z koszyka)


No właśnie ja mam tak zrobione, że do tego koszyka jest tylko id produktu i ilość, ale niektóre produkty mają wiele kolorów i różne rozmiary i chcę zrobić tak, by klient zanim wciśnie dodaj do koszyka mógł zaznaczyć, jaki kolor i rozmiar danego produktu chce kupić i to też bym chciała trzymać w koszyku/sesji.
Dla tego zależałoby mi by to było jakoś tak na podstawie takiej funkcji
  1. <?php
  2. function dodaj($element, $ilosc, $kolor, $rozmiar) 
  3. { //?questionmark.gif 
  4. }
  5. ?>


>> Sedziwoj w tej Twojej funkcji nie rozumiem tego fragmentu:
  1. <?php
  2. public function __construct( $intId )
  3. { $this->strKolor = 'czarnr'.$intId; $this->intRozmiar = 4+$intId;  }
  4. ?>


czumu jest 'czarnr'.$intId z kropką, a tu z plusem 4+$intId
Sedziwoj
Jeśli o tamten fragment chodzi, to po prostu się nie zrozumieliśmy. Bo sądziłem, że kolor i rozmiar są na stałe przypisane do produktu, a jeśli nie są to zmienia postać rzeczy.
Co do tego co przekazujesz do Koszyka, to zależy jak uniwersalny kod ma być. Bo jeśli w koszyku chcesz mieć więcej rodzajów produktów przechowywać to nie możesz na sztywno ich właściwości przekazywać, tylko obiekt z tymi właściwościami, wtedy wystarczy że konkretny rodzaj dziedziczy po produktach i jest już dobrze.
Tylko trzeba umożliwić sobie identyfikacje typu produktu wyjętego z koszyka, aby móc specyficzne właściwości pobrać, choć też nie do końca, bo przy wyświetlaniu zawartości wyświetla się tylko to co mają wszystkie produkty, a jak się wejdzie w opis specyficznego to wtedy na podstawie id można rozpoznać typ, choć to akurat zależy od konkretnej budowy relacji.

Co do koszyka w sesji to odpowiednie metody w obiekcie __sleep() i __wakeup(), wtedy też każda klasa produktów też by musiała mieć to wbudowane, aby swoje specyficzne wartości odtworzyć.
Choć może to że próbuję to upakować w obiekty nie jest łatwiejsze/najlepsze rozwiązanie.

P.S. Jest specjalne metody aby sprawdzić ilość i zawartość argumentów przekazywanych do funkcji/metody.
Olimpia_ona
Na jednym z forów Pan o nicku 123456 napisał fajną klasę, którą chciałabym użyć, niestety nie działa ona w php wersji 4 tylko pod wersję 5. Wyskakuje mi błąd:
Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}''

  1. <?php
  2. class koszyk {
  3.  
  4. $zawartosc = Array(); 
  5.  
  6. // -------------  
  7. function dodaj($goods)
  8. {
  9. $this->zawartosc[] = $goods; 
  10. }  
  11. // ------------- 
  12. // (...) 
  13. // ------------- 
  14. function stan() 
  15. { 
  16. return $this->zawartosc; 
  17. } 
  18. // ------------- 
  19. // (...) 
  20. // ------------- 
  21. }
  22. ?>


Jak należało by ją zmienić?
rodzyn
Nalezaloby napisac do admina zeby zainstalowal PHP5 bo obciach smile.gif
Po co sie meczyc z OOP w PHP4 skoro w pelni go nie obsluguje? o_O
Olimpia_ona
Na serwerze jest PHP5, ale zanim coś tam wrzuce, to robie lokalnie na krasnalu, który ma php4. Próbowałam zainstalować PHP5, ale zaczeło mi wywalać jakieś błędy i musiałam odinstalować tą nakładkę. sad.gif
rodzyn
Proponuje: Wamp5
Nightmare
W kransalu klikasz prawym na ikonkę apache (zielone piórko) -> ustawienia -> php -> php5 i już masz php5 na krasnalu 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.