Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: singleton - nie można pobrać instancji w klasach dziedziczonych
Forum PHP.pl > Forum > PHP
czychacz
problem polega na tym, że przy próbie uruchomienia skryptu dostaję błąd:
Cytat
Allowed memory size of 134217728 bytes exhausted (tried to allocate 43 bytes)

w projekcie stworzyłem 4 singletony. dwa z nich podczas tworzenia ustalają sobie jakieś parametry (ale to chyba nie jest ważne). dalej - w projekcie posiadam klasę "_controller". inne klasy mogą z niej dziedziczyć. gdy próbuję odpalić kod, który zawiera tworzenie obiektu $a (klasy "lol" dziedziczącej po "_controller"), dostaję wyżej wymieniony błąd.
poniżej klasa controller:
  1. class _controller{
  2.  
  3. protected $engine = null;
  4. protected $view = null;
  5. protected $db = null;
  6. protected $config = null;
  7.  
  8. public $defaultAction = 'index';
  9.  
  10. public function __construct(){
  11. $this->engine = _engine::getInstance();
  12. $this->view = _view::getInstance();
  13. $this->db = _db::getInstance();
  14. $this->config = _config::getInstance();
  15. }
  16.  
  17. }

a tu jeden z singletonów:
  1. <?php
  2.  
  3. class _view{
  4.  
  5. static private $instance;
  6. static public function getInstance(){
  7. if(is_null(self::$instance))
  8. self::$instance = new _view();
  9. return self::$instance;
  10. }
  11. private function __construct(){}
  12. private function __clone(){}
  13.  
  14. }
  15.  
  16. ?>

czy ktoś wie, w czym może być problem?
edit: dodam, że po wywaleniu kodu odpowiedzialnego za przypisanie zawartości w konstruktorze klasy "_controller" wszystko idzie normalnie. kod "getInstance" jest prawie taki sam w każdym singletonie (nie licząc nazwy klasy przy wywołaniu "new").
Sinevar
Spróbuj pokombinować z tymi ustawieniami (dodatkowo możesz wklepać zaklęcie, o ile siedzisz na unixie: ulimit -a):

  1. ini_get('memory_limit');
  2. memory_get_peak_usage();


- na początku sprawdziłbym coś takiego

  1. public function __construct()
  2. {
  3. $this->engine = _engine::getInstance();
  4. $this->view = _view::getInstance();
  5. $this->db = _db::getInstance();
  6. $this->config = _config::getInstance();
  7. }


- potem wywaliłbym linijkę z $this->db (może jakiś ORM wyżera Ci pamieć)
- potem przeszukałbym kod, głównie pętle foreach, możę tam jest jakis memory leak
- potem popróbowałbym zwiększyć limit pamięci z poziomu php

  1. ini_set('memory_limit', -1);
  2. ini_set('memory_limit', "192M");


Generalnie baw się i próbuj, możesz nawet zapiąc xdebuga, albowiem jest to odpowiednia do tego sytuacja smile.gif
czychacz
problem jest chyba gdzieś indziej. zacząłem pisać nowy projekt i wszystkie klasy są prawie puste. np. klasy _db i _view mają tylko zmienną przechowującą instancję i metody pobierające tą instancję.
próba zwiększenia limitu pamięci nawet do 192 MB kończy się tym samym. ten kod nie pozwala także wyświetlić użycia pamięci.
w całym kodzie są tylko 2 pętle (foreach, konstruktor klasy _config, przetwarza on plik ini).

temat do zamknięcia. poradziłem sobie - okazało się, że w konstruktorze klasy _controller wywoływałem pobieranie instancji, która jeszcze nie została utworzona a sam obiekt klasy _controller był tworzony w konstruktorze klasy _engine. fakt - był to rodzaj pętli tongue.gif
bastard13
Taki offtopic.
A dlaczego chcesz tutaj koniecznie mieć singletony?
Rozumiem, że każda dziedzicząca klasa ma posiadać takie same (a dokładniej - te same) atrybuty. Ja bym zrobił coś takiego:
  1. class _controller{
  2.  
  3. protected static $engine;
  4. protected static $view;
  5. protected static $db;
  6. protected static $config;
  7.  
  8. public function __construct()
  9. {
  10. if (is_null(self::engine))
  11. $this->init();
  12. }
  13.  
  14. private function init()
  15. {
  16. self::engine = new _engine();
  17. self::view = new _view();
  18. self::db = new _db();
  19. self::config = new _config();
  20. }
  21.  
  22. }

Atrybuty są statyczne, czyli dotyczą każdej klasy rozszerzającej rodzica. init() jest wywoływany tylko raz, gdy atrybuty jeszcze nie zostały zainicjalizowane. Dodatkowo unikasz tworzenia singletonów, co jest z pewnością na plus:)
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.