Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Destruktor wykonuje się za wcześnie.
kazaa9
post
Post #1





Grupa: Zarejestrowani
Postów: 13
Pomógł: 0
Dołączył: 30.05.2007
Skąd: Wędzina

Ostrzeżenie: (0%)
-----


Witam.

Mam dziwny problem z destruktorami i nie za bardzo wiem jak go rozwiązać. Przeglądałem trochę forum i manuala, ale nic w podobnym stylu nie było.

Oto opis mojego problemu: mam prosty systemik, w którym mam m. in. klasy DB (obsługa bazy danych, śle zapytania i przechowuje informacje o ewentualnych błędach) oraz Session (jak sama nazwa mówi - do obsługi sesji).

W klasie Session w destruktorze wywołuję metodę, która kończy mi daną sesję, czyli przy pomocy klasy DB robi UPDATE danych w bazie. Działa, jednak...no właśnie. Gdybym w klasie DB miał destruktor, w którym kończyłbym połączenie z bazą danych, to to zapytanie już wygeneruje błąd, czyli tak jakbym był rozłączony. Dodam jeszcze, że później pobieram sobie pewną metodą informacje o zapytaniach (klasa DB) i brakuje tego ostatniego zapytania kończącego sesję (teraz oczywiście rozważam wersję bez zakończonego połączenia).

Aha, jeszcze dodam (może to mieć jakiś związek - tak przypuszczam), że obiekty pobieram przy pomocy czegoś w stylu rejestru, tzw. ClassLoader'a.
Załączę odnośniki do kodów klas. Na logikę i angielski proszę na razie nie zwracać uwagi - poprawki wprowadzam na bieżąco (IMG:style_emoticons/default/winksmiley.jpg)
session.class.php
db.class.php
classloader.class.php
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
LBO
post
Post #2





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Przez lata programiści nauczyli się nie ufać destruktorom w PHP. Sprawiały mnóstwo problemów (wystarczy poczytać komentarze w odpowiednim rozdziale manuala). Istnieje obejście tego problemu, dosyć szeroko stosowane w wielu frameworkach - swój własny wirtualny system zarządzania obiektami.


  1. class ApplicationManager
  2. {
  3. protected $managers = array();
  4.  
  5. public function registerManager(IManager $manager)
  6. {
  7. $this->managers[] = $manager;
  8. }
  9.  
  10. public function start()
  11. {
  12. // number of registered managers
  13. $norm= count($this->managers);
  14. for($i = 0; $i < $norm; $i--)
  15. {
  16. $this->managers[$i]->start();
  17. }
  18. }
  19.  
  20. public function stop()
  21. {
  22. // number of registered managers
  23. $norm= count($this->managers);
  24. for($i = $norm - 1; $i >= 0; $i--)
  25. {
  26. $this->managers[$i]->stop();
  27. }
  28. }
  29. }
  30.  
  31. interface IManager
  32. {
  33. public function start();
  34. public function stop();
  35. }
  36.  
  37. class SessionManager implements IManager
  38. {
  39. public function start()
  40. {
  41. // ustawiasz sobie sterownik sesji
  42. }
  43.  
  44. public function stop()
  45. {
  46. //zamykasz sesję
  47. }
  48. }
  49.  
  50.  
  51. class DatabaseManager implements IManager
  52. {
  53. public function __construct($dsn)
  54. {
  55. // łączysz się z bazą
  56. }
  57.  
  58. public function start() {}
  59.  
  60. public function stop()
  61. {
  62. // zamykasz połączenie z bazą
  63. }
  64. }


A wykorzystujesz to mniej więcej tak.

  1. $application = new ApplicationManager();
  2.  
  3. // dalej pobierasz konfig aplikacji i tworzysz na jego podstawie potrzebne obiekty m.in. obiekty odpowiedzialne za sesje i połączenie z bazą danych.
  4.  
  5. $database = new Database($config['database']['dsn']);
  6.  
  7. $application->registerManager($database);
  8.  
  9. $session = new SessionManager();
  10.  
  11. $application->registerManager($session);
  12.  
  13. $application->start(); // wszystkie zarejestrowane obiekty wykonują własne metody start()
  14.  
  15. // etc
  16.  
  17. $application->stop(); // wszystkie zarejestrowane obiekty wykonują własne metody stop(). Zwróć uwagę, że robią to w odwrotnej kolejności niż zostały zarejestrowane. To jest ważne - pozwala zachować zależności.
  18.  


Wszystko pisane z palca, więc jakby co poprawiać lub pytać (IMG:style_emoticons/default/smile.gif)

Pozdrawiam

Cytat(kazaa9 @ 16.08.2009, 18:58:01 ) *
Też racja.

Ale nawet nie o to mi chodziło. Chciałbym uzyskać odpowiedź na temat tego destruktora, dlaczego to nie działa. W sumie jakoś pracy szczególnie nie utrudnia, ale bywa w małym stopniu irytujące, gdyż (moim zdaniem) powinno wszystko działać.


O ile sam nie usuwasz obiektów robi to samo PHP przy zakończeniu skryptu - a wtedy nie możesz być 100%-owo pewny kolejności. Rozwiązanie powyżej.

Ten post edytował LBO 16.08.2009, 18:44:58
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 11.06.2026 - 02:26