Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Ładowanie plików
wlamywacz
post 21.09.2008, 16:05:39
Post #1





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

Ostrzeżenie: (20%)
X----


Witam. Jestem w trakcie projektowania swojego pierwszego poważnego framweworka którego mam zamiar używać w swoich aplikacjach. Struktura katalogów i plików jest identyczna jak w ZF czyli:
aplication
- controllers
- models
- views
library
public

Zastanawia mnie jak wykonać w takim systemie tzw. autoload? Myślałem nad stworzeniem dodatkowego kontrolera który przejmował by za mnie ten problem. Działało by to w to w ten sposób:
  1. <?php
  2.  
  3. $myClass = loader getInstance('aplication_models_myClass');
  4.  
  5. ?>

Loader ładował by potrzebny plik z odpowiednią klasą i zwracał jej obiekt. Jak wy rozwiązujecie taki problem ?

Psuje kod, miało być:
$myClass = loader::getInstance('aplication_models_myClass');

Ten post edytował wlamywacz 21.09.2008, 16:08:33
Go to the top of the page
+Quote Post
Crozin
post 21.09.2008, 20:03:53
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


W ZF nazwa klasy jest równocześnie ścieżką do jej źródła:
Zend_Sth_Sthelse_Qwert -> ./library/Zend/Sth/Sthelse/Qwerty.php
Możesz sobie tak napisać __autoload(), aby to było właśnie w ten sposób wczytywane.

Nie wiem co robi klasa Loader w ZF, ale z Twojego kodu wnioskuję, że jest to poprostu Rejest (Google: Registry design pattern)
Go to the top of the page
+Quote Post
LBO
post 21.09.2008, 20:12:38
Post #3





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

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


Zależy w którą stronę chcesz pójść z autoloaderem.

Jeżeli chcesz by było łatwo, ale sztywno to możesz stworzyć coś a'la Zend/PEAR autoloader

Jeżeli chcesz tak, żeby było trochę zachodu, ale za to multielastycznie to stwórz sobie coś w rodzaju konfiguracji, tam zapisuj ścieżki do plików względem projektu/frameworka dopasowane do nazw klas w tych plikach i potem użyj tego w autoloaderze.


Na forum jest jeden wilki wątek dotyczący autoloadera - poszukaj.
Go to the top of the page
+Quote Post
ARJ
post 21.09.2008, 20:19:59
Post #4





Grupa: Zarejestrowani
Postów: 453
Pomógł: 22
Dołączył: 20.09.2004
Skąd: Kraków - NH -

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


u mnie autoload opiera się na stworzonej mapie plików. używając __autoload() lub spl_autoload_register() ustawiam używanie mojego loadera. mapa klas jest tworzona za pierwszym użyciem lub gdy plik nie istnieje (update). później za pomocą nazwy klasy ładowany jest plik. oczywiście założeniem jest, że nazwa klasy to nazwa pliku.

jeżeli wzorujesz się na ZF to możesz stworzyć taki loader jak tam istnieje czyli nazwa pliku jest ścieżką do niego. niestety nazwy klas bywają długie ale za to wiadomo co i skąd się bierze.

