Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: OOP - pierwsze starcie
Forum PHP.pl > Forum > PHP > Object-oriented programming
netmare
Zacznę może od tego że nie rozumiem w ogóle idei ubierania w obiekty prostych kodów w języku tak elastycznym jak PHP, ale skoro tyle osób widzi w tym sens, to pewnie coś w tym jest i chciałbym wiedzieć co. Najlepszym chyba sposobem jest zaczęcie programowania obiektowego. Przeczytałem arty na gajdaw.pl, a poniżej pierwsze wypociny:

  1. <?php
  2. class session {
  3.  
  4. public static $tcookie='session_class_timestamp';
  5. public static $tsession='session_class_timestamp';
  6. public static $dsession='session_class.details';
  7. public static $visited='session_class.visited';
  8. public static $lifetime=600;
  9.  
  10.  
  11. protected function first(){
  12. }
  13.  
  14.  
  15. protected function next(){
  16. }
  17.  
  18.  
  19. protected function failed(){
  20. die();
  21. }
  22.  
  23.  
  24. private function simple(){
  25.  
  26. $hash=md5(@$_SERVER["HTTP_USER_AGENT"].$_SERVER["REMOTE_ADDR"]);
  27. if(isset($_SESSION[self::$dsession])){
  28.  
  29. if($_SESSION[self::$dsession]==$hash) return true; else return false;
  30.  
  31. } else {
  32. $_SESSION[self::$dsession]=$hash;
  33. return true;
  34. }
  35. }
  36.  
  37.  
  38. private function advanced(){
  39.  
  40. if(isset($_SESSION[self::$tsession]))
  41. if(!isset($_COOKIE[self::$tcookie]) || $_SESSION[self::$tsession]!==$_COOKIE[self::$tcookie])
  42. return false;
  43.  
  44. $timestamp=md5(microtime());
  45. $_SESSION[self::$tsession]=$timestamp;
  46. setcookie(self::$tcookie,$timestamp,time()+self::$lifetime);
  47. return true;
  48. }
  49.  
  50.  
  51. public static function start($advanced=false){
  52. ini_set('session.use_only_cookies','1');
  53. ini_set('session.cookie_lifetime',self::$lifetime);
  54. ini_set('session.gc_maxlifetime',self::$lifetime);
  55. $advanced_result=$advanced?self::advanced():true;
  56. if(!self::simple() || !$advanced_result)
  57. {
  58. self::failed();
  59. return false;
  60. } 
  61. else
  62. {
  63. if(!isset($_SESSION[self::$visited])) {self::first();$_SESSION[self::$visited]='1';} else self::next();
  64. return true;
  65. }
  66. }
  67.  
  68. }
  69. ?>


No i oczywiście pojawiły się problemy. Miało to działać tak (jeżeli mój tok myślenia odbiega od OOP to proszę o wyjaśnienia):
- klasa miała być uniwersalna żeby łatwo mogła współpracować z klasą odpowiedzialną na przykład za obsługę użytkowników
- w przypadku wywołania przez session::start(true) dodatkowym zabezpieczeniem miało być sprawdzanie czasu wykonania ostatniego wyświetlenia strony przez użytkownika.
- metody next i first miały być przeznaczone do przesłaniania aby dało się na przykład łatwo wpleść licznik odwiedzin (z tego co czytałem wasze posty klasa powinna odpowiadać za jakąś warstwę aplikacji i stąd ten pomysł), failed też miała być do ewentualnego przesłonięcia, ponieważ nie do końca wiem jak się ma private do przesłonięcia są zdefiniowane jako protected.

Przy wywołaniu statycznym jednak przesłanianie metod nie działa, a jak na moją logikę tworzenie obiektu w tym przypadku jest marnotrastwem zasobów i rozwiązaniem mniej estetycznym.

Jak można to ominąć i czy jeśli chodzi o logikę OOP to popełniam jakieś błąd??
Sedziwoj
Ze statycznymi rzeczami taki problem jest, ma być to zmienione, na późne wiązanie, ale chwilowo można o tym pomarzyć.
Co do wydajności, to bym nie był takim pesymistą.
Nie można też mówić o OOP kiedy mamy w użyciu jedną klasę.
Dodawaj też phpDoc to ułatwia czytanie co dana klasa ma robić, jak jej użycie w dobrym środowisku programistycznym.
netmare
No cóż, nie bardzo wiem co dalej z tym zrobić (nie jest mi ta klasa do niczego potrzebna, bardziej chodzi o sens OOP)
1. Przerobić klasę, aby wymuszała tworzenie obiektu i przysłaniać metody
2. Przerobić metody na pola logiczne first oraz failed i pozostawić możliwość ich kontroli z poziomu innej klasy,
3. Umieścić mechanizm odpowiadający za first i next w klasie odpowiadającej za usera, jednak pozostanie problem metody failed, który należy kontrolować wyjątkami (to by w sumie dało możliwość rozbudowy klasy), lub przez wartość zwracaną przez session::start()
4. Przy pomocy try szukać czy user zdefiniował funkcę o ustalonej nazwie (to chyba nie ma nic wpólnego z OOP winksmiley.jpg)
5. Zdefiniować te metody jako abstract, choć uniemożliwi to szybkie wykorzystanie klasy osobom które nie znają się na sesjach bądź OOP.
6. Przejść całkowicie na obsługę wyjątków, bądź jakiś skomplikowany sytem zwracanych wartości np. na flagi błędów w jakiejś reprezentacji tablicowej bądź binarnej, czy też pola pokazujące wszystkie możliwe stany.

