Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Bufor komunikatów w singletone
Forum PHP.pl > Forum > Przedszkole
JohnySpot
Na stronie internetowej np. w trakcie rejestracji sprawdza się różne ciekawe rzeczy.
Zazwyczaj buforowałem w jakiejś zmiennej wszystkie komunikaty błędów a później ją wyświetlałem i czyściłem jej zawartość. To dziłało jak tymczasowy bufor zmiennej, działało naprawdę super smile.gif

Później kiedy się dowiedziałem o funkcjach statycznych pisałem sobie taką funkcję:
  1. <?php
  2. function ($error, $co) {
  3.  static $bledy;
  4.  if ($co == 'add') {
  5. $bledy .= '<li>'.$error.'</li>';
  6.  } elseif ($co == 'show') {
  7. echo $bledy;
  8. $bledy = NULL;
  9.  }
  10. }
  11. ?>


No i to sobie działało. Dziś chciałbym to samo zamknąć w klasie. Mam 5 klas, które mogą zwracać różne komunikaty błędów. Więc klasę "strona" zrobiłem jako singletone:
  1. <?php
  2. /**
  3. * Konstruktor wywołuje singletone mysql-a.
  4. * Zabezpieczenie przed tworzeniem obiektów tej klasy.
  5. *
  6. * @access private
  7. */
  8.  protected function __construct() {
  9. $this->mysql = mysql::singletone();
  10.  }
  11.  
  12.  /**
  13. * Funkcja odopowiedzialna zazwracanie referencji do obiektu (singletone).
  14. *
  15. * @access public
  16. * @static
  17. * @return &singletone
  18. */
  19.  public static function &singletone() {
  20. if (self::$singletone == NULL) {
  21. self::$singletone = new strona();
  22. }
  23. return self::$singletone;
  24.  }
  25. ?>


A metody odpowiedzialne za wszystko wyglądają tak:

  1. <?php
  2. public function error($error) {
  3. $error = '<li>'.$error.'</li>';
  4. $this->error .= $error;
  5.  }
  6.  public function show_error() {
  7. return $this->error;
  8. $this->error = NULL;
  9. self::$singletone->error = NULL;
  10.  }
  11. ?>


I to :/ nie działa. To z tym slef dodałem, bo średnio qmam o co chodzi z tym self. W każdym bądź razie do klasy zupełnie innej w konstruktorze dodaje singletona klasy "strona". Obiekt się tworzy.Nie wiem o co dokładnie chodzi ale może powiem jaki jest efekt. Albo komunikat pojawia się dwa razy ! Albo raz, ale na pewno nie czyści się. To znaczy cały czas ten error jest mimo wyczyszczenia zmiennej do NULL.