jeżeli jesteś ciekawy mogę zaprezentować moją klasę loader`a. nie wklejam jej tutaj bo ostatnio jest problem na forum z "::", a klasa opiera się na metodach statycznych i kod może dziwnie wyglądać.


--------------------
Warsztat: Windows 7 Pro 64bit | Apache 2.2 | PHP 5.2 | MySQL 5.0 | PHPmyadmin 2.6.4
Go to the top of the page
+Quote Post
wlamywacz
post 21.09.2008, 20:27:57
Post #5





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

Ostrzeżenie: (20%)
X----


Jeśli mógłbyś to wkleić na phpfi byłbym bardzo wdzięczny. Jeśli chodzi o nazwę klasy jako ścieżkę do niej to przerabiałem to już w ostatnim systemie i podobało mi się to strasznie.

Crozin
Zapominasz że library to tylko klasy niezbędne a jeszcze do tego dochodzą modele w osobnych katalogach i klasy pomocnicze wykorzystywane tylko podczas testowania aplikacji. Robiłem to tak w poprzedniej aplikacji:
  1. <?php
  2. function __autoload($value) {
  3.  
  4. $url = str_replace("_", "/", $value);
  5.    
  6.    require_once 'libs/'.$url.'.class.php';
  7.    
  8. }
  9. ?>


Ten post edytował wlamywacz 21.09.2008, 20:30:52
Go to the top of the page
+Quote Post
ARJ
post 21.09.2008, 20:39:45
Post #6





Grupa: Zarejestrowani
Postów: 453
Pomógł: 22
Dołączył: 20.09.2004
Skąd: Kraków - NH -

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


proszę: http://phpfi.com/355575
klasa nie ma komentarzy ponieważ jest jeszcze ciepła. są do tego poprawki takie jak skanowanie kilku "folderów głównych", a nie tak jak teraz folderu lib (lub innego podanego) i jego podkatalogów.
użycie to np.
  1. <?php
  2. require('lib/hpLoader.php');
  3. function __autoload($classname){
  4.    hpLoaderautoLoad($classname);
  5. }
  6. ?>

w kodzie powyżej brak ::


--------------------
Warsztat: Windows 7 Pro 64bit | Apache 2.2 | PHP 5.2 | MySQL 5.0 | PHPmyadmin 2.6.4
Go to the top of the page
+Quote Post
LBO
post 21.09.2008, 20:44:14
Post #7





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

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


Temat o którym pisałem wcześniej: Włączanie plików + autoloader, chętnie bym posłuchał ciekawych pomysłów
Go to the top of the page
+Quote Post
wlamywacz
post 21.09.2008, 20:46:19
Post #8





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

Ostrzeżenie: (20%)
X----


Czytałem ten temat, dziękuje za klasę jutro ją przejrzę. Jestem chyba za tym aby robić mapę w pliku .ini i z niego pobierać dane.
Go to the top of the page
+Quote Post
likemandrake
post 21.09.2008, 21:31:10
Post #9





Grupa: Zarejestrowani
Postów: 175
Pomógł: 17
Dołączył: 23.06.2006

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


Ja kiedyś rozwiązałem ten problem w taki sposób:

Storzyłem sobie klasę Loader, która w konstruktorze wywoływała funkcję spl_autoload_register. Klasa zaraz po utworzeniu obiektu, sprawdzała czy we wskazanej lokalizacji znajduje się plik z cachem. Jeśli cache się znajdował, to wczytywał go, a w cache'u była zserializowana tablica, której kluczem była nazwa klasy, a wartością ścieżka do pliku z klasą.

W klasie (Loader) istniała metoda, przy której użyciu można było dodawać ścieżki z katalogami do klas, metoda ta przeszukiwała rekurencyjnie wskazany katalog w poszukiwaniu plików. Generalnie szukała na podstawie takiego schematu nazwy pliku: class.nazwa_klasy.php dla klasy, oraz interface.nazwa_interfejsu.php dla interfejsu. Na tej podstawie tworzyła się tablica o schemacie, o którym wspomniałem wyżej.

W destruktorze zawartość tablicy z klasami była serializowana i zapisywana do pliku (cache, o którym mowa wyżej). Istniała również metoda, dzięki której mogłem dodać sobie ręcznie jakąś klasę, np. coś z biblioteki PEAR. Do metody tej dostarczałem więc nazwę klasy oraz ścieżkę do klasy.

Proponuję również, dla zachowania pewnej zgodności wstecznej (a mianowicie, jeśli brakuje nam spl_autoload), do klasy Loader wstawić metodę, która po przekazaniu tylko i wyłącznie nazwy klasy, ładowałaby nam odpowiedni plik. Nię muszę chyba tłumaczyć, że wygodniejsze jest wklepanie "Loader::load('nazwa_klasy');" niż "require_once '/sciezka/do/klasy/class.nazwa_klasy.php';". To tyle smile.gif


--------------------
serwiswww.pl
Go to the top of the page
+Quote Post
zimi
post 22.09.2008, 16:21:27
Post #10





Grupa: Zarejestrowani
Postów: 233
Pomógł: 9
Dołączył: 3.06.2007

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


dorzuce może jeszcze swoje 3 grosze, w niektórych rozwiązaniach jest sugestia aby korzystać z określonego rozszerzenia np. class.php, że nazwa klasy była taka sama jak pliku, żeby ...

Ja zrobiłem klasę która mapuje wskazany katalog, z opcjonalną flagą o rekursywności mapowania:
tak wygląda przykładowy kod wykorzystujący klasę mapowania
  1. <?php
  2. require_once'core/MapaKlas.php';
  3. $obiekt = new MapaKlas();
  4. $obiekt->szukaj('.', FALSE);
  5. $obiekt->szukaj('core/');
  6. $obiekt->szukaj('modele/');
  7. $obiekt->szukaj('modul/');
  8. $obiekt->generujPlik();
  9. ?>

Tym kodem mapujemy zawartość wszystkich plików w katalogu głównym i rekursywnie wszystkie pliki w katalogach core, modele, modul i sprawdzamy tokenizerem PHP czy w pliku są klasy PHP i ew. jakie, tworząc tablicę asocjacyjną i generując całą klasą autoloadera... Tu w sumie trochę przesadziłem lepiej by chyba było serializować i odserializować dane w autoloaderze, ale zrobiłem jak zrobiłem

taki był mój pomysł, obróka tokenizerem nie była trudna, a dzięki niej jesteśmy niezależni czy ktoś ma jakieś swoje rozszerzenie php5, php6, php, php_cokolwiek biggrin.gif:P, czy ma 2 klasy w pliku czy cokolwiek innego, wszystko wyciąga tokenizer i przyporządkowuję klasę do pliku

Kod nie jest piękny, dość bałaganiarski tak mi się wydaję..., ale jeśli ktoś jest zainteresowany to podrzucę (możnaby rzec: mi działało smile.gif ), chciałem jedynie zasygnalizować ideę..., ja chwilowo staram się pracować z symfony więc klasy nie rozwijałem...
Go to the top of the page
+Quote Post
wlamywacz
post 22.09.2008, 18:00:58
Post #11





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

Ostrzeżenie: (20%)
X----


Nie rozumiem ? worriedsmiley.gif Właśnie o to chodzi że tak się nie da bo modele itp. mogą być rozsiane po kilka katalogach w różnych częściach aplikacji.
Go to the top of the page
+Quote Post
LBO
post 22.09.2008, 18:11:58
Post #12





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

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


Cytat(wlamywacz @ 22.09.2008, 19:00:58 ) *
Nie rozumiem ? worriedsmiley.gif Właśnie o to chodzi że tak się nie da bo modele itp. mogą być rozsiane po kilka katalogach w różnych częściach aplikacji.


Akurat modelami, kontrolerami/akcjami i widokami powinien zajmować się na pierwszym miejscu Dispatcher.

Wg mnie autoloader powinien być na tyle elastyczny, by być w stanie odszukać każdą klasę w projekcie. Najlepiej w tym przypadku działa rozwiązanie z mapą plików i klas w nich zawartych. Co za tym idzie, nie zgodzę się, że autoloader powinien zajmować się przeszukiwaniem katalogów. Od tego powinno być osobne narzędzie, które budowało w/w mapę na żądanie programisty (wyobrażacie sobie żeby w środowisku developerskim, przy każdym teście autoloader przeszukiwał katalogi?).

To w kwestii uniwersalnego autoloadera ofkorz.
Go to the top of the page
+Quote Post
wlamywacz
post 22.09.2008, 18:48:59
Post #13





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

Ostrzeżenie: (20%)
X----


Jednak załadowanie do nich odpowiednich plików musi się zając autoloader. Wybrałem jednak zrobienie po prostu mapy .ini wszystkich potrzebnych plików. Dziękuje za dyskusje w temacie
Go to the top of the page
+Quote Post
zimi
post 22.09.2008, 19:45:39
Post #14





Grupa: Zarejestrowani
Postów: 233
Pomógł: 9
Dołączył: 3.06.2007

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


Cytat
Właśnie o to chodzi że tak się nie da bo modele itp. mogą być rozsiane po kilka katalogach w różnych częściach aplikacji.

tak mogą być rozsiane w różnych częściach aplikacji... ale z góry możesz stwierdzić że nie będzie go np. w katalogu z obrazkami... dlatego aby skrypt nie przebijał się przez obrazki w poszukiwaniu klas, czy przez pliki innych dużych zbiorów plików

możesz jednak zapisać tylko:
  1. <?php
  2. $obiekt->szukaj('.');
  3. ?>

i mój skrypt przeszuka rekurencyjnie wszystko w katalogu bieżącym

zresztą to nie ma większego znaczenia... skrypt który podałem ma wykonać się tylko raz (gdy aplikacja przechodzi w tryb produkcyjny, w czasie tworzenia aplikacji można ją dołączyć do jakiegoś frontcontrolera) a plik, który wygeneruję jest autoloaderem który pozostaje już stały

jednym słowem ja mam 2 klasy:
- MapaKlas -> przeszukuje wg zaleceń "pliku konfiguracyjnego" którego przykład był poniżej, znajduje klasy, odczytuje jej nazwy i generuje klasę Autoloader'a
- Autoloader -> jak bedzie potrzebna klasa X wyszukuje klasę X w mapie i wczytuje

Cytat
Co za tym idzie, nie zgodzę się, że autoloader powinien zajmować się przeszukiwaniem katalogów.

Zdecydowanie, zbyt dużo czasu by to zajęło...

Cytat
Od tego powinno być osobne narzędzie, które budowało w/w mapę na żądanie programisty (wyobrażacie sobie żeby w środowisku developerskim, przy każdym teście autoloader przeszukiwał katalogi?).

Właśnie od tego jest moja MapaKlas, mówimy jej gdzie chcemy aby szukała (tylko dlatego żeby skrócić czas oczekiwania, bo wiemy że niektórych katalogów nie warto w ogóle otwierać, np. w /download/, /images/, /javascript/, /css/ klas PHP na pewno nie znajdziemy...)
reszta plików niezależnie od rozszerzenia może być otwarta i dokładnie przeszukana tokenizerem PHP w celu znalezienia nawet wielu klas w jednym pliku...
Go to the top of the page
+Quote Post
wlamywacz
post 22.09.2008, 19:57:23
Post #15





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

Ostrzeżenie: (20%)
X----


Doszliśmy już do tego rozwiązania smile.gif I właśnie je wykorzystam tyle że raczej mapę będę robić sam.
Go to the top of the page
+Quote Post
LBO
post 22.09.2008, 20:08:23
Post #16





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

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


Jeżeli w Twoim systemie masz podział na środowiska (czyli możesz uruchomić na tej samej aplikacji zarówno środowisko developerskie jak i produkcyjne) spróbuj to połączyć z tą mapą. Wyjdzie to Tobie na dobre.

W Agavi, nieraz to wykorzystuje np. modelami. Czasami testowo podmieniam sobie modele (modele są abstrakcja na warstwą bazodanową) na developerskim z używających Propela na czyste PDO (żeby zobaczyć, czy opłacalne).

I tak mogę mieć 2 klasy PostModel - pierwsza w pliku PostModel.class.php, a druga w PostModelPDO.class.php ładujące się w zależności od środowiska.

Ten post edytował LBO 22.09.2008, 20:10:20
Go to the top of the page
+Quote Post
likemandrake
post 22.09.2008, 20:13:30
Post #17





Grupa: Zarejestrowani
Postów: 175
Pomógł: 17
Dołączył: 23.06.2006

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


LBO, mam rozumieć, że stworzyłeś sobie klasę, która jest odpowiedzialna tylko i wyłącznie za generowanie mapy i na dodatek jest wywoływana kiedy ty tak naprawdę ją wywołasz? Druga klasa natomiast mam rozumieć, że jest odpowiedzialna za wczytanie tej mapy i pełnienie funkcji autoloadu?


--------------------
serwiswww.pl
Go to the top of the page
+Quote Post
LBO
post 22.09.2008, 20:21:45
Post #18





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

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


Cytat(likemandrake @ 22.09.2008, 21:13:30 ) *
LBO, mam rozumieć, że stworzyłeś sobie klasę, która jest odpowiedzialna tylko i wyłącznie za generowanie mapy i na dodatek jest wywoływana kiedy ty tak naprawdę ją wywołasz? Druga klasa natomiast mam rozumieć, że jest odpowiedzialna za wczytanie tej mapy i pełnienie funkcji autoloadu?


Nie mówię, że mam taką klasę generatora. Mówię, że to jest najnormalniejsze, przy swej prostocie, wyjście.

Osobiście wolę sam sobie pisać te mapy. Dodatkowo nie trzeba się ograniczać tylko do jednej - mogę sobie stworzyć stałą mapę z klasami frameworka, baaa, mogę sobie napisać mapę klas OM z Propela, a generować tylko wąską część z projektu.

Nie zapominaj też autoloaderach innych projektów. Używając Zenda, nie będę sobie generował mapy klas, tylko podłączę Zend_Loadera.

Ten post edytował LBO 22.09.2008, 20:22:37
Go to the top of the page
+Quote Post
Cysiaczek
post 22.09.2008, 21:29:45
Post #19





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Ja kiedyś popełniłem takie coś: http://kavuka.cal.pl/fsp/entry-2fa33a3605a...c85f1136b37.htm
autoloader.tar.gz. Nie mam do niego niestety dokumentacji i brakuje obsługi błędów, a rozgryzienie działania może chwilę zająć. Był stworzony raczej do ładowania bibliotek CORE mojego FW, więc obsługuje tylko jeden katalog - rekursywnie.
Działa jednak wyśmienicie. Oferuje dwie możliwości składowania mapy plików.
Pierwsza to array, druga to symlinki (oj, szybciej potrafi działać niż array - nawet o połowę). Jeśli pliku nie znajduje, automatycznie skanuje katalogi i jeszcze raz próbuje dołączyć plik.


Pozdrawiam.


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
LBO
post 22.09.2008, 22:42:04
Post #20





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

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


Cytat(Cysiaczek @ 22.09.2008, 22:29:45 ) *
druga to symlinki (oj, szybciej potrafi działać niż array - nawet o połowę).


Nie wiem jak z symlinkami (wierzę na słowo), ale o uszy mi się kiedyś obiło, że takie proste struktury warto trzymać w ini. Jestem skłonny uwierzyć, bo jednak ini jest łatwiej i szybciej sparsować.

Ten post edytował LBO 22.09.2008, 22:42:29
Go to the top of the page
+Quote Post

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

 



RSS Wersja Lo-Fi Aktualny czas: 28.04.2024 - 09:57