Czy punkt 1 jest tutaj najlepszym rozwiązaniem?
ayeo
Na początek połącz to z handlerem sesji session_set_save_handler(); Wtedy ze swojej sesji korzystasz tak jak ze zwykłej natywnej sesji z PHP....
netmare
Nie widzę potrzeby zmiany sposobu zapisu sesji, bo ten oryginalny jak na moje potrzeby jest zupełnie wystarczający, jeśli się nie zostawi furtki do pliku sesji. A bardziej chodzi mi o OOP. Gdyby ktoś z Was miał jakiegoś świeżego programistę do dyspozycji i miałby wam napisać prostą klasę do obsługi sesji pod jakiś portal (na razie samo bezpieczeństwo sesji powiedzmy że do tego jeszcze dorzucenie sprawdzenia referer z nagłówka z ostatnio odwiedzonym URI w sesji), to jak ta klasa miałaby być obsługiwana później przez doświadczonego programistę o ile Wy w ogóle takie rzeczy wrzucacie w klasy.

Edit: to po prostu moja pierwsze w życiu podejście do OOP po ponad 15 latach przyzwyczajania się do myślenia proceduralnego czy tam strukturalnego i tak naprawdę póki co sens w OOP w PHP widzę w rozwiązaniach takich jak CURL, gdzie obiekt ma naprawdę olbrzymią ilość pól i sterowniki baz danych gdzie definiuje się uniwersalny interfejs a pod niego pisze się klasy do obsługi Postgresa albo MySQL. Natomiast w dziale gotowe rozwiązania widzę np klasę bodaj kolegi cysiaczka(jemu braku wiedzy napewno zarzucić nie mogę) PeselValidator, której w życiu nie napisałbym obiektowo bo nie widzę w tym sensu. Ponieważ prawda jest taka że wszystko da się napisać obiektowo i proceduralnie, chciałem napisać z Waszą podpowiedzią napisać kilka klas i połączyć je w jakąkolwiek aplikację. Tyle że jak napiszę to żeby napisać, to najwyżej wyjdzie z tego proceduralne ubrane w słowa kluczowe z obiektowego i w ten sposób napewno nie poznam uroków programowania obiektowego.
Sedziwoj
@netmare
Zaczynasz od czegoś, od czego nie powinieneś, bo klasa do obsługi sesji jest specyficzna, tak jak napisał ayeo lepiej od razu użyć session_set_save_handler(), bo to przysłania sposób działania, a nadal możesz użyć klasy do obsługi.
Jakbym zaczął jednak od innego problemu, bo na początek zazwyczaj lepiej zacząć od prostych rzeczy.
netmare
Dzięki w ogóle za zaintersowanie.

Nie łapę kwestii session handlerów, ani po co ich w ogóle użyć i dlaczego gdybym już chciał ich użyć to powinny być w tej klasie. Ale w takim razie chyba na razię odpuszczę kwestię klasy sesji.

Możesz podpowiedzieć mi co mogę spróbować napisać żeby to miało coś więcej wpólnego z OOP niż sterownik do bazy danych ?
Sedziwoj
Cytat(netmare @ 14.05.2008, 11:26:10 ) *
Nie łapę kwestii session handlerów, ani po co ich w ogóle użyć i dlaczego gdybym już chciał ich użyć to powinny być w tej klasie. Ale w takim razie chyba na razię odpuszczę kwestię klasy sesji.

Używasz ich, bo wtedy w projekcie możesz korzystać z tablicy $_SESSION a ona wykorzysta Twój mechanizm. Czyli takie niewidoczne korzystanie. Dlaczego używać obiektu, a nie po prostu funkcji, skoro i tak nie widać klasy, bo obiekt zamyka to wszystko w całość, czyli jak szukasz to w jednym miejscu. Do tego możesz tworzyć kreator różnych sesji, i w zależności od projektu przekazywać obiekt o zadanym interfejsie do kreatora, a on już podczepi pod hendler.
Cytat
Możesz podpowiedzieć mi co mogę spróbować napisać żeby to miało coś więcej wpólnego z OOP niż sterownik do bazy danych ?


Teraz nic mi nie przychodzi do głowy, oprócz rzeczy z pracy :|

EDIT nie odwróciłem znaczników cytatu
netmare
Teraz to mi rozjaśniłeś winksmiley.jpg
Generalnie sama funkcja session_set_save_handler(); jest mi znana tyle, że nie zrozumiałem co ayeo miał na myśli.

Popróbuję może trochę rozwinąć tą klasę i dołożyć do niej jakąś inną i może kiedyś coś z tego wyniknie winksmiley.jpg
Jeszcze jedno wpadło mi w sumie do głowy... tak w sumie na zapas... czy dobrze mi się wydaje, że klasa odpowiadająca za sejsę czy też taka odpowiadająca za użytkownika nie powinny być obsługiwane metodami statycznymi, ale powinny działać na obiekcie i do tego nie zezwalać na więcej niż jedną instancję (o ile dobrze zrozumiałem to co czytałem to nazywa się to singleton) ?
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.