Chodzi mi o to aby uzyskać efekt podobny jak sesja tylko, że w klasie. Czyli, żeby klasa nie gubiła wartości swoich zmiennych i była dostępna w innych klasach.
matipl
wklej proszę cała klasę, bo nie wiem jak się ona nazywa. W jednym miejscu piszesz że "strona", a w metodzie konstruktora masz jakieś mysql.
JohnySpot
Wkleje dwie przykładowe klasy:

  1. <?php
  2. /**
  3.  * Plik zawierający implementacje klasy strona
  4.  * Klasa służy do pokazywania komunikatów o błędach i debugowania
  5.  *
  6.  * @author JKJK
  7.  * @version 1.0
  8.  * @subpackage klasy
  9.  * 
  10.  */
  11.  
  12. class strona {
  13.  
  14.  /**
  15. * Zmienna przechowuje komunikaty wszystkich błędów.
  16. *
  17. * @access private
  18. */
  19.  private $error;
  20.  
  21.  /**
  22. * Zmienna przechowuje komunikaty wszystkich błędów.
  23. *
  24. * @access private
  25. */
  26.  private $info;
  27.  
  28.  /**
  29. * Zmienna przechowuje referencję do MySQL-a
  30. *
  31. * access protected
  32. */
  33.  protected $mysql;
  34.  
  35.  /**
  36. * Zmienna odpowiedzialna na singletone klasy
  37. *
  38. * @access protected
  39. */
  40.  protected static $singletone = NULL;
  41.  
  42.  
  43.  /**
  44. * Konstruktor wywołuje singletone mysql-a.
  45. * Zabezpieczenie przed tworzeniem obiektów tej klasy.
  46. *
  47. * @access private
  48. */
  49.  protected function __construct() {
  50. $this->mysql = mysql::singletone();
  51.  }
  52.  
  53.  /**
  54. * Funkcja odopowiedzialna zazwracanie referencji do obiektu (singletone).
  55. *
  56. * @access public
  57. * @static
  58. * @return &singletone
  59. */
  60.  public static function &singletone() {
  61. if (self::$singletone == NULL) {
  62. self::$singletone = new strona();
  63. }
  64. return self::$singletone;
  65.  }
  66.  
  67.  /**
  68. * Metoda dopisuje komunikat błędu będący parametrem do istniejących komunikatów błędu.
  69. *
  70. * @access public
  71. * @param string error
  72. */
  73.  public function error($error) {
  74. $error = '<li>'.$error.'</li>';
  75. $this->error .= $error;
  76.  }
  77.  
  78.  /**
  79. * Metoda dopisuje komunikat informacji będący parametrem do istniejących komunikatów informacji.
  80. *
  81. * @access public
  82. * @param string info
  83. */
  84.  public function info($info) {
  85. $info = '<li>'.$info.'</li>';
  86. $this->info .= $info;
  87.  }
  88.  
  89.  /**
  90. * Metoda pokazuje informacje użteczne przy debugowaniu
  91. *
  92. * @access public
  93. */
  94.  public function debug() {
  95. echo '<div class="debug"><b>Last MySQL error:</b> '.$this->mysql->error.'<br /><b>Last MySQL query:</b> '.$this->mysql->last_query().'</div>';
  96.  }
  97.  
  98.  /**
  99. * Metoda zwraca komunikat informacji i czyści zawartość zmiennej info.
  100. *
  101. * @access public
  102. * @return string info
  103. */
  104.  public function show_info() {
  105. return $this->info;
  106. $this->info = NULL;
  107. self::$singletone->info = NULL;
  108.  }
  109.  
  110.  /**
  111. * Metoda zwraca komunikat błędu i czyści zawartość zmiennej error.
  112. *
  113. * @access public
  114. * @return string error
  115. */
  116.  public function show_error() {
  117. return $this->error;
  118. $this->error = NULL;
  119. self::$singletone->error = NULL;
  120.  }
  121. }
  122. ?>


  1. <?php
  2. /**
  3.  * Plik zawierający implementacje klasy użytkownik
  4.  *
  5.  * @author JKJK
  6.  * @version 1.0
  7.  * @subpackage klasy
  8.  *
  9.  */
  10.  
  11. class uzytkownik {
  12.  /**
  13. * Zmienna odpowiada za obsługę błędów strony
  14. *
  15. * @access public
  16. * @var strona
  17. */ 
  18.  private $strona;
  19.  
  20.  /**
  21. * Zmienna przetrzymuje referencję do obiektu MySQL
  22. *
  23. * @access private
  24. * @var mysql
  25. */  
  26.  private $mysql;
  27.  
  28.  /**
  29. * Konstruktor ustawia singletona dla mysql
  30. *
  31. * @access public
  32. */ 
  33.  public function __construct() {
  34. $this->mysql = mysql::singletone();
  35. $this->strona = strona::singletone();
  36.  }
  37.  
  38.  /**
  39. * Funkcja sprawadza czy istnieją na komputerze ciasteczka
  40. * Pobiera dane z ciasteczek lub te wysłane z formularza
  41. * Wykonuje zapytanie SELECT do bazy danych
  42. * Sprawdza czy został zwrócony chociaż jeden rekord
  43. * Jeżeli tak zapisuje do sesji dane o użytkowniku
  44. * Kiedy ktoś prosił o zapamiętanie logowania w formularzu zapisuje ciasteczka
  45. *
  46. * @access public
  47. */
  48.  public function loguj() {
  49. $login = ($_COOKIE['autologin']) ? $_COOKIE['autologin'] : $_POST['login'];
  50. $haslo = ($_COOKIE['autopassw']) ? $_COOKIE['autopassw'] : md5($_POST['haslo']);
  51. if ($login != NULL) {
  52. $zapytanie = 'SELECT id, avatar, mail, admin FROM uzytkownicy WHERE nick = "'.@mysql_escape_string(htmlspecialchars($login, ENT_QUOTES)).'" AND haslo = "'.@mysql_escape_string(htmlspecialchars($haslo , ENT_QUOTES)).'";';  
  53. $wyniki = $this->mysql->query($zapytanie);
  54. if ($wyniki->num_rows) {
  55.  $rekord = $wyniki->fetch_assoc();
  56.  $_SESSION['nick'] = $login;
  57.  $_SESSION['id'] = $rekord['id'];
  58.  $_SESSION['avatar'] = $rekord['avatar'];
  59.  $_SESSION['mail'] = $rekord['mail'];
  60.  $_SESSION['admin'] = $rekord['admin'];
  61.  if ($_POST['autologowanie']) {
  62. setcookie ('autologin', $login, mktime(0,0,0,12,31,2012));
  63. setcookie ('autopassw', $haslo, mktime(0,0,0,12,31,2012));
  64.  }
  65.  $this->strona->info('Logowanie zakończone powodzeniem.');
  66. } else {
  67.  $this->strona->error('Logowanie nie powiodło się.');
  68. }
  69. }
  70.  }
  71.  
  72.  };
  73. ?>
