![]() |
![]() ![]() |
![]() |
![]() ![]()
Post
#1
|
|
![]() Grupa: Zarejestrowani Postów: 87 Pomógł: 3 Dołączył: 15.08.2009 Ostrzeżenie: (0%) ![]() ![]() |
Witam, tworzę zalążek aplikacji, która będzie obsługiwać inne aplikacje.
Stanąłem nad jednym zagadnieniem, możliwe że moje ubytki wiedzy wiążą się z małym niedoinformowaniem. Otóż. Tworzę sobie loader całej aplikacji. Plik index.php wygląda miej więcej tak że wywołuje klasę EngineInit, a w niej funkcję EngineStart. W klasie EngineInit, w func EngineStart ładuję odpowiednie klasy, które własnie tworzę. Dopowiednio jest to obsługa sesji, obsługa debugowania aplikacji, obsługa aplikacji, obsługa baz danch i inne Problem polega na tym że chcę kożystać z tych obiektów tak:
Problem polega na tym że chcę użyć np. obiektu $conf w $db lub w $session i np. $db w $session.. Global nie działa ![]() Ma ktoś pomysł jak to rozwiązać? Proszę o naprowadzenie ![]() -------------------- "Zło do triumfu potrzebuje tylko tego, aby dobrzy ludzie nic nie robili" |
|
|
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 1 729 Pomógł: 346 Dołączył: 4.04.2009 Ostrzeżenie: (0%) ![]() ![]() |
Najprościej zastosować singletona http://phpedia.pl/wiki/Singleton tworzysz obiekt używając metody statycznej
-------------------- |
|
|
![]()
Post
#3
|
|
![]() Grupa: Zarejestrowani Postów: 87 Pomógł: 3 Dołączył: 15.08.2009 Ostrzeżenie: (0%) ![]() ![]() |
Czyli musiał bym to zrobić w taki sposób?
Ten post edytował zielu001 28.03.2012, 10:45:44 -------------------- "Zło do triumfu potrzebuje tylko tego, aby dobrzy ludzie nic nie robili" |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 1 729 Pomógł: 346 Dołączył: 4.04.2009 Ostrzeżenie: (0%) ![]() ![]() |
Tak, w tym momencie gdy obiekt już był gdzieś stworzony Singleton::getInstance(); zwraca ci ten stworzony obiekt. Teraz tylko jedna instancja klasy będzie
-------------------- |
|
|
![]()
Post
#5
|
|
![]() Grupa: Zarejestrowani Postów: 87 Pomógł: 3 Dołączył: 15.08.2009 Ostrzeżenie: (0%) ![]() ![]() |
Niestety nie działa;
I wywala: Call to undefined method Singleton::query(); Jakiś inny pomysł ? -------------------- "Zło do triumfu potrzebuje tylko tego, aby dobrzy ludzie nic nie robili" |
|
|
![]()
Post
#6
|
|
![]() Grupa: Zarejestrowani Postów: 1 527 Pomógł: 438 Dołączył: 28.06.2011 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
A masz w ogóle tą metody query w Singleton?
![]() Nie może nie działać... najprostszy singleton wygląda mniej więcej tak:
Singleton do takich celów został stworzony - postaraj się go zastosować poprawnie - opłaci się ![]() -------------------- If you're good at something, never do it for free.
Potrzebujesz skryptu JS lub PHP - szukasz kogoś kto przetestuje twoją aplikację pod względem bezpieczeństwa? Szybko i solidnie? Napisz ;) Mój blog - Jak zwiększyć wydajność front-endu - O buforowaniu wyjścia w PHP słów kilka... |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
Koledze nie o to chodzi, czy i gdzie wykorzystać singleton. Jeśli nawet wykorzysta ten wzorzec, to nadal jego problem nie będzie rozwiązany.
@zielu001: Z Twojego opisu wynika, że klasa EngineInit jest niejako klasą główną, a metoda EngineStart ma zainicjować konfigurację, bazę danych i sesje, z których później będziesz korzystał. Jednak w kodzie, który nam pokazałeś tworzysz tylko zmienne lokalne, działające w obrębie metody EngineStart. Nie będziesz miał zatem możliwości posługiwania się nimi później. Dlatego klasa mogłaby/powinna wyglądać nieco inaczej:
Teraz przejdźmy do meritum. Jeśli obiekt klasy DatabaseLoader (i tutaj nieważne, czy jest to singleton, czy nie), czy też klasy SessionLoader musi skorzystać z danych zawartych w obiekcie klasy ConfigurationInit, to trzeba te informacje przekazać. Jak to zrobić? Otóż można posłużyć się "mechanizmem" DI (dependency injection, wstrzykiwanie zależności). Metoda EngineStart wyglądałaby zatem trochę inaczej:
Teraz konstruktory klas DataBaseLoader i SessionLoader mogą skorzystać z informacji, jakie "posiada" obiekt klasy ConfigurationInit. Gwoli dopełnienia formalności uzupełnijmy dla przykładu klasę DataBaseLoader:
Innym "mechanizmem" jest Dependency Non-Injection (uzależnianie bez wstrzykiwania). Mechanizm ten polega na zainicjowaniu "na sztywno" obiektu klasy, z której potrzebujemy skorzystać. Tak mogłaby wyglądać klasa DataBaseLoader wykorzystująca Dependency Non-Injection
O tym, który z przedstawionych mechanizmów wybrać musisz zdecydować sam. Dependency Injection daje nam sporą elastyczność, ponieważ przekazywane obiekty nie muszą być obiektami dokładnie jednej klasy, choć muszą spełniać założenia pewnych wzorców, które nazywamy interfejsami. Dependency Non-Injection samo w sobie nie zapewnia nam żadnej elastyczności i wymusza na nas korzystnie z dokładnie takiej, a nie innej klasy (czasami jednak właśnie tego potrzebujemy). Wszystkie napisane wyżej klasy, to tylko przykłady. W rzeczywistości konstruktor klasy obsługującej połączenie z bazą danych nie potrzebuje wszystkich danych konfiguracyjnych, a tylko niektórych (tzn. nazwa/adres serwera, nazwa i hasło użytkownika bazy danych, czy kodowanie połączenia). Wystarczyłoby zatem przekazać konstruktorowi klasy DataBaseLoader tablicę zawierającą wymagane dane, a nie cały obiekt klasy ConfigurtionInit. EDIT1: Poprawiłem parę literówek, ale chyba jeszcze jakieś są. EDIT2: Problem i jego rozwiązanie z dziedziczeniem nie mają nic wspólnego. Ten post edytował mortus 28.03.2012, 16:31:14 |
|
|
![]()
Post
#8
|
|
![]() Grupa: Zarejestrowani Postów: 87 Pomógł: 3 Dołączył: 15.08.2009 Ostrzeżenie: (0%) ![]() ![]() |
Można powiedzieć że o to mi chodziło, ale nie jestem do końca przekonany.
Jak widać chcę załadować wszystko w klasie głownej jak to nazwałeś i to jest racja. A potem w tych "pod klasach" ( czyli np. SessionLoader ) kożystać z tych innych "pod klas" załadowanych w głowej klasie "EngineInit"; Czyli coś takiego:
Ten post edytował zielu001 29.03.2012, 19:06:52 -------------------- "Zło do triumfu potrzebuje tylko tego, aby dobrzy ludzie nic nie robili" |
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
No przecież opisałem Ci dwa mechanizmy, przy czym jeśli chcesz korzystać z obiektów utworzonych w klasie "głównej" to nie masz wyboru i pozostaje Ci jedynie Dependency Injection:
|
|
|
![]()
Post
#10
|
|
![]() Grupa: Zarejestrowani Postów: 87 Pomógł: 3 Dołączył: 15.08.2009 Ostrzeżenie: (0%) ![]() ![]() |
Wiem, wiem, ale ja bym chciał bez podawania obiektu, ponieważ np. w jednej klasie będę potrzebował obsługi użytkownika, templatek, bazy danych, a w innej tylko bazy danych.. A tu musze podawać jako parametr, który tworzę. Będzie to też uciążliwe jeśli zrobię obsługę aplikacji, gdzie klasa aplikacji będzie ładowana automatycznie i nie będzie możliwości podania parametrów do konstruktora ponieważ będzie używana tylko funkcja startująca tą aplikację czyli jedna dla wszystkich.
// EDIT: Chyba się źle za to zabrałem.. Wymyślę coś innego. Ma ktoś jakiś pomysł? Jak napisać coś co będzie funkconalne ? ![]() Ten post edytował zielu001 29.03.2012, 20:48:17 -------------------- "Zło do triumfu potrzebuje tylko tego, aby dobrzy ludzie nic nie robili" |
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
Wiem, wiem, ale ja bym chciał bez podawania obiektu. Pytałeś, jak przekazywać obiekty jednej klasy obiektom innej klasy i jak korzystać z obiektów jednej klasy wewnątrz innej klasy, gdy obiekty obu klas są tworzone w metodzie jeszcze innej klasy. Tutaj nie masz wyjścia i musisz skorzystać z DI. Alternatywą jest Dependency Non-Injection, ale tam nie przekazujesz obiektów wcześniej utworzonych, a tworzysz zupełnie odrębne instancje tych obiektów. Dla przykładu klasa SessionLoader i EngineInit:
Opisane przeze mnie "mechanizmy" zastępują niejako słówko global, którego chciałeś na początku użyć. O tym, który z przedstawionych mechanizmów wybrać musisz zdecydować sam. Dependency Injection daje nam sporą elastyczność, ponieważ przekazywane obiekty nie muszą być obiektami dokładnie jednej klasy, choć muszą spełniać założenia pewnych wzorców, które nazywamy interfejsami. Dependency Non-Injection samo w sobie nie zapewnia nam żadnej elastyczności i wymusza na nas korzystnie z dokładnie takiej, a nie innej klasy (czasami jednak właśnie tego potrzebujemy).
|
|
|
![]()
Post
#12
|
|
![]() Grupa: Zarejestrowani Postów: 87 Pomógł: 3 Dołączył: 15.08.2009 Ostrzeżenie: (0%) ![]() ![]() |
No tak, a dało by się zrobić coś w rodzaju globalnego ( wszystkiego ) obiektu który przechowywał by wszystkie moje obiekty?
Albo stworzyć klasę która poprzez funkcję wskazywała by na inną klasę czyli użycie np.
Wtedy DI był by w sumie idealny. Ale jak zrobić w tym "pobierzKlasę("nazwa klasy")" aby nie tworzyło nowego obiektu tylko korzystało z już utworzonego ? -------------------- "Zło do triumfu potrzebuje tylko tego, aby dobrzy ludzie nic nie robili" |
|
|
![]()
Post
#13
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
// EDIT: Chyba się źle za to zabrałem.. Wymyślę coś innego. Ma ktoś jakiś pomysł? Jak napisać coś co będzie funkconalne ? ![]() Dependency Injection dzisiaj jest wykorzystywane praktycznie wszędzie. Natomiast Twój pomysł nie jest zły i jest podobny np. do Zend-owskich Bootstraperów, które na podstawie danych konfiguracyjnych (zazwyczaj z pliku .ini) "przygotowują" odpowiednie klasy do współdziałania z całą aplikacją. No tak, a dało by się zrobić coś w rodzaju globalnego ( wszystkiego ) obiektu który przechowywał by wszystkie moje obiekty? Albo stworzyć klasę która poprzez funkcję wskazywała by na inną klasę czyli użycie np.
Wtedy DI był by w sumie idealny. Ale jak zrobić w tym "pobierzKlasę("nazwa klasy")" aby nie tworzyło nowego obiektu tylko korzystało z już utworzonego ? To zależy od założeń Twojego projektu. Poczytaj o wzorcu FrontController, który poniekąd temu właśnie służy. Ten post edytował mortus 29.03.2012, 21:14:07 |
|
|
![]()
Post
#14
|
|
![]() Grupa: Zarejestrowani Postów: 87 Pomógł: 3 Dołączył: 15.08.2009 Ostrzeżenie: (0%) ![]() ![]() |
Chcę stworzyć szybki, dobrze zabezpieczony framework.
Mógł byś mnie naprowadzić jak najlepiej było by to napisać? Oczywiście robię to aby się czegoś ciekawego nauczyć. -------------------- "Zło do triumfu potrzebuje tylko tego, aby dobrzy ludzie nic nie robili" |
|
|
![]() ![]() |
![]() |
Aktualny czas: 20.08.2025 - 13:05 |