raikou
Kod
public function show_info() {
          return $this->info;
          $this->info = NULL;
          self::$singletone->info = NULL;
}


Kod za instrukcją return nigdy nie zostanie wykonany, więc nigdy nie ustawisz tego NULLa. To samo dotyczy metody show_error().

Kod
public function show_info()
{
    $foo = $this->info;
    unset($this->info); $this->info = NULL;
    return $foo;
}
matipl
zgadzam się z @raiku. A co do kodu drogi @JohnySpot polecam całkowicie przepisać, bo nie rozumiesz idei wzorca Singleton. Mieszasz warstwy, zupelnie nie rozumiem sensu uzywania w taki sposob klasy strona i mysql w klasie Uzytkownik.
Pozatym nazw klasy piszemy z wielkiej litery. We wzorcu Singleton konstruktor powinien byc prywatny, a ty masz w klasie strona konstruktor jako protected.
JohnySpot
To może poproszę o jakiś dłuższy wywud bo oprócz tego że poczułem się głupi to nic nie zrozumiałem. Dziękuję za pomoc smile.gif pewnie zadziała (zaraz sprawdzę).
O idei singletona czytałm, ale używam go jenak trochę po swojemu. Mam dobre nawyki z C++ ale niestety w php :/ one nie działają tak jakbym chciał bo model obiektowy jest - jaki jest nie ma na co narzekać.

Będę bardzo wdzięczny jeżeli ktoś napisze co źle robię.
matipl
Nie podoba mi się, że bezpośrednio w klasie Uzytkownik używasz klasy Strona. Poniewaz wyglada niby to po nowemu (obiektowo) ale nie rozni sie w dzialaniu niczym od wczesnych wersji php gdzie nagminnie uzywalo sie zmiennych globalnych.
Moglbys postarac sie uzyc chociazby wzorca MVC. Co do bazy danych powinienes miec jakis kontener ktory zajmuje sie instertami, a Ty np. wywolujesz tylko odpowiednie metody w klasie Uzytkownik. Spojrz np. na DB_DataObject w PEAR-ze.
JohnySpot
@MatiPL:
Nie działam na globalach - ten argument uważam za czepianie się.
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.