Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Zasady pisania na forum Pro

Tematy na forum Pro mogą zakładać jedynie moderatorzy. W otwartych tematach może pisać każdy, kto ma coś fachowego do powiedzenia. Wszystkie posty nie wnoszące nic do tematu będą natychmiast usuwane, a ich autorzy dostaną ostrzeżenie.
Jeśli uważasz, że jakiś temat jest warty dyskusji na tym forum, zgłoś go w temacie Propozycje.

10 Stron V   1 2 3 > »   
Reply to this topicStart new topic
> Włączanie plików + autoloader, chętnie bym posłuchał ciekawych pomysłów
hawk
post 10.02.2005, 17:23:52
Post #1





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


Problem stary jak świat: system wymaga włączenia sporej liczby plików i zarządzanie tym jest upierdliwe. Do tego nie należy włączać więcej kodu niż potrzeba, a najlepiej zrobić jakieś lazy load.

Oczywiście, technik jest wiele:

1) require_once rozsiane po plikach, najlepiej poprzedzone jakąś stałą, np. require_once ROOT_DIR . '/foo/Foo.class.php';

2) Prado: deklarujemy namespacy - np. za pomocą funkcji using(), co dodaje nam ścieżki do include_path, a potem niech php znajdzie klasę.

3) Autoloader + mapa (nazwa klasy => ścieżka do pliku); autoloader wczytuje mapę i na jej podstawie jest w stanie znaleźć każdą klasę

Są jeszcze jakieś inteligentne sposoby? Dobry mechanizm powinien być odporny na "przemeblowanie" struktury plików (np. chcemy połączyć kilka klas w jeden plik).

BTW, włączanie plików bez klas (tylko funkcje i kod) jest gorsze, bo nie ma tego czegoś, czego można szukać po plikach... kolejna zaleta OOP? winksmiley.jpg
Go to the top of the page
+Quote Post
DeyV
post 10.02.2005, 21:46:51
Post #2





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Aby sprawę jeszcze bardziej skomplikować - warto pamietać o tym - że require_once i inlude_once jest w rzeczywistości bardzo wolne = każde wywołanie tych funkcji, nawet jeśli tym razem NIE MUSIAŁA ona ładować tego pliku, bo już był załadowany wcześniej, trwa niemal tyle samo, co require()
proste porównanie:
http://www.phpinsider.com/smarty-forum/viewtopic.php?t=4323
I choć, jak ktoś to zauwazył w tym wątku, fizyczny zysk czasu jest niewielki, to jednak procentowo - różnica jest ogromna.


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
Imperior
post 11.02.2005, 18:39:48
Post #3





Grupa: Zarejestrowani
Postów: 105
Pomógł: 0
Dołączył: 16.10.2004

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


Myślę, że moje rozwiązanie pomoże Ci, jeśli wpadniesz na jakiś dobry pomysł, to daj znać:
(nawiasem mówiąc każda klasa przekłada się na lokalizację w ten sposób:
Projekt_Podgrupa_Costam -> /packages/projekt/podgrupa/projekt_podgrupa_costam.php
zdecydowałem się na to, aby każdy plik miał pełną nazwę klasy, a instalator tworzył pakiety klas.)
Plik poza_drzewkiem/packages/noname/noname_package.php
  1. <?php
  2. define('NN_SEP', DIRECTORY_SEPARATOR);
  3. define('NN_LIB', dirname(dirname(__FILE__)).NN_SEP);
  4. define('NN_PRIVATE', dirname(NN_LIB).NN_SEP);
  5.  
  6. function __autoload($sName) {
  7. if (!(CORE :: Import($sName) || CORE :: ImportEx($sName))) {
  8. echo 'Kaboooom! Reason? '.$sName.' not found!!!';
  9. }
  10. }
  11.  
  12. class CORE {
  13. public static function Import($sName, $sFind = null, $bSearch = true) {
  14. if (!isset($sFind)) {
  15. $sFind = $sName;
  16. }
  17. if ($bSearch && (class_exists($sFind, false) || interface_exists($sFind, false))) {
  18. return true;
  19. }
  20. $sName = strtolower($sName);
  21. $aArr = explode('_', $sName);
  22. array_pop($aArr);
  23. $sPath = NN_LIB.implode(NN_SEP, $aArr).NN_SEP.$sName.'.php';
  24. if (is_readable($sPath)) {
  25. include_once ($sPath);
  26. if ($bSearch && !(class_exists($sFind, false) || interface_exists($sFind, false)) ) {
  27. return false;
  28. }
  29. return true;
  30. }
  31. return false;
  32. }
  33.  
  34. public static function ImportEx($sName) {
  35. $aArr = explode('_', $sName);
  36. array_pop($aArr);
  37. array_push($aArr, 'package');
  38. if (CORE :: Import(implode('_', $aArr), $sName) || CORE :: Import($sName)) {
  39. return true;
  40. }
  41. return false;
  42. }
  43. }
  44. ?>


(zamiast kaboom w __autoload() będzie komunikat o tym, że strona nieczynna i próba poinformowania admina)

Pliki *_package.php zawierają zlepek klas najczęściej wykorzystywanych w danym pakiecie (noname_package.php zawiera noname_(core,timer,exception itp).php . )
ImportEx różni się tym, że najpierw spróbuje władować pakiet (czyli np. jak władowywyję jakąś usługę, dajmy SQL, to automatycznie mam wyjątki, klase do łączenia, klase do zapytań itp.)

Jeśli jestem pewien, że jakaś klasa/interfejs powinna być w systemie to poprostu z niej korzystam - jeśli nie jest władowana, to zrobi to autoload. (Klasa z pakietu nie musi sprawdzać innych z tego samego pakietu, najczęściej stosowana przeze mnie metoda)
Jeśli wgrywam usługę (auth, sql, cache...) to daję CORE::ImportEx, żeby wgrać pakiet.
Jeśli potrzebuję pojedynczą klasę to poprostu CORE::Import.

Obie funkcje Import i ImportEx zwracają true/false, czyli ustrzegają mnie przed wykorzystaniem nieistniejącej klasy, a co za tym idzie przed Fatal Error.
Przed próbą odczytania pliku oczywiście jest sprawdzenie, czy nie jest obecna już dana klasa/interfejs.


--------------------
Com powiedział, powiedziałem.
Go to the top of the page
+Quote Post
hawk
post 18.02.2005, 14:39:33
Post #4





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


@Imperior:

Dwie słabe strony tu widzę:

1) Wszystko musi siedzieć w 2 miejscach: NN_LIB i NN_PRIVATE, co utrudnia model działania typu "user ściąga pakiet, wrzuca gdzie mu się podoba i chce żeby to działało".

2) Nie da się tego połączyć z zewnętrznymi bibliotekami, tzn takimi, gdzie nie ty decydujesz o nazwach klas.

Za to podobają mi się dwie inne rzeczy:

1) Importowanie całych "pakietów".

2) Nazwa_Klasy niejako emuluje pakiety, których php nie ma (nie możesz zrobić $foo = new com.example.Foo).

A mi się coraz bardziej podoba mapa:
  1. <?php
  2. $map = array(
  3. 'MojaKlasa' => MY_DIR . 'foo/MojaKlasa.class.php',
  4. 'MojaInnaKlasa' => MY_DIR . 'bar/KilkaKlas.inc.php',
  5. 'MojaInnaKlasa2' => MY_DIR . 'bar/KilkaKlas.inc.php',
  6. 'Smarty' => SMARTY_DIR . 'Smarty.class.php',
  7. }
  8. ?>

Autoloader jest w tym momencie banalny. Takie mapy można nawet generować automatycznie przeszukując skryptem katalogi i parsując (tokenizując) pliki php. Można automatycznie łączyć mapy dostarczane z pakietami w jedną wspólną. Można dowolnie łączyć pliki w pakiety, wrzucać do jednego pliku, dzielić itd., a potem przegenerować mapę i dalej wszystko działa. Szczególnie podoba mi się to w kontekście trzymania "normalnej" hierarchii plików u siebie i dystrybuowania wszystkiego w jednym pliku po wycięci komentarzy i whitespaces.

Wada - trzeba ten głupi plik wczytać zanim autoloader cokolwiek zrobi sad.gif. I ciężko byłoby automatycznie wstawić stałe jak w przykładzie powyżej.
Go to the top of the page
+Quote Post
bela
post 18.02.2005, 15:03:36
Post #5


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

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


Ja mysle, zeby rozwiazac to na podobnej zasadzie jak w javie. Mianowicie :

Mamy metode import, ta zaś wczytuje plik/pliki jakie chcemy. Czyli robimy:

  1. <?php
  2. import('pl.bela.foo.bar.Bar');
  3. import('pl.bela.foo.*');
  4. ?>


W pierwszym przypadku wczyta klase Bar ktora jest w katalogu pl/bela/foo/bar/, a w drugim wczyta wszystkie klasy znajdujące się w katalogu pl/bela/foo, z wyjatkiem pl.bela.foo.bar.Bar bo informacja o tym ze taka klasa jest załadowa jest przetrzymywane w tablicy ( 2 posty wyzej jest wyjasnienie czemu smile.gif ).

Co do położenia katalogow pl/bela, net/php/smarty, nie przejmuje sie tym za bardzo, ponieważ są classpathy smile.gif

Aha, i nie definiuje package(); no bo po co winksmiley.jpg


--------------------
Go to the top of the page
+Quote Post
Imperior
post 18.02.2005, 20:17:07
Post #6





Grupa: Zarejestrowani
Postów: 105
Pomógł: 0
Dołączył: 16.10.2004

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


Cytat(hawk @ 2005-02-18 13:39:33)
Dwie słabe strony tu widzę:

1) Wszystko musi siedzieć w 2 miejscach: NN_LIB i NN_PRIVATE, co utrudnia model działania typu "user ściąga pakiet, wrzuca gdzie mu się podoba i chce żeby to działało".

2) Nie da się tego połączyć z zewnętrznymi bibliotekami, tzn takimi, gdzie nie ty decydujesz o nazwach klas.

ad 1. NN_LIB jest podrzędne do NN_PRIVATE. W NN_LIB są trzymane właśnie pakiety, dla mnie nie do pomyślenia jest coś takiego, że user wrzuca jakiś pakiet gdzie mu się żywnie podoba, zamiast tego jest Instalator, przez którego może ściągnąć pakiet, uploadować, wskazać na serwerze i na podstawie plików konfiguracyjnych w pakiecie wszystko jest pięknie i ładnie instalowane razem z weryfikacją zależności.

ad 2. Z pozoru... Jeśli pliki będą w NN_LIB to zostaną załadowane, jedynie musi być spełniony warunek, żeby nie miały '_' w nazwach... (a jeśli tak, to żeby były prawidłowo umieszczone, ale wtedy probelmu nie ma biggrin.gif )

Ciekawe z tymi mapami... a gdyby rozszerzyć je o jakieś wyrażenia regularne?


--------------------
Com powiedział, powiedziałem.
Go to the top of the page
+Quote Post
hawk
post 21.02.2005, 14:43:27
Post #7





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


@bela_666: Takie rozwiązanie na pewno pasuje do javy, ale czy pasuje do php? Wszystko rozbija się o wydajność. Trzeba te importy przeczytać, pozamieniać na slashe, znaleźć katalogi, wczytać pliki... Owszem, mamy classpath (tzn. include_path winksmiley.jpg), ale w php jest to kosztowna (IMHO, nie robiłem testów) opcja, bo szuka po dysku przy każdym requeście. A przecież nie pozbędziemy się bibliotek, które nie stosują się do naszego standardu (smarty, adodb, ...). Czyli classpath się rozrasta.

Do tego, w php opłaca się wczytywać tylko te pliki, które są niezbędne. W javie nie ma tego problemu, bo wczytujesz raz i masz spokój. W php starasz się zminimalizować ilość operacji dyskowych na jedno żądanie.

W javie importy i w ogóle pakiety są potrzebne, bo 2 klasy w różnych pakietach mogą mieć tą samą nazwę i nie jest to problem. W php taka sytuacja jest niedozwolona, więc i pakiety są niepotrzebne (tak naprawdę jest to zabronione właśnie dlatego, że nie ma pakietów, ale skutek jest ten sam).

W javie z importami jest jeden problem: w pewnym momencie robi się ich zbyt dużo i upraszczamy sobie życie pisząc import java.util.*. W php jest to nie do przyjęcia - za dużo niepotrzebnie włączanego kodu. Więc nie muszę się martwić o unikalność com.example.hawk, bo to i tak nic mi nie daje.

@Imperior: sens regexpów zależy od tego, czy będą one szybsze niż wymienienie wszystkich klas. Czyli od wydajności.

Podsumowując, idealnie chciałbym mieć:
- nie muszę w swoich plikach php pisać require_once, przypominać sobie gdzie są potrzebne klasy, oraz upewniać się że nie pominąłem potrzebnego interfejsu
- mogę obsługiwać zewnętrzne (nie moje) biblioteki tak samo (tzn też bez pamiętania o require_once smarty)
- mogę w trakcie developmentu zmienić strukturę moich plików z klasami, przenieść do innych katalogów, itd. bez poprawiania mojej aplikacji
- mogę zmienić coś w n-tej dystrybucji pakietu bez obawy, że kod użytkowników nie znajdzie mojej klasy
- włączane są tylko te klasy, które są aktualnie potrzebne, i narzut czasy wykonania jest minimalny
Go to the top of the page
+Quote Post
hawk
post 25.02.2005, 09:23:01
Post #8





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


@serafin: Możesz napisać więcej? Mi się zawsze wydawało że php nie pozwala na kropki w nazwie klasy. Tak bardzo mi się wydawało, że nigdy nie sprawdziłem. I czy to oznacza, że pełna nazwa klasy rzeczywiście brzmi System.Console.Out? Żeby autoloader mógł znaleźć klasę.

Bo problem z brakiem namespaces jest taki, że jak napiszemy $foo = new System.Console.Out, to php nie wie, że ma szukać klasy Out w System.Console, tylko szuka System.Console.Out.
Go to the top of the page
+Quote Post
Imperior
post 25.02.2005, 09:55:57
Post #9





Grupa: Zarejestrowani
Postów: 105
Pomógł: 0
Dołączył: 16.10.2004

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


Cytat(hawk @ 2005-02-25 08:23:01)
Bo problem z brakiem namespaces jest taki, że jak napiszemy $foo = new System.Console.Out, to php nie wie, że ma szukać klasy Out w System.Console, tylko szuka System.Console.Out.

A ściślej mówiąc to stara się odczytać stałe i połączyć je w jeden string.

Ja to zrozumiałem w ten sposób, że pisze kod, który zawiera błędy z punktu widzenia parsera php, a który jest parsowany, aby poprawić te błędy i dopisać jakieś includy itp.

Alternatywnie poprostu w kodzie jest coś jak:
uses 'System.Console.Out';
i to jest odczytywane, żeby do pliku wynikowego dodać includy.

serafin: czy coś w tym stylu miałeś na myśli?


--------------------
Com powiedział, powiedziałem.
Go to the top of the page
+Quote Post
Vengeance
post 25.02.2005, 11:42:46
Post #10





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


A co Wam się stanie gdy zamiast System.Out będzie System_Out ?
Czy warto stosować te wszystkie parsery/tokenizery czy co tam jeszcze (opóźniające czas wykonywania) aby wygrać "walke" z kropką ? smile.gif


--------------------
Go to the top of the page
+Quote Post
hawk
post 25.02.2005, 12:06:36
Post #11





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


Nic się nie stanie, poza utratą estetyki winksmiley.jpg. Chociaż kwestia "kropka czy kreska" nie jest tutaj podstawowa. Problem jest raczej w tym, że autoloader będzie szukał klasy System_Out, a nie klasy Out w pakiecie System. Czyli na braku pakietów. I na tym, że na pewno znajdą się biblioteki, gdzie kreska jest używana do czegoś innego, co może wprowadzić system w błąd.
Go to the top of the page
+Quote Post
Vengeance
post 25.02.2005, 12:31:22
Post #12





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


ale to jest php a nie java smile.gif

Co do autoloadera... co za problem zrobić jakiś explode po znaku _
i odpowiednio sprawdzić?


--------------------
Go to the top of the page
+Quote Post
hawk
post 25.02.2005, 12:48:42
Post #13





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


Co za problem? Sprawdzanie po zrobieniu explode jest kosztowne. Odwołanie do dysku, przemnożone przez ileś tam włączanych klas. A ja zakładałem sobie idealnie, że autoloader, jako "jądro jądra", musi być super szybki.

Żeby nie było że się czepiam: to nie jest zła metoda, na razie nie zakodowałem samemu nic mądrego (stąd ten wątek). Zawsze są zady i walety, ja tylko wymieniam słabe strony.
Go to the top of the page
+Quote Post
Seth
post 25.02.2005, 12:50:43
Post #14





Grupa: Przyjaciele php.pl
Postów: 2 335
Pomógł: 6
Dołączył: 7.03.2002

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


Troche to stary kod ale moze sie przyda:

  1. <?php
  2. define( 'INCLUDE_PATH', 'include/' );
  3.  
  4. /**
  5.  * Use this function to include classes in given namespace pattern
  6.  *
  7.  * @param $nsPattern string
  8.  * @return true if succed, false otherwise
  9.  */
  10. function Import( $nsPattern )
  11. {
  12. // Filter pattern namespace
  13. if ( preg_match( '/^[a-z0-9_]+(.[a-z0-9_]+){0,}(.*)?$/i', $nsPattern ) )
  14. {
  15. $nsPattern = str_replace( '.', '/', $nsPattern );
  16.  
  17. if ( preg_match( '/^(.*)/*$/', $nsPattern, $match ) )
  18. {
  19. $patch = INCLUDE_PATH.$match[1];
  20.  
  21. if ( $handle = opendir( $patch ) )
  22. {
  23. while ( false !== ( $file = readdir( $handle ) ) )
  24. {
  25. $i = 0;
  26.  
  27. if ( $file != '.' && $file != '..' && preg_match( '/^(.*).class.php$/', $file, $match ) )
  28. {
  29. $filePath = $patch.&#092;"/\".$file;
  30.  
  31. if ( file_exists( $filePath ) && is_file( $filePath ) && !class_exists( $match[1] ) )
  32. {
  33. require_once( $filePath );
  34.  
  35. $i++;
  36. }
  37. }
  38. }
  39.  
  40. closedir($handle);
  41. }
  42.  
  43. return ( $i ? 1 : 0 );
  44. }
  45. else
  46. {
  47. $className = substr( strrchr( $nsPattern, '/'), 1 );
  48. $filePath = INCLUDE_PATH.$nsPattern.&#092;".class.php\";
  49.  
  50. if ( file_exists( $filePath ) && is_file( $filePath ) && !class_exists( $className ) )
  51. {
  52. require_once( $filePath );
  53.  
  54. return 1;
  55. }
  56.  
  57. return 0;
  58. }
  59. }
  60.  
  61. // Wrong pattern
  62. return 0;
  63. }
  64. ?>


Wywolania:
Import( 'db.*' );
includuje wszystkie klasy z katalogu include_path.'db/'

Import( 'db.jakas_klasa' );
includuje klasy o nazwie jakas_klasa z katalogu db

Pliki z klasami musza miec w nazwie .class.php

Aha... pisany pod php 4, wiec bez autoloadera :/

Ten post edytował Seth 25.02.2005, 12:53:16
Go to the top of the page
+Quote Post
bela
post 25.02.2005, 12:55:30
Post #15


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

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


Seth, a czy te pregi nie spowalniają bardzo przy dużej ilości plików ?


--------------------
Go to the top of the page
+Quote Post
Seth
post 25.02.2005, 13:07:03
Post #16





Grupa: Przyjaciele php.pl
Postów: 2 335
Pomógł: 6
Dołączył: 7.03.2002

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


Jakies spowolnienie napewno jest ale za to mozna latwo zaincludowac kilka klas winksmiley.jpg
Go to the top of the page
+Quote Post
bela
post 26.02.2005, 00:02:23
Post #17


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

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


Cytat(hawk)
Podsumowując, idealnie chciałbym mieć:
- nie muszę w swoich plikach php pisać require_once, przypominać sobie gdzie są potrzebne klasy, oraz upewniać się że nie pominąłem potrzebnego interfejsu
- mogę obsługiwać zewnętrzne (nie moje) biblioteki tak samo (tzn też bez pamiętania o require_once smarty)
- mogę w trakcie developmentu zmienić strukturę moich plików z klasami, przenieść do innych katalogów, itd. bez poprawiania mojej aplikacji
- mogę zmienić coś w n-tej dystrybucji pakietu bez obawy, że kod użytkowników nie znajdzie mojej klasy
- włączane są tylko te klasy, które są aktualnie potrzebne, i narzut czasy wykonania jest minimalny


No chyba udało mi się to osiągnąć, mianowicie: tokenizer przejezdza po wszystkich katalogach i załączą pliki .php, a przy okazji pomija katalogi .svn ( coś się zawieszało winksmiley.jpg ), wyciąga nazwy klas/interfejsów i to gdzie one się znajdują, wciska to do tablicy i generuje piękny pliczek autoload.php, wraz z funckją __autoload.

No, to by było na tyle biggrin.gif


--------------------
Go to the top of the page
+Quote Post
Nievinny
post 26.02.2005, 09:35:42
Post #18





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

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


Jeśli mogę wtrącić trzy grosze, ja myślę, że można przejechać po katalogach czymś takim:
  1. <?php
  2.  
  3. $Dir = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( ROOT_PATH ), true );
  4. foreach( $Dir as $File ) {
  5. if( $File->getFilename() === $sFile ) {
  6. try {
  7. CORE::loadClass( $File->getPathname() );
  8. }
  9. catch( CoreExceptions $Error ) {
  10. print Debuger::errorDisplay( $Error );
  11. }
  12. break;
  13. }
  14. }
  15.  
  16. ?>

Tylko trzeba zdefiniować stała ROOT_PATH i dodać do nazwy rozszerzenie i zdefiniować klasę CORE.
Warunki:
  • nazwy klas musza byc takie same ja nazwy plikow (bez rozszerzenia) lub odwrotnie winksmiley.jpg
  • Może przy dużej ilości katalogów spowoli trochę, ale można dodać funkcje ładowania kilku klas i odrzucić katalogi smile.gif
Za jakiś czas dołącze dokładniejszy kod, może trochę wolnawe, ale samo znajdzie ścieżkę dostępu do plików smile.gif


--------------------
Go to the top of the page
+Quote Post
hawk
post 26.02.2005, 09:55:15
Post #19





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


@bela_666: pokaż pokaż pokaż tongue.gif
Go to the top of the page
+Quote Post
Vengeance
post 26.02.2005, 11:55:48
Post #20





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


Nievinny: jakbyś zrobił cache jakiś to ok. Teraz uważam, że to jest najgorsze z najgorszych rozwiązań smile.gif


--------------------
Go to the top of the page
+Quote Post
bela
post 26.02.2005, 12:21:14
Post #21


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

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


Cytat(hawk @ 2005-02-26 09:55:15)
@bela_666: pokaż pokaż pokaż tongue.gif

Heh, ale to dopiero brzydko wyglądający prototyp, ale ok biggrin.gif Pisałem, aby w ogóle działało winksmiley.jpg

  1. <?php
  2. error_reporting(E_ALL|E_STRICT);
  3. function get_microtime() {
  4. list($usec, $sec) = explode(&#092;" \",microtime());
  5. return ((float)$usec + (float)$sec);
  6. }
  7.  
  8. global $fileContext;
  9. $fileContext = array();
  10. $start = get_microtime();
  11. iterateDir('.'/*dirname(__FILE__)*/);
  12.  
  13. function iterateDir($path) {
  14. $di = new DirectoryIterator($path);
  15. foreach ($di as $k => $v) {
  16. // get extension
  17. $ext = end(explode('.', $v->getPathname()));
  18. // is svn dir
  19. $name = $v->getFilename();
  20. $first = substr($name, 0, 1);
  21. $first == '.' ? $dupa = false : $dupa = true;
  22.  
  23. // if is dir and not svn dir, iterate this dir;]
  24. if($v->isDir() && $dupa) {
  25. iterateDir($v->getPath() . '/' . $v->getFilename());
  26. }
  27. // print filename with path, with php extenstion
  28. if($dupa && $v->isFile() && $ext == 'php' && $v->getFilename() != 'tokenizer.php' && $v->getFilename() != 'test.php' && $v->getFilename() != 'config.php' && $v->getFilename() != 'dupa.php') {
  29. $GLOBALS['fileContext'][] = array($v->getPathname(), token_get_all(file_get_contents($v->getPathname())));
  30. //print $v->getPathname() . \"<br />n\";
  31. }
  32. }
  33.  
  34. }
  35.  
  36. //dump($fileContext);
  37. $classes = array();
  38. $key = 0;
  39. foreach($fileContext as $file) {
  40. static $i;
  41. foreach ($file as $c) {
  42. if(is_array($c)) {
  43. $a = false;
  44. foreach ($c as $k => $v) {
  45. if(is_array($v)) {
  46. if($v[0] == T_CLASS || $v[0] == T_INTERFACE) {
  47. $a = true;
  48. } elseif ($a && $v[0] == T_STRING) {
  49. $classes[] = array($v[1], substr($file[0], 2));
  50. $a = false;
  51. }
  52. }
  53. else
  54. {
  55. //print(\"$v<br/>n\");
  56. }
  57. }
  58. }
  59.  
  60. }
  61.  
  62. }
  63.  
  64. //dump($classes);
  65.  
  66. $phpCode = '<?php function __autoload($name) {' . &#092;"n\";
  67. $phpCode .= 'static $map = array(' . &#092;"n\";
  68. foreach ($classes as $k => $v) {
  69. $phpCode .= ''' . $v[0] . '' => '' . $v[1] . '','. &#092;"n\";
  70. }
  71. $phpCode .= ');' . &#092;"n\";
  72. $phpCode .= 'require_once($map[$name]);' . &#092;"n}n\";
  73. $phpCode .= '?>';
  74. file_put_contents('autoload.php', $phpCode);
  75. //dump($fileContext);
  76. function dump($dump) {
  77. print('<pre>');
  78. var_dump($dump);
  79. print('</pre>');
  80. }
  81. print ($end = get_microtime() - $start . '<br />');
  82. ?>


--------------------
Go to the top of the page
+Quote Post
Vengeance
post 26.02.2005, 12:36:56
Post #22





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


Połączyłem kody: bela_666, Nievinny oraz Imperiora i osiągnołem taki efekt:

  1. <?php
  2.       public function getClassesMap($sDirName)
  3.       {
  4.          $oRecursiveDirectory = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $sDirName ), true );
  5.          foreach ($oRecursiveDirectory as $oFile)
  6.          {
  7.             if(!is_file($oFile->getPathname()))
  8.                continue;
  9.             $aTokenAll = token_get_all(file_get_contents($oFile->getPathname()));
  10.             $bIsClass = false;
  11.             foreach ($aTokenAll as $iToken)
  12.             {
  13.                if (!is_string($iToken))
  14.                {
  15.                   list($iTokenID, $sTokenValue) = $iToken;
  16.                   switch ($iTokenID)
  17.                   {
  18.                      case T_CLASS:
  19.                         $bIsClass = true;
  20.                         break;
  21.                      case T_INTERFACE:
  22.                         $bIsClass = true;
  23.                         break;
  24.                      case T_STRING:
  25.                         if ($bIsClass)
  26.                         {
  27.                            $aClassesMap[$sTokenValue] = $oFile->getPathname();
  28.                            $bIsClass = false;
  29.                         }
  30.                         break;
  31.                      case T_WHITESPACE:
  32.                         break;
  33.                      default:
  34.                         $bIsClass = false;
  35.                         break;
  36.                   }
  37.                }
  38.             }
  39.          }
  40.          return $aClassesMap;
  41.       }
  42. ?>


Ten post edytował Vengeance 26.02.2005, 12:37:36


--------------------
Go to the top of the page
+Quote Post
Vengeance
post 26.02.2005, 12:41:48
Post #23





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


Linia nr 9: zmieniasz ją na:
Kod
           if(!is_file($oFile->getPathname()) OR $oFile->getFileName == '.svn')


Powinno zadziałać


--------------------
Go to the top of the page
+Quote Post
Nievinny
post 26.02.2005, 17:03:09
Post #24





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

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


@Vengeance -> Czy twoim zdaniem ładowanie z mapy powinno być zaimplementowane od razu w __autoload() czy dać jakąś funkcję pośrednią?

OK, a ja myślę, że można to jeszcze przerobić winksmiley.jpg i jeszcze jedno: kiedy należy a kiedy nie robić mapę plików?

I czy pozwolisz wykorzystam to w swoim CORE?

Zobaczcie coś takiego i oceńcie
  1. <?php
  2.  
  3. define( 'IN_CORE', true );
  4.  
  5. // ---- Definicja stałych
  6. define( 'ROOT_PATH', './' );
  7. define( 'PHPEX', '.php' );
  8.  
  9. // ---- Załadowanie systemów
  10. include_once( ROOT_PATH . 'lib/debuger/Debuger' . PHPEX );
  11. include_once( ROOT_PATH . 'lib/CORE' . PHPEX );
  12.  
  13. // ---- Mapa plików
  14. $aMap = CORE::getClassesMap( ROOT_PATH );
  15. // ---- Funkcja autoładowania
  16. function __autoload( $sFile ) {
  17. global $aMap;
  18. $bLoad = false;
  19. foreach( $aMap as $sName => $sValue ) {
  20. if( $sName === $sFile ) {
  21. try {
  22. CORE::loadClass( $sValue, $sFile );
  23. }
  24. catch( CoreExceptions $Error ) {
  25. print Debuger::errorDisplay( $Error );
  26. }
  27. $bLoad = true;
  28. break;
  29. }
  30. }
  31. if( $bLoad === false ) {
  32. print Debuger::errorLiteDisplay( 'Nie można odnaleźć podanej klasy' );
  33. }
  34. }
  35.  
  36. ?>


Mapa jest tworzona tylko raz, a potem porównywana w pentli foreach? Czy lepiej inaczej, np:
  1. <?php
  2.  
  3. function __autoload( $sFile ) {
  4. global $aMap;
  5. if( isset($aMap[$sFile] ) ) {
  6. try {
  7. CORE::loadClass( $aMap[$sFile], $sFile );
  8. }
  9. catch( CoreExceptions $Error ) {
  10. print Debuger::errorDisplay( $Error );
  11. }
  12.  
  13. }
  14. else {
  15. print Debuger::errorLiteDisplay( 'Nie można odnaleźć podanej klasy' );
  16. }
  17. }
  18.  
  19. ?>

Chyba tes sposób lepszy, czy nie?

Ten post edytował Nievinny 26.02.2005, 17:25:44


--------------------
Go to the top of the page
+Quote Post
Vengeance
post 26.02.2005, 17:35:25
Post #25





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


Nievinny: chodzi oto, aby mape generować tylko RAZ!! Potem jak coś dodasz/zmienisz dopiero robisz ją ponownie. W moim przypadku robienie mapy zabiera 95% czasu wykonywnia skryptu! Dlatego tak ważnym jest aby wynik był objęty jakimś cache. A czy zrobisz w __autoload() czy w czymkolwiek innym to już nie jest takie ważne smile.gif


--------------------
Go to the top of the page
+Quote Post
Nievinny
post 26.02.2005, 17:42:59
Post #26





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

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


Cytat
Nievinny: chodzi oto, aby mape generować tylko RAZ!! Potem jak coś dodasz/zmienisz dopiero robisz ją ponownie. W moim przypadku robienie mapy zabiera 95% czasu wykonywnia skryptu! Dlatego tak ważnym jest aby wynik był objęty jakimś cache. A czy zrobisz w __autoload() czy w czymkolwiek innym to już nie jest takie ważne smile.gif


Źle mnie zrozumiałeś, to, że mapa powinna być robiona tylko raz to ja doskonale wiem....
Chodzi mi o samą funkcję __autoload() czy lepsza jest z foreach czy ta druga... winksmiley.jpg

Ten post edytował Nievinny 26.02.2005, 17:44:05


--------------------
Go to the top of the page
+Quote Post
Vengeance
post 26.02.2005, 18:15:03
Post #27





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


A po co foreach? Jeszcze opozniac ? To $map[$className] jest takie zle? W sumie to i tak kazdy robi jak mu wygodniej ;]


--------------------
Go to the top of the page
+Quote Post
hawk
post 26.02.2005, 18:42:06
Post #28





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


@Vengeance et al: No, bardzo ładny kod biggrin.gif. Ja bym dodał parametryzację/konfigurację generatora mapy. Coś takiego jak ma phpdocumentor - jakie katalogi ma przeglądać, jakie pliki ma czytać. Wtedy można sobie zignorować .svn i nie trzeba tego zakodowywać na stałe w kodzie.

A potem tylko zrzucić mapę do jakiegoś pliku php i voila!

I na koniec coś takiego:
  1. <?php
  2. function __autoload($sClass) {
  3. ClassLoader::load($sClass);
  4. }
  5.  
  6. class ClassLoader {
  7. private static $aMap;
  8.  
  9. public static function addMap($aMap) {
  10. self::$aMap = self::$aMap == null ? $aMap : array_merge(self::$aMap, $aMap);
  11. }
  12.  
  13. public static function load($sClass) {
  14. if (array_key_exists($sClass, self::$aMap)) {
  15. require self::$aMap[$sClass];
  16. }
  17. }
  18. }
  19. ?>
Go to the top of the page
+Quote Post
Vengeance
post 26.02.2005, 19:07:38
Post #29





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


Ok userzy forum.php.pl "wymyslili" juz idee "routera" (a raczej po prostu to nazwali ladnie). Teraz czas nazwac to co tu razem stworzyliśmy snitch.gif


--------------------
Go to the top of the page
+Quote Post
Nievinny
post 27.02.2005, 12:32:23
Post #30





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

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


Nazwa: Autoload Class System...

może być, a klasa niezła, tylko, że robi zrzuty przy każdym wywołaniu skryptu a nie ciągnie z cache winksmiley.jpg

Pozwolę sobie jeszcze dopisać, cos o systemie cache:
1) Jest absolutnie niezbędny:
  • Czas gen bez cache: 0.0617 sec
  • Z cache: 0.0111 sec
  • Czyli o 0.0516 sec szybciej
  • Czyli ok 5,5 raza szybciej
Jak ktoś jest zainteresowany klasą cache to na PW

Ten post edytował Nievinny 3.03.2005, 14:44:37


--------------------
Go to the top of the page
+Quote Post
chmolu
post 4.03.2005, 10:29:10
Post #31





Grupa: Zarejestrowani
Postów: 179
Pomógł: 0
Dołączył: 8.10.2004

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


Ja to rozwiązałem podobnie, jak w nowym Mojavi:

  1. <?php
  2. function __autoload($class_name)
  3. {
  4. $filename = ConfigManager::getConfig('autoload', 'autoload', $class_name);
  5. if (!empty($filename))
  6. {
  7. /* include a file with the class definition */
  8. require_once $filename;
  9. }
  10. else 
  11. {
  12. /* unknown class */
  13. throw new Exception(sprintf('Autoloading of class \"%s\" failed', $class_name));
  14. }
  15. }
  16. ?>


Lista plików jest przechowywana w pliku konfiguracyjnym (ini). Bardzo elastyczne rozwiązanie. Trzeba tylko włączyć klasę ConfigManager - reszta jest ładowana automatycznie.
Go to the top of the page
+Quote Post
Nievinny
post 4.03.2005, 10:52:36
Post #32





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

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


A ja generujesz listę klas? Tu masz od razu generator


--------------------
Go to the top of the page
+Quote Post
chmolu
post 4.03.2005, 16:34:52
Post #33





Grupa: Zarejestrowani
Postów: 179
Pomógł: 0
Dołączył: 8.10.2004

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


Lista klas jest w pliku konfiguracyjnym autoload.ini, który wygląda tak:

Cytat
[autoload]
Class1 = sciezkadopliku
Class2 = sciezkadopliku
Classn = sciezkadopliku


Plik ten jest parsowany do tablicy i następnie chache'owany jako plik .php

Muszę przemyśleć Twój sposób ze skanowaniem katalogów... ciekawe smile.gif

Ten post edytował chmolu 4.03.2005, 16:37:08
Go to the top of the page
+Quote Post
hawk
post 4.03.2005, 17:26:32
Post #34





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


@chmolu:
1) Z tego co pamietam, w __autoload nie mozna rzucac wlasnych wyjatkow, bo i tak nie beda dzialac. Czyzby bug w Mojavi?

2) Pliki ini sa w tym przypadku zdecydowanie gorsze od tablic php. W pliku ini nie mozna zrobic czegos takiego:
  1. <?php
  2. $map = array(
  3. 'FooClass' => FOO_DIR . '/Foo.class.php',
  4. );
  5. ?>

Kazdy, kto bedzie uzywal systemu z plikiem ini, bedzie musial zmienic wszystkie sciezki w tym pliku, bo domyslne nie beda u niego dzialaly.

3) Jaki jest sens kompilowac plik ini do pliku php? Jezeli pliki php sa zdecydowanie szybsze, to dlaczego nie zaczac wlasnie od nich? Dla mnie to jest komplikowanie sobie zycia.
Go to the top of the page
+Quote Post
chmolu
post 4.03.2005, 17:49:43
Post #35





Grupa: Zarejestrowani
Postów: 179
Pomógł: 0
Dołączył: 8.10.2004

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


Cytat
1) Z tego co pamietam, w __autoload nie mozna rzucac wlasnych wyjatkow, bo i tak nie beda dzialac. Czyzby bug w Mojavi?

Wyjątki można wyrzucać, tylko nie mozna ich łapać w catch. Wtedy są uznawane jako fatal error.

Cytat
Pliki ini sa w tym przypadku zdecydowanie gorsze od tablic php. W pliku ini nie mozna zrobic czegos takiego:
...

kazdy, kto bedzie uzywal systemu z plikiem ini, bedzie musial zmienic wszystkie sciezki w tym pliku, bo domyslne nie beda u niego dzialaly.

Można zrobić coś takiego. Po prostu trzeba dodawać do każdego wpisu pseudo-stałą, np. Action = %APP_DIR%/modules/actions/action.php. ConfigManager automatycznie zamienia takie 'stałe' na właściwą scieżkę.

Cytat
3) Jaki jest sens kompilowac plik ini do pliku php? Jezeli pliki php sa zdecydowanie szybsze, to dlaczego nie zaczac wlasnie od nich? Dla mnie to jest komplikowanie sobie zycia.

Wiesz, to jest indywidualna sprawa. Ja przyjąłem, że taka rzecz należy do konfiguracji, a nie do kodu aplikacji. Konfigurację zapisuję w plikach ini. Mogę oczywiście zapisywac od razu w plikach php. Dla mnie jest wygodniej to oddzielić na właściwy kod aplikacji i dane konfiguracji. Wcale nie jest to komplikowanie sobie życia. Całość ogranicza się do funkcji parse_ini_file(), var_export() i fputs().

Zależy, jak kto lubi smile.gif

Ten post edytował chmolu 4.03.2005, 17:53:19
Go to the top of the page
+Quote Post
Nievinny
post 4.03.2005, 18:05:53
Post #36





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

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


W sumie, skrypt po raz pierwszy zaczyna działanie więc generuje mapę, która jest potem cachowana. Gdy odpalimy skrypt po raz drugi odczyta mapę z cache (zserializowany ciąg + <?php die(); ?> ), usunie te ostatnie i przyśpieszenie jest widoczne winksmiley.jpg
to sprowadza się ogólnie do:
  1. <?php
  2.  
  3. if( !CORE::addMap( $Cache->loadCacheArray( 'aMap' ) ) ) {
  4. $aMap = CORE::getMap( './' );
  5. CORE::addMap( $aMap );
  6. $cache->saveCacheArray( 'aMap', $aMap );
  7. }
  8. // 'aMap' - uchwyt do pliku cache .php w ./cache/arrays/
  9.  
  10. ?>

I wg mnie to najprostszy sposób winksmiley.jpg


--------------------
Go to the top of the page
+Quote Post
Imperior
post 5.03.2005, 11:12:31
Post #37





Grupa: Zarejestrowani
Postów: 105
Pomógł: 0
Dołączył: 16.10.2004

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


Cytat(hawk @ 2005-03-04 16:26:32)
1) Z tego co pamietam, w __autoload nie mozna rzucac wlasnych wyjatkow, bo i tak nie beda dzialac. Czyzby bug w Mojavi?

Zgadza się, w __autoload nie rzuca się wyjątków, ale mojavi3 nie rzuca go, tylko tworzy (bo tam ma zaimplementowane metody dot. informowania o bledach).

PS. Na początku też myślałem, że mają błąd, ale tam throw nie ma smile.gif


--------------------
Com powiedział, powiedziałem.
Go to the top of the page
+Quote Post
hawk
post 7.03.2005, 03:36:42
Post #38





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


@chmolu: Faktycznie, obsługa plików ini jest bardzo prosta. Co ciekawe, na początku próbowałem właśnie podejścia z "%APP_DIR%/...". Pliki ini wyglądają lepiej, prościej się je edytuje, trudniej popełnić błąd lub wrzucić niedozwolony kod. Z drugiej strony, trzeba wygenerować z nich pliki php, co samo w sobie jest banalne, ale wymaga sprawdzenia daty modyfikacji, czyli dodatkowego kroku. Wpływ na wydajność jest minimalny i to już chyba kwestia gustu.
Go to the top of the page
+Quote Post
Bora
post 7.03.2005, 15:06:38
Post #39





Grupa: Zarejestrowani
Postów: 270
Pomógł: 0
Dołączył: 15.06.2003

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


Pliki ini są wczytywane szybciej niż php gdyż mają specjalny prostszy parser.
Porównajcie soebie a zobaczycie że czasami nawet cechowanie w php trwa dłużej.
Go to the top of the page
+Quote Post
Vengeance
post 7.03.2005, 16:07:14
Post #40





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


A czy są szybsze od zserializowanej tablicy, zapisanej w pliku ? smile.gif


--------------------
Go to the top of the page
+Quote Post
Imperior
post 7.03.2005, 17:09:23
Post #41





Grupa: Zarejestrowani
Postów: 105
Pomógł: 0
Dołączył: 16.10.2004

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


Cytat(Vengeance @ 2005-03-07 15:07:14)
A czy są szybsze od zserializowanej tablicy, zapisanej w pliku ? smile.gif

Jeśli to nie jest pytanie retoryczne, to: Nie.


--------------------
Com powiedział, powiedziałem.
Go to the top of the page
+Quote Post
hawk
post 7.03.2005, 17:19:21
Post #42





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


@Bora: Pliki ini moze i sa wczytywane szybciej, ale zamiana %APP_DIR% na odpowiednia sciezke niestety zepsuje tutaj wydajnosc.
Go to the top of the page
+Quote Post
orson
post 7.03.2005, 22:59:24
Post #43





Grupa: Zarejestrowani
Postów: 548
Pomógł: 2
Dołączył: 19.07.2003

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


witam ...

a moze w ini zrobic 2 sekcje ...
Kod
[path]
app_dir = "./jakis/dir/"
trans_dir = "./jakis/dir"
jakis_dir = "./jakis/dir"
[clases]
class = file_name
class = file_name
class = file_name

i potem parse ini ze znacznikiem true i mamy sklejanie stringow ...
  1. <?php
  2. $array['path']['app_dir'].$array['path']['class']
  3. ?>

i nie trzeba nic zamieniac ... i da sie latwo konfigurowac w tym samym ini ...

pozdrawiam


--------------------
Computer games don't affect kids; I mean if <span style="font-weight: bold;">Pac Man</span> affected us as kids,we would all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music.
Go to the top of the page
+Quote Post
hawk
post 8.03.2005, 00:10:53
Post #44





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


A w jaki sposob z gory okreslisz, ktora sciezke masz dokleic do konkretnej klasy? Nie zrobisz tego, chyba ze narzucisz sobie jakies bardzo scisle reguly, a tego wole uniknac.
Go to the top of the page
+Quote Post
Nievinny
post 8.03.2005, 08:01:25
Post #45





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

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


A ja mam jeszcze pytanie dot. __autoload(). Czy jeśli wywołam w niej statyczną metodę która w razie niepowodzenia wywala wyjątek, to trzeb go obsłużyć w __autoload() czy przejdzie poziom wyżej?
Przykład:
  1. <?php
  2.  
  3. function __autoload( $sClassName ) {
  4. Application::loadClass( $sClassName );
  5. }
  6.  
  7. //czy
  8.  
  9. function __autoload( $sClassName ) {
  10. try {
  11. Application::loadClass( $sClassName );
  12. }
  13. catch( NotFoundClassException $e ) {
  14. //coscos
  15. }
  16. }
  17.  
  18. ?>


Czy 1 sposób też może być? Czy wyjątek zostanie obsłużony?


--------------------
Go to the top of the page
+Quote Post
orson
post 8.03.2005, 20:18:36
Post #46





Grupa: Zarejestrowani
Postów: 548
Pomógł: 2
Dołączył: 19.07.2003

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


Cytat(hawk @ 2005-03-08 00:10:53)
A w jaki sposob z gory okreslisz, ktora sciezke masz dokleic do konkretnej klasy? Nie zrobisz tego, chyba ze narzucisz sobie jakies bardzo scisle reguly, a tego wole uniknac.

witam ..

no przeciez normalnie ...
Kod
[path]
mainAppPath = '/home/user/public_hmtl/site/'
mainImagesPath = '/home/user/public_hmtl/site/images/'
cos tam
cos tam
default = 'clases/'
[clases]
dbclass = 'clases/db.class.php'
session = 'clases/session.class.php'
mail = '3rdpart/clases/mail/mail.class.php'
;z defaultem
dbclass = 'db.class.php'
session = 'session.class.php'

i potem:
  1. <?php
  2.  
  3. print $iniFile['path']['mainAppPath'].$iniFile['clases']['dbclass'];
  4. print $iniFile['path']['mainAppPath'].$iniFile['clases']['session'];
  5. //defaultem
  6. print $iniFile['path']['mainAppPath'].$iniFile['path']['default'].$iniFile['clases']['dbclass'];
  7.  
  8. ?>

w sekcji clases tez moga byc sciezki podane, przeciez to lokalizacja pliku a nie nazwa klasy ... czyli dajesz najpierw najbardziej ogolna a potem w poszczegolnych klasach dodajesz, podkatalogi ... mozna na sztywno dodac default do kodu strony a jak cos sie zmieni [ale znowu bez przesady ... tak czesto sie nie zmienia i klasy i tak sa w 1 miejscu] to zmienic albo nawet wyzerowac default

pozdrawiam


--------------------
Computer games don't affect kids; I mean if <span style="font-weight: bold;">Pac Man</span> affected us as kids,we would all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music.
Go to the top of the page
+Quote Post
hawk
post 9.03.2005, 03:16:17
Post #47





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


@Orson: nie o to mi chodzi. Masz np. (a raczej użytkownik systemu ma) Smarty, kawałek WACT i w ogóle przynajmniej kilka bibliotek, których używa. Przecież nie będzie tak, że jeden super framework robi wszystko najlepiej, więc autoloader nie powinien być ograniczony do tego, co sami sobie wymyślimy, tylko po prostu działać tak jak chce użytkownik.

Nie powiesz teraz użytkownikowi, że ma to wszystko umieścić w innym katalogu. Będzie miał Smarty w jakimś niestandardowym miejscu, będzie chciał użyć razem z super-autoloaderem i będzie oczekiwał, że autoloader załaduje mu Smarty - od tego przecież jest.

I co wtedy? Skąd autoloader ma wiedzieć, że Smarty akurat nie jest pod mainAppPath?

PS
Cytat
...mozna na sztywno dodac default do kodu strony a jak cos sie zmieni...

Nie można. Autoloader jest po to, żeby tego kodu w ogóle nie było. Nie ma gdzie dodawać defaulta.
Go to the top of the page
+Quote Post
orson
post 9.03.2005, 07:31:00
Post #48





Grupa: Zarejestrowani
Postów: 548
Pomógł: 2
Dołączył: 19.07.2003

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


witam ...

hmm ... no to w pliku ini w sekcji clases podajesz
Kod
[clases]
smarty = /full/path/to/smarty/lib/smarty.php

a zeby bylo latwiej mozna np. wprowadzic ifa przy ladowaniu i np. jak nazwa klasy zaczyna sie od 2 // a nie od 1 to laduj bez patha .... czyli jak dopiszemy // przed smarty to oleje sekcje path i biblioteka moze byc gdziekolwiek ...
rozwiazanie z plikiem ini coraz bardziej mi sie podoba ... chyba zaczne go stosowac ...

pozdrawiam


--------------------
Computer games don't affect kids; I mean if <span style="font-weight: bold;">Pac Man</span> affected us as kids,we would all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music.
Go to the top of the page
+Quote Post
dr_bonzo
post 9.03.2005, 10:25:30
Post #49





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


@Nievinny: wyrzuc wyjatek w tej metodzie i sprawdz. Wyjatek wedruje w gore do ekranu (error) dopuki go nie zlapiesz gdzies po drodze.


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Nievinny
post 9.03.2005, 17:20:55
Post #50





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

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


Owszem wywala wyjątek, ale nie obsługuje go w zwykły sposób, a skrypt wychwytuje wyjątek "po drodze", tylko wywala fatal errora.

@dr_bonzo: To co mówisz byłoby dobre, gdyby funkcję wywoływać w ten sposób:
  1. <?php
  2.  
  3. __autoload( $zmienna );
  4.  
  5. ?>

A nie jeśli zostaje ona wykonana automatycznie... :/
Zostaje obsługa błędów na poziomie funkcji. Jeśli obsługujemy przez funkcję to pojawiają się problemy:
1) Jeśli klasą którą ładuje system jest klasa obsługi błędów?
  1. <?php
  2.  
  3. //$zmienna = 'Debug';
  4. function __autoload( $zmienna ) {
  5. try {
  6. CORE::zaladuj( $zmienna )
  7. } catch( Exception $e ) {
  8. print Debug::display( $e );
  9. }
  10. }
  11.  
  12. ?>


Znajdą się też inne problemy... :/
Macie jakieś pomysły jak ładnie obsłużyć ten wyjątek?


--------------------
Go to the top of the page
+Quote Post
chmolu
post 12.03.2005, 23:12:26
Post #51





Grupa: Zarejestrowani
Postów: 179
Pomógł: 0
Dołączył: 8.10.2004

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


Rozwiązanie z generowaniem mapy przez skanowanie katalogów wydaje się najlepsze. Jednak sposób Vengeance'a nie jest zbyt efektywny. Wymaga wczytania zawartości każdego pliku z osobna i sprawdzania, czy zawiera on jakieś klasy. Może jest to bardziej elastyczne, gdy mamy po kilka klas w jednym pliku, ale ja to zrobiłem inaczej.

U mnie każda klasa jest w osobnym pliku. Nazwa pliku zawierającego definicję klasy lub interfejsu kończy się na .class.php lub interface.php. I tylko takie pliki są ładowany do mapy.

Wycinki kodu z mojego frameworka:
  1. <?
  2. /**
  3.    * Checks whether the specified path exists.
  4.    * If the directory is not found, it'll try to create one.
  5.    *
  6.    * @param string $dirname 
  7.    * @return void
  8.    */
  9. function ensure_directory_exists($dirname)
  10. {
  11. $dirname = substr($dirname, strlen(APP_DIR));
  12.  
  13. $sub_dirs = explode('/', $dirname);
  14. $path = '';
  15. foreach ($sub_dirs as $dir)
  16. {
  17. $path .= $dir . '/';
  18. if (!file_exists($path))
  19. {
  20. if (!@mkdir($path, 0777))
  21. {
  22. throw new DaeronException('Could not create a directory \"' . $path . '\"');
  23. }  
  24. }
  25. }
  26. }
  27.  
  28. /**
  29.    * Writes the supplied content to a file.
  30.    *
  31.    * @param string $filename Name of a file to write to.
  32.    * @param mixed $content Data to write to a file.
  33.    * @return void
  34.    */
  35. function file_write($filename, $content)
  36. {
  37. ensure_directory_exists(dirname($filename));
  38. $fp = @fopen($filename, 'w');
  39. if($fp)
  40. {
  41. @fputs($fp, $content, strlen($content));
  42. }
  43. @fclose($fp);
  44. }
  45.  
  46. class Autoloader
  47. {
  48. /**
  49.  * Map of class names and their localization. 
  50.  *
  51.  * @var array
  52.  * @static 
  53.  */
  54. private static $map = null;
  55.  
  56. /**
  57.  * Loads specified class.
  58.  *
  59.  * @param string $class_name
  60.  * @return void 
  61.  */
  62. public static function load($class_name)
  63. {
  64. $cached_map = APP_DIR . '/var/cache/autoload.php';
  65. if (!is_readable($cached_map))
  66. {
  67. self::generateMap();
  68. }
  69.  
  70. if (!isset(self::$map)) require_once $cached_map;
  71.  
  72. $class_name = strtolower($class_name);
  73. if (!isset(self::$map[$class_name]))
  74. {
  75. throw new Exception('Unknown class ' . $class_name);
  76. }
  77.  
  78. require_once self::$map[$class_name];
  79. }
  80.  
  81. /**
  82.  * 
  83.  * 
  84.  *  
  85.  */
  86. private static function generateMap()
  87. {
  88. self::$map = array();
  89.  
  90. $cached_map = APP_DIR . '/var/cache/autoload.php';
  91.  
  92. self::scan(DAERON_DIR);
  93. self::scan(APP_DIR);
  94.  
  95. $compiled = &#092;"<?phpn\";
  96. $compiled .= 'self::$map = ' . var_export(self::$map, true) . &#092;"n?>\";
  97.  
  98. file_write($cached_map, $compiled);  
  99. }
  100.  
  101. /**
  102.  * 
  103.  * 
  104.  *  
  105.  */
  106. private static function scan($dir)
  107. {
  108. $match = array();
  109.  
  110. $rd = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir), true);
  111. foreach ($rd as $file)
  112. {
  113. if(!is_file($file->getPathname())) continue;
  114.  
  115. if (preg_match('/([a-z0-9_]+).(class|interface).php$/i', $file->getPathName(), $match))
  116. {
  117. self::$map[strtolower($match[1])] = $file->getPathName();
  118. }
  119. }  
  120. }
  121. }
  122.  
  123. function __autoload($class_name)
  124. {
  125. Autoloader::load($class_name);
  126. }
  127. ?>


Porównanie szybkości (dla stosunkowo małej liczby plików):
- czytanie mapy z generowaniem: 35,67 ms
- czytanie z cache'owanej mapy: 00,57 ms

Kod Vengeance'a:
- czytanie mapy z generowaniem: 129.35 ms

A czytanie z cache wygląda identycznie smile.gif

Ten post edytował chmolu 13.03.2005, 12:41:45
Go to the top of the page
+Quote Post
Vengeance
post 13.03.2005, 01:10:23
Post #52





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


chmolu: Zauważ, że to Ty trzymasz każdą klasę w innym pliku!

A jak byś chciał dodać do frameworka np. AdoDB, Smarty czy inne rzeczy? One nie stosują twojego nazewnictwa.

Po to właśnie ten mój* skrypt przeszukuje wszystkie pliki wczytując je!

Skoro twoje nazewnictwo jest tak ustandaryzowane to w jakim celu w ogóle tworzyć mape ? przecież wystarczy zrobić

require $className . '.class.php'; hehe

* przypominam, iż nie czuje się właścicielem skryptu smile.gif posklejałem kod z wielu wypowiedzi innych osób i wrzuciłem smile.gif


--------------------
Go to the top of the page
+Quote Post
chmolu
post 13.03.2005, 09:44:36
Post #53





Grupa: Zarejestrowani
Postów: 179
Pomógł: 0
Dołączył: 8.10.2004

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


@Vengeance: to prawda, nie każdy musi trzymać każdą klasę w innym pliku. Dla mnie takie rozwiązanie jest najwygodniejsze.

Cytat
A jak byś chciał dodać do frameworka np. AdoDB, Smarty czy inne rzeczy? One nie stosują twojego nazewnictwa.

Autoloader u mnie ma służyć tylko do ładowania klas należących do jądra i aplikacji. Biblioteki typu Smarty i AdoDB zaliczam do "zewnętrznych" części aplikacji, którymi zająć musi się odpowiednia akcja/widok. Poza tym zauważ, że w przypadku tych bibliotek musimy włączyć tylko jeden główny plik, który już sam zajmuje się potrzebnymi mu plikami.
(btw: główny plik Smarty ma nazwę Smarty.class.php, więc pasuje do mojego nazewnictwa tongue.gif)

Cytat
Skoro twoje nazewnictwo jest tak ustandaryzowane to w jakim celu w ogóle tworzyć mape ? przecież wystarczy zrobić

require $className . '.class.php'; hehe

Ale dzięki mapie struktura katalogów jest dowolna. Mogę sobie w dowolny sposób podzielić na różne katalogi i podkatalogi, a gdy zajdzie potrzeba zmiany struktury wystarczy tylko wygenerowac mapę i nie trzeba grzebać w kodzie i poprawiać wszystkich ścieżek.

Ten post edytował chmolu 13.03.2005, 09:52:28
Go to the top of the page
+Quote Post
bela
post 13.03.2005, 10:44:30
Post #54


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

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


@chmolu a jak zmienisz ścieżke do smarty ? biggrin.gif


--------------------
Go to the top of the page
+Quote Post
chmolu
post 13.03.2005, 12:43:09
Post #55





Grupa: Zarejestrowani
Postów: 179
Pomógł: 0
Dołączył: 8.10.2004

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


Nie używam Smarty więc nie ma żadnego problemu biggrin.gif

// btw: poprawiłem troszkę ten kod

Ten post edytował chmolu 13.03.2005, 12:43:29
Go to the top of the page
+Quote Post
Vengeance
post 13.03.2005, 13:43:28
Post #56





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


@chmolu: ty nie. Ale z tego co wynika z twoich wypowiedzi to co piszesz
to framework. Pewnie kiedys ktos inny z niego bedzie korzystac i moze chciec takze korzystac ze smarty smile.gif


--------------------
Go to the top of the page
+Quote Post
chmolu
post 13.03.2005, 13:55:45
Post #57





Grupa: Zarejestrowani
Postów: 179
Pomógł: 0
Dołączył: 8.10.2004

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


Zapewniam cię, że nie będzie to żaden problem aarambo.gif
Ale mam nadzieję, że zamiast Smarty ludzie będą używali systemu wbudowanego w mój framework (wzorowany na WACT/ASP/JSP).
Jak skończę, to zarzucę tu kod do oceny.

Ten post edytował chmolu 13.03.2005, 13:57:45
Go to the top of the page
+Quote Post
Ociu
post 4.05.2005, 18:16:29
Post #58





Grupa: Moderatorzy
Postów: 1 566
Pomógł: 37
Dołączył: 14.05.2003
Skąd: Kraków




Pozwole sobie odkopać temat winksmiley.jpg

Zastanawiam się czy nie użyć pliku xml ładowania klas. Coś na wzór:

  1. <Classes>
  2.  
  3. <dirname>
  4. <class name='jakas tam nazwa'>file.php</class>
  5. <class name='jakas tam nazwa2'>file2.php</class>
  6. </dirname>
  7.  
  8. <dirname2>
  9. <class name='jakas tam nazwa3'>file3.php</class>
  10. <class name='jakas tam nazwa4'>file3.php</class>
  11. </dirname2>
  12.  
  13. </Classes>


Potem bardzo prosto: simplexml, loader instacji (w moim przypadku) i tyle smile.gif

Iść dalej tym tropem, czy zacząć myśleć nad czymś innym ?
Go to the top of the page
+Quote Post
davidD
post 5.05.2005, 00:09:50
Post #59





Grupa: Zarejestrowani
Postów: 13
Pomógł: 0
Dołączył: 10.10.2002

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


Tylko właściwie... po co XML do zwykłego przypisania nazwy pliku do nazwy klasy? IMO jest to lekkie komplikowanie sobie całej sprawy - no chyba, że chcemy przechowywać jakieś dodatkowe informacje.

Mnie osobiście podoba się pomysł z iteratorem, szukającym klas po wszystkich plikach o określonym wzorcu, w podanej ścieżce (ścieżkach). Można z tego zrobić ładną tablicę, zserializować ją i do pliku... Co prawda trzeba się troszkę pobawić samym pisaniem tego generatora mapy, ale za to później, przy zmianie położenia/nazw plików zaoszczędzi się duużo czasu.


--------------------
| WinXP | Apache 2.0.50 | php 5.0.3 | MySQL 4.0.20 | Zend Studio |
CMS::engine llllllllllllllllllll 80%
CMS::userInterface
Go to the top of the page
+Quote Post
matid
post 5.05.2005, 06:37:45
Post #60





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

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


Ja to widzę tak:
1. Crowler, szuka po określonych folderach w poszukiwaniu plików php zawierających klasy. Będzie miał możliwość wyszukiwania z filtrowaniem nazw plików, nazwach klas itp. Być może po dodaniu opcji filtracji czas generowania mapy się zwiększy nieco, ale na jakoże jest to czynność wykonywana rzadko, można sobie na to pozwolić.
2. Dodatkowy plik XML z klasami zewnętrznymi. W tym pliku będą zapisane w postaci XML dodatkowe klasy, które autoloader ma obsługiwać. Plik byłby parsowany i razem z wynikami crowlera zapisywany w pliku php w postaci tablicy.
Go to the top of the page
+Quote Post
Ociu
post 5.05.2005, 07:22:02
Post #61





Grupa: Moderatorzy
Postów: 1 566
Pomógł: 37
Dołączył: 14.05.2003
Skąd: Kraków




Cytat(matid @ 2005-05-05 07:37:45)
2. Dodatkowy plik XML z klasami zewnętrznymi. W tym pliku będą zapisane w postaci XML dodatkowe klasy, które autoloader ma obsługiwać.

O to mi chodziło winksmiley.jpg

Śpieszyłem się i zapomaniałem dopisać.
Go to the top of the page
+Quote Post
chmolu
post 5.05.2005, 08:24:02
Post #62





Grupa: Zarejestrowani
Postów: 179
Pomógł: 0
Dołączył: 8.10.2004

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


IMO pliki XML w tym wypadku są niepotrzebne. Szybciej i wygodniej będzie to zrobić przy pomocy plików ini
Go to the top of the page
+Quote Post
Nievinny
post 5.05.2005, 17:06:02
Post #63





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

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


XML to przeładowanie, a nam zależy na czasie, nie? Chociaż wszystko da się zrobić ;P


--------------------
Go to the top of the page
+Quote Post
matid
post 5.05.2005, 17:55:53
Post #64





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

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


Cytat(Nievinny @ 2005-05-05 18:06:02)
XML to przeładowanie, a nam zależy na czasie, nie? Chociaż wszystko da się zrobić ;P

Przecież parsowanie pliku XML będzie się odbywać tylko w wypadku rekonstruowania mapy, co za często się dziać nie powinno, czyż nie? Zyskujemy natomiast na przejrzystości i strukturze pliku konfiguracyjnego.
Go to the top of the page
+Quote Post
bigZbig
post 10.05.2005, 09:28:27
Post #65





Grupa: Zarejestrowani
Postów: 740
Pomógł: 15
Dołączył: 23.08.2004
Skąd: Poznań

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


@matid -> zauwazylem u Ciebie duze przywiazanie do technologi xml. Wiesz mnie sie zawsze wydawalo, ze ten jezyk zostal powolany do zycia po to, aby zapewnic przenosnosc danych pomiedzy roznymi platformami. Nie wiem czy w tym przypadku zapewnienie tej cechy jest pozadane. Uwazam ze próbujesz robic cos na sile utrudniajac sobie zywot.


--------------------
bigZbig (Zbigniew Heintze) | blog.heintze.pl
Go to the top of the page
+Quote Post
Nievinny
post 10.05.2005, 16:01:11
Post #66





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

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


@matid -> ale tą mapę musisz za każdym uruchomnienie skryptu załadować i to będzie się dziać często...


--------------------
Go to the top of the page
+Quote Post
matid
post 10.05.2005, 17:36:31
Post #67





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

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


Cytat(Nievinny @ 2005-05-10 17:01:11)
@matid -> ale tą mapę musisz za każdym uruchomnienie skryptu załadować i to będzie się dziać często...

Przecież nie chodzi mi o trzymanie mapy w XMLu, bo jest to totalną pomyłką. Nie jestem aż tak przywiązany do XMLa żeby tracić na wydajności. Chodzi mi o trzymanie w pliku XML dodatkowych ścieżek do przeszukiwania, czyli parsowane będzie to tylko przy regenerowaniu mapy.
Go to the top of the page
+Quote Post
Nievinny
post 10.05.2005, 18:24:33
Post #68





Grupa: Zarejestrowani
Postów: 134
Pomógł: 0
Dołączył: 27.01.2005
Skąd: Białystok

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


Czyli trzymasz tylko katalogi do parsowania? To nie ma sensu, ponieważ powinno się parsować wszystkie katalogi i uzyskać pełną mapę klas.


--------------------
Go to the top of the page
+Quote Post
Ociu
post 10.05.2005, 19:40:08
Post #69





Grupa: Moderatorzy
Postów: 1 566
Pomógł: 37
Dołączył: 14.05.2003
Skąd: Kraków




Cytat(matid @ 2005-05-10 18:36:31)
Chodzi mi o trzymanie w pliku XML dodatkowych ścieżek do przeszukiwania, czyli parsowane będzie to tylko przy regenerowaniu mapy.

Przemyślałem sposób z XML i stwierdziłem, ze pomysł jest chybiony. Tak czy inaczej trzeba za każdym razem parsowac plik, traci się na tym cenny czas... A gdy tych dodatkowych ścieżek jest dużo ? wtedy czas wydłuża się do sek, a nie tysiącznych sekund.
Go to the top of the page
+Quote Post
matid
post 10.05.2005, 20:34:10
Post #70





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

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


Cytat(Ociu @ 2005-05-10 20:40:08)
Przemyślałem sposób z XML i stwierdziłem, ze pomysł jest chybiony. Tak czy inaczej trzeba za każdym razem parsowac plik, traci się na tym cenny czas... A gdy tych dodatkowych ścieżek jest dużo ? wtedy czas wydłuża się do sek, a nie tysiącznych sekund.

Nie wiem jak sobie wyobrażasz wygenerowanie mapy w tysięczne sekund. W średniej wielkości projekcie (jeszcze bez czytania dodatkowych ścieżek, ok. 90 klas w różnych plikach) trwa to ok. 0,4 s. Czytanie z mapy to ok 0.0008s. Więc nie wiem jakbyś chciał kombinować, ale IMO niemożliwym jest generowanie mapy w tysięczne sekundy. Oczywiście mówię tutaj o mapie nie wymuszającej żadnego przystosowania nazwy pliku itp.
Go to the top of the page
+Quote Post
Vengeance
post 10.05.2005, 21:26:35
Post #71





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


" trwa to ok. 0,4 s"

lol :] Mój kod (a ogolnie ten co podałem powyżej gdzieś), który rekurencyjnie schodzi katalogami w dół i zapisuje znalezione klasy już teraz wykonuje się czasem więcej niż 20 sekund :]
Oczywiście robione jest to tylko raz, przy pierwszym uruchomieniu.


--------------------
Go to the top of the page
+Quote Post
matid
post 10.05.2005, 21:46:19
Post #72





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

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


Cytat(Vengeance @ 2005-05-10 22:26:35)
" trwa to ok. 0,4 s"

lol :] Mój kod (a ogolnie ten co podałem powyżej gdzieś), który rekurencyjnie schodzi katalogami w dół i zapisuje znalezione klasy już teraz wykonuje się czasem więcej niż 20 sekund :]
Oczywiście robione jest to tylko raz, przy pierwszym uruchomieniu.

Moja klasa autoloadera jest w znaczej części oparta na wypowiedziach i nawet fragmentach kodów z tego tematu, więc nie zdziwiłbym się, gdyby funkcja skanująca foldery (lub jej założenia) była już przez ciebie cytowana.

Prędkości w dostępie do plików mogą wynikać z różnego systemu operacyjnego (ja testuję lokalnie na linuksie, który ma świetny system buforowania dysków), procesora, pamięci, obciążenia, itp.
U mnie przeskanowanie ok 100 plików (ok. 1 MB) i stworzenie mapy zawierającej 90 klas trwa ok. 0,4s.

Oprócz tego mam napisany bardzo fajny system automatycznego regenerowania mapy, cachowania wyników, itp.

Ten post edytował matid 10.05.2005, 21:49:35
Go to the top of the page
+Quote Post
Ociu
post 11.05.2005, 09:08:31
Post #73





Grupa: Moderatorzy
Postów: 1 566
Pomógł: 37
Dołączył: 14.05.2003
Skąd: Kraków




Czepiasz się szczegółów, liczba była podana dla przykładu.
Go to the top of the page
+Quote Post
Vengeance
post 11.05.2005, 20:45:37
Post #74





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


To nie było czepianie. Chodziło mi o sposób w jaki @matid osiągnął tak dobry jak dla mnie wynik. U mnie już powoli php robi time out przy generowaniu :] (WinXP, 950 MHz, 256mb RAM)


--------------------
Go to the top of the page
+Quote Post
matid
post 11.05.2005, 21:21:56
Post #75





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

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


Dla zainteresowanych - moja klasa Autoloader: http://matid.emmatrade.pl/files/Autoloader.class.phps

I jeszcze raz moje testy:
Sprzęt: Pentium 4 2,4 GHz, 1024 MB RAM, dysk twardy 7200 RPM (system plików: ReiserFS)
System: Ubuntu Linux 5.04 Hoary Hedgehog

Dane testowe:
Rozmiar: 913.6 KB
Liczba plików: 120
Liczba klas: 90

Czas generowania mapy po raz pierwszy po włączeniu komputera: 0.872271060944s
Czas generowania mapy po raz kolejny (część plików mogła być w buforze dysków): 0.427920103073

Ten post edytował matid 11.05.2005, 21:23:57
Go to the top of the page
+Quote Post
hawk
post 12.05.2005, 09:45:30
Post #76





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


Skoro temat zrobił się popularny i każdy chce mieć swój autoloader oparty o mapy (co uważam za słuszne), to warto załatwić jedną prostą rzecz. Kompatybilność. Taka mapa to na tyle prosta struktura, że pewnie wszędzie wygląda tak samo:
  1. <?php
  2. $map=array(
  3. 'nazwaklasy' => 'ścieżkadoklasy',
  4. );
  5. ?>

Wtedy każdy może sobie generować mapę jak mu się podoba, szybciej lub wolniej. I każdą mapę można wrzucić do każdego autoloadera. Dobrze myślę?

Kompatybilność jest akurat bardzo ważna w przypadku autoloadera. Bo jeżeli napiszę jakąś bibliotekę, to wykorzystam swój pomysł. I ta biblioteka musi działać z biblioteką autorstwa kogoś innego, kto też oparł ją o swój autoloader. A autoloader może działać tylko jeden, więc jeżeli jeden do drugiego nie pasuje, to całość wychodzi do dupy.
Go to the top of the page
+Quote Post
bigZbig
post 12.05.2005, 09:49:20
Post #77





Grupa: Zarejestrowani
Postów: 740
Pomógł: 15
Dołączył: 23.08.2004
Skąd: Poznań

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


@hawk -> Amen


--------------------
bigZbig (Zbigniew Heintze) | blog.heintze.pl
Go to the top of the page
+Quote Post
dr_bonzo
post 26.05.2005, 15:15:11
Post #78





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


...mam i ja.

Stworzylem swojego autoloadera:
- w konfigu podaje katalogi do rekursywnego przejrzenia
- podaje rozszerzenia plikow ktore maja byc tokenizowane

- mapa jest tworzona w std. formacie: nazwa_klasy => sciezka_do_pliku
- i zapisywana w formacie .ini (moze dorobie wybor ini | php)

I co najwazniejsze -- cachuje wyniki tokenizowania plikow (to nie to samo co 'mapa') -- tokenizowane sa tylko te co zostaly zmodyfikowane (okreslane przez filemtime()), co daje znaczna oszczednosc czasu. Zapisuje tablice:
  1. <?php
  2.  
  3. [ 'nazwa_pliku' ] ->
  4. (
  5.     [ 'classes' ] ->
  6.     (
  7.         [ 0 ] -> 'klasa_1';
  8.         [ 1] - > itd...
  9.     )
  10.     [ 'modification_time' ] = 111123423423423; // czas modyfikacji
  11.     { ['valid' ] = TRUE }
  12. )
  13. )
  14. ?>


Jak to wyglada w praktyce:
- wczytuje ww. cache
- przegladam katalogi i robie liste znajdujacych sie tam plikow
- loop po tych wszystkich plikach: porownuje czas modyfikacji pliku z czasem zapisanym w cache
- jesli plik zostal zmieniony to go tokenizuje i aktualizuje cache (+ ustawienie znacznika 'valid' w cache)
- jesli nie zostal zmodyfikowany to tylko ustawienie znacznika 'valid' w cache
- po przejrzeniu wszystkich plikow, usuwam te wpisy w cache, ktore nie maja znacznika 'valid', i usuwam znacznik 'valid' z tych, ktore go maja (tylko po to zeby go (znacznika) nie zapisac w cache)
- uzyskuje tablice z wpisami
nazwa_pliku --> klasy/interfejsy w min sie znajdujace + czas modyfikacji pliku
- zapisuje to cache
- na podstawie tego cache tworze mape

Wlasciwosci
- nowe pliki ktorych nie bylo w cache sa tokenizowane i dodawane do cache i mapy
- pliki ktore byly w cache a teraz nie istnieja (nie ma ich w podanych w configu katalogach) sa usuwane z cache i mapy
- pliki ktore byly w cache i nie zostaly zmienione nie sa tokenizowane (duuuza oszczednosc czasowa)
- pliki ktore byly w cache i zostaly zmodyfikowane sa ponowanie tokenizowane -> aktualizacja cache

Czasy wykonania:
6 klas / 5 plikow:
0.1137sec // bez cache
0.0041 sec // z cache

dodanie dodatkowych plikow i klas, w sumie
355 plikow / 138 klas
4.3358 sec // bez cache
0.1672 z cache// z cache

modyfikacja 3 z tych plikow (glowne pliki Smartyego -- 161kB) i utworznie mapy, z cache
0.7571 sec




Kodu jest sporo: > 470 linii, jak dokoncze to dam linka.
Pozostaje jeszcze fopisac __autoload()'a.

Ten post edytował dr_bonzo 26.05.2005, 15:16:32


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Vengeance
post 26.05.2005, 18:37:05
Post #79





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

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


Z twojego opisu wynika mi, że za każdym uruchomieniem klasy następuje rekurencyjne przejrzenie katalogów. Jeśli tak jest, to jest to tragiczne rozwiązanie :]

Po co te wszystkie "czasy edycji plikow" itp. Na co ci oszczednosc czasowa przy generowaniu mapy, skoro zalozeniem glownym jest ze robisz to tylko raz! Ewentualnie potem gdy cos zmieniasz w strukturze ponawiasz proces generowania.

Twoje "Jak to wyglada w praktyce" wg mnie powinno ograniczac sie tylko do:
1. przejrzenie rekurencyjne wskazanych katalogów
2. tokenizacja każdego pliku celem wyłapania zawartych w nim klas
3. zapisanie wszystkich powiązań klasa=>plik do .ini czy tam .php

A sam główny skrypt powinien tylko ów .ini lub .php wczytywać, zaś gdy go nie ma powinien uruchamiać generowanie ów pliku :]

Taka moja wersja


--------------------
Go to the top of the page
+Quote Post
dr_bonzo
post 26.05.2005, 19:12:28
Post #80





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


Cytat
Z twojego opisu wynika mi, że za każdym uruchomieniem klasy następuje rekurencyjne przejrzenie katalogów. Jeśli tak jest, to jest to tragiczne rozwiązanie :]


Jesli mapa istnieje to ten skrypt nie jest uruchamiany.

Cytat
Na co ci oszczednosc czasowa przy generowaniu mapy, skoro zalozeniem glownym jest ze robisz to tylko raz!


Przy rozbudowie aplikacji i sprawdzaniu poprawnosci jej dzialania nie bedzie mi sie chcialo czekac tych 5 czy 20 sekund na zobaczenie rezultatow.

"W praktyce" to robi + robi to szybciej jesli moze.


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
hawk
post 27.05.2005, 20:47:33
Post #81





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


Ciekawe rozwiązanie. Faktem jest, że mi by się nie chciało smile.gif. Zwłaszcza że ja raczej na początku mam rozplanowane klasy, a potem głównie edytuję zawartość nie ruszając struktury.

Co do plików ini... rezultat ten sam. Dla ciekawości, sprawdzałeś, czy są szybsze od zwykłego php? Chociaż wada jest taka, że ja bym w pliku php bardzo chętnie umieszczał mapę wykorzystując jakąś zmienną - główny katalog projektu. Po to, aby ktoś, kto tego używa, nie musiał generować dla siebie mapy tylko dlatego, że u niego pliki php są w innym miejscu na dysku.
Go to the top of the page
+Quote Post
dr_bonzo
post 5.06.2005, 02:20:39
Post #82





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


W koncu. Kod przepisany od nowa, lecz jeszcze nie dopieszczony:
http://northslope.lap.pl/dev/Autoloader/0.2-dev/

a tu zrodla do pobrania:
http://northslope.lap.pl/dev/Autoloader/au...-0.2-dev.tar.gz
Kod
generowanie mapy (cache puste):
Array
(
   [files_found] => 468
   [files_parsed] => 468
   [classes_found] => 233
)
Map generation time: :: 12.85658 sec

a z cache (nic nie zmienione):
Array
(
   [files_found] => 468
   [files_parsed] => 0
   [classes_found] => 233
)
Map generation time: :: 0.23078 sec

map from php: :: 0.00076 sec
map from ini: :: 0.00412 sec

php szybsze od INI

PSy: statystki (files_parsed)w udostepninych zrodlach sa nieprawidlowe, te wyzej sa ok.
Testowane na P3 @ 560

Ten post edytował dr_bonzo 5.06.2005, 02:21:56


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Imperior
post 5.06.2005, 13:02:34
Post #83





Grupa: Zarejestrowani
Postów: 105
Pomógł: 0
Dołączył: 16.10.2004

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


dr_bonzo: http://wiki.php.pl/index.php/RecursiveDirectoryIterator
Czyż nie łatwiej?


--------------------
Com powiedział, powiedziałem.
Go to the top of the page
+Quote Post
hawk
post 5.06.2005, 13:23:14
Post #84





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


Fajny kod. Nawet zdążyłem już użyć biggrin.gif.

Kilka uwag:
- nie można podać extension np. "class.php", co jest bardzo przydatne, bo pozwala pominąć unit testy ("test.php"). Musiałbyś zmienić metodę isFileExtensionOnTheList tak, aby po prostu sprawdzała, czy nazwa pliku kończy się jednym z podanych wzorców
- przy pierwszym wywołaniu dostaję warning, że cache jeszcze nie istnieje. Potem jest OK.
- RecursiveDirectoryIterator uprościłby sprawę
- przydatną funkcją byłoby parsowanie tagów phpdoc (jeżeli są), aby pomijać klasy "wewnętrzne", czyli takie, które wykorzystywane są tylko w obrębie danego pliku i nie ma potrzeby wystawiać ich na zewnątrz. Ja takich mini-klas używam, i brakuje mi możliwości zrobienia prywatnej klasy wewnętrznej jak w Javie...
Go to the top of the page
+Quote Post
dr_bonzo
post 5.06.2005, 14:00:34
Post #85





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


Cytat
- nie można podać extension np. "class.php", co jest bardzo przydatne, bo pozwala pominąć unit testy ("test.php"). Musiałbyś zmienić metodę isFileExtensionOnTheList tak, aby po prostu sprawdzała, czy nazwa pliku kończy się jednym z podanych wzorców

[DONE] Jest w TODO

Cytat
- przy pierwszym wywołaniu dostaję warning, że cache jeszcze nie istnieje. Potem jest OK.

Kod jeszcze "niedopieszczony" wersja dev -- dziala ok, pokazuje wszystkie bledy na ekranie, potem dodam malpy do funkcji

Cytat
- RecursiveDirectoryIterator uprościłby sprawę

[DONE] Zgadza sie. Poprawie

Cytat
- przydatną funkcją byłoby parsowanie tagów phpdoc (jeżeli są), aby pomijać klasy "wewnętrzne", czyli takie, które wykorzystywane są tylko w obrębie danego pliku i nie ma potrzeby wystawiać ich na zewnątrz.

Troche roboty bedzie. A jaki znacznik odpowiada za plikowy zasieg klasy?

PS. [files_found] to liczba znalezionych plikow z wybranymi rozszerzeniami
-------------------------------------------
EDIT

podglad kodu online
http://northslope.lap.pl/dev/Autoloader/au...-0.3.0-sources/

paczka
http://northslope.lap.pl/dev/Autoloader/au...er-0.3.0.tar.gz

Ten post edytował dr_bonzo 7.06.2005, 11:27:39


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
hawk
post 12.06.2005, 22:16:47
Post #86





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


A co powiecie na taką implementację?
  1. <?php
  2. $i = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(PHIEND_HANDLE_DIR));
  3. $i = new KeyFilter($i, '.class.php$');
  4. $w = new PhiendClassMapWriter('./handle_map.php');
  5. $w->setTargetDir('e:/Web Files/lib/phiend2/phiend.handle', 'PHIEND_HANDLE_DIR');
  6.  
  7. $generator = new ClassMapGenerator();
  8. $generator->addIterator($i);
  9. $generator->setCreator(new BasicClassMapCreator());
  10. $generator->addFilter(new SortClassMapFilter());
  11. $generator->setWriter($w);
  12.  
  13. $generator->run();
  14. ?>

Wynik:
  1. <?php
  2.  
  3. /*
  4.  * File generated by phiend.autoload
  5.  */
  6.  
  7. define('PHIEND_HANDLE_DIR', 'e:/Web Files/lib/phiend2/phiend.handle');
  8.  
  9. $aMap = array(
  10. 'IHandle' => PHIEND_HANDLE_DIR . '/IHandle.class.php',
  11. 'BasicHandle' => PHIEND_HANDLE_DIR . '/BasicHandle.class.php',
  12. // (ciach)
  13. 'SerializedHandle' => PHIEND_HANDLE_DIR . '/SerializedHandle.class.php',
  14. );
  15.  
  16. Autoloader::addMap($aMap);
  17.  
  18. ?>

Mogę tu zrobić praktycznie wszystko, dzięki dobremu rozbiciu na klasy i dziedziczeniu. W pełni wykorzystuje SPL - do tego stopnia, że moje php 5.0.3 jest za stare i musiałem wykomentować kilka linii winksmiley.jpg.
Kod: http://cvs.sourceforge.net/viewcvs.py/phie...hiend.autoload/
Zip: http://phiend.sourceforge.net/misc/phiend-autoload.zip
Go to the top of the page
+Quote Post
cagrET
post 13.06.2005, 13:24:34
Post #87





Grupa: Zarejestrowani
Postów: 90
Pomógł: 0
Dołączył: 3.04.2003
Skąd: Opole

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


offtopic.gif

hawk: widzę, że używasz "notacji węgierskiej", ciekawi mnie czy może czytałeś ten artykuł: http://www.joelonsoftware.com/articles/Wrong.html > I’m Hungary . Joel pisze tam o tym, że w zły sposób używa się notacji węgierskiej, nie w taki jakim intencją autora tej notacji było.


--------------------
code.gosu.pl
Go to the top of the page
+Quote Post
hawk
post 13.06.2005, 20:10:13
Post #88





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


Nie, nie czytałem do tej pory. Przedrostki określające typ stosuję tylko w php, bo tak jest mi wygodniej. W językach ze ścisłą typizacją są mi niepotrzebne.
Go to the top of the page
+Quote Post
matid
post 13.06.2005, 20:30:28
Post #89





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

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


Cytat(hawk @ 2005-06-05 14:23:14)
- przydatną funkcją byłoby parsowanie tagów phpdoc (jeżeli są), aby pomijać klasy "wewnętrzne", czyli takie, które wykorzystywane są tylko w obrębie danego pliku i nie ma potrzeby wystawiać ich na zewnątrz. Ja takich mini-klas używam, i brakuje mi możliwości zrobienia prywatnej klasy wewnętrznej jak w Javie...

Który znacznik phpDoc oznacza klasy wewnętrzne?
Edit: Ale ja jestem ślepy, że nie widziałem wcześniej tego pytania ohmy.gif. Nie zmienia to faktu, że nie udzielono na nie odpowiedzi, więc dołączam się do grona pytających tongue.gif

BTW. Bardzo mi się twój kod podoba, szczególnie te wszechobecne interface i rozdrabnianie tego na wiele klas. Chyba trzeba przepisać mój Autoloader tongue.gif

Ten post edytował matid 13.06.2005, 21:10:21
Go to the top of the page
+Quote Post
dr_bonzo
post 13.06.2005, 21:03:51
Post #90





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


cagrET: link do swietnego serwisu.
Cytat
Z jakiegoś powodu większość ludzi zdaje się rodzić bez tej części mózgu, która jest potrzebna do rozumienia wskaźników
, LOL

hawk: do takiego OOP troche mi jeszcze brakuje smile.gif

notacja wegierska: pamietam jak na poczatku '90 czytalem o tym w pc kurierze -- nawet mam wyrwane strony z tym artem smile.gif


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
hawk
post 13.06.2005, 21:51:34
Post #91





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


@dr_bonzo i matid:
Niestety, phpDocumentor nie ma, AFAIK, takiego znacznika. Szkoda. Chociaż nic nie stoi na przeszkodzie taki sobie stworzyć. Precedens jest - w Javie wiele narzędzi posiada swoje własne znaczniki javadoc. Może @no-autoload?
Go to the top of the page
+Quote Post
matid
post 13.06.2005, 22:12:12
Post #92





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

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


Cytat(hawk @ 2005-06-13 22:51:34)
@dr_bonzo i matid:
Niestety, phpDocumentor nie ma, AFAIK, takiego znacznika. Szkoda. Chociaż nic nie stoi na przeszkodzie taki sobie stworzyć. Precedens jest - w Javie wiele narzędzi posiada swoje własne znaczniki javadoc. Może @no-autoload?

Osobiście byłbym nie za wprowadzeniem znacznika mówiącego o wykluczeniu klasy z autoładowania (choć może to też by był dobry pomysł), lecz znacznika mówiącego o zasięgu klasy.
Czyli prędzej coś jak:
@range: file
@class-range: file
@classrange: file

Oprócz tego można by się pokusić o bardziej rozbudowany sysem autoloadingu, który np. pozwalałby na uwzględnienie takich czynników jak zakres folderowy (@range: directory), no i oczywiście @range: global, czyli to samo co w przypadku gdy pomijamy parametr zasięgu.

To takie moje 3 grosze.

BTW. Jak widzicie wykorzystanie takiego autoloadera w systemie? Czy korzystacie z niego dla całego kodu, czy tylko dla bibliotek? Bo dość niewygodne może być korzystanie z tego w modułach/akcjach. Bo akcja powinna być unikalna w obrębie modułu, ale może się pojawić w innych.

Ten post edytował matid 14.06.2005, 06:28:12
Go to the top of the page
+Quote Post
hawk
post 16.06.2005, 12:17:19
Post #93





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


@matid: Pomysł wręcz genialny w swojej prostocie. Popieram. Jeżeli mamy wybrać najlepszą nazwę, to ja proponuję
Kod
@scope file

Scope, bo to bardziej odpowiednie słowo niż range. Bez dwukropka, bo chyba tagi phpdoc nie używają normalnie dwukropka? W każdym razie ja nigdy nie pisałem...

Co do zastosowania: generalnie używałbym na biblioteki. Albo na intensywnie wykorzystywaną część kodu - zawsze mogę wygenerować sobie mapę np. dla części Modelu. Natomiast dla akcji - nie warto, bo i tak w akcjach musi być porządek, wiadomo dobrze gdzie jaka akcja jest, i wykonujemy jedną akcję na raz. Szkoda mapę robić.
Go to the top of the page
+Quote Post
matid
post 16.06.2005, 15:48:55
Post #94





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

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


No rzeczywiście, @scope będzie lepsze.
Spróbuję to jakoś zaimplementować, zobaczymy, co z tego wyjdzie smile.gif
Cytat(hawk)
Bez dwukropka, bo chyba tagi phpdoc nie używają normalnie dwukropka? W każdym razie ja nigdy nie pisałem...

Literówka winksmiley.jpg Miało być bez.
Cytat(serafin)
Ludzie rozwodzicie sie nad mapa, ktora mozna napisac nawet recznie. A wy tworzycie jakies skrypty bog wie po co i tworzycie nowa teorie do tego. Bezsensu. Zamiast napisac prosty skrypt do tworzenia mapy wy tworzycie 50 klas do wygenerowania tablicy 100 klas.

Ja osobiście wole mieć tablice generowane automatycznie. Nie dość że mogę sobie dowolnie zmieniać położenie klas to w dodatku skrypt przy następnym uruchomieniu sam uaktualnia mapę.

A co do podzielenia na 50 klas. Pierwsza wersja mojego skryptu do autoloadingu to była jedna klasa. Ale po przejrzeniu kodu @hawk widzę, ile jeszcze mojemu OOP brakuje. Dopiero podział tej klasy na kilka mniejszych pokazał mi, o ile większe możliwości w późniejszym rozszerzaniu daje OOP.
Go to the top of the page
+Quote Post
hawk
post 16.06.2005, 18:31:01
Post #95





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


@serafin:

1) Nikt ci nie broni tworzyć takiej mapy ręcznie. Gratuluję odwagi. I nadmiaru wolnego czasu.

2) Bezsensu. Zamiast napisac prosty skrypt do wyświetlania stron wy tworzycie 50 klas, jakieś wzorce, MVC, biblioteki. Przecież każdy wie, że najlepiej jest wrzucić wszystko do jednego pliku, a całe to OOP to jedna wielka ściema.

Pokaż swój autoloader, a wtedy możemy porozmawiać, co jest lepsze, a co jest bez sensu.
Go to the top of the page
+Quote Post
hawk
post 16.06.2005, 20:42:41
Post #96





Grupa: Zarejestrowani
Postów: 521
Pomógł: 0
Dołączył: 3.11.2003
Skąd: 3city

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


Cytat("serafin")
Hawk: Wykorzystales 10 plikow na to co mozna zrobic w jednej klasie (i nie powiedziane ze gorzej).

No dobrze, porozmawiajmy wobec tego konkretnie. Na przykładach. Zaraz zobaczymy, czy rzeczywiście nie gorzej.

1. Chcę włączyć do mapy pliki z katalogów foo/first i foo/second, ale absolutnie nie z foo/third, bo tam są przykłady, które niepotrzebnie zaśmiecałyby mapę.

2. Chcę przeparsować tylko pliki o rozszerzeniu .class.php. Wszystko inne jest niepotrzebne.

3. Chcę, żeby w mojej mapie klasy były posortowane alfabetycznie. Dzięki temu mogę łatwo sprawdzić, jakie klasy są w moim pakiecie, a ponieważ jest to bez różnicy dla przetwarzania, nie ma żadnego powodu, żeby tego nie zrobić. No chyba że narzędzie jest gorsze...

4. Chcę wygenerować mapę dla zewnętrznego pakietu, który inaczej nazywa swoje klasy. Jak narzędzie, to uniwersalne, a nie ograniczone do mojego kodu, prawda? Pakiet jest w zupełnie innym miejscu na dysku.

5. Chcę w wersji produkcyjnej wrzucić kilka klas, które zawsze zawsze są używane, do jednego pliku, żeby przyspieszyć działanie i żeby prościej to wyglądało dla użytkownika końcowego. To częsta praktyka - weźmy np. mojavi.

6. Chcę za pomocą mojego autoloadera wygenerować mapę, która może być od razu wykorzystana w twoim systemie. Czyli plik wygląda tak samo. Chcę mieć uniwersalny autoloader, którego mogą używać inni, a nie nieprzenośne narzędzie.

7. Mam 2 mapy, do 2 różnych pakietów, i chcę obydwie naraz wbić do autoloadera.

Wierzę ci, że można to zrobić w jednej klasie. Która do tego będzie mniejsza niż suma tych plików i w ogóle lepsza. Tylko nie wiem, jak...

A co do tych 10 plików... rozmijasz się z prawdą winksmiley.jpg. To są cztery pliki, plus trzy interfejsy (do niczego niepotrzebne, możesz je spokojnie wywalić, ale ja mam do interfejsów sentyment), plus trzy klasy dziedziczące z klas podstawowych (miałem kaprys zrobić coś extra, ale przecież w ogóle nie musisz ich wykorzystywać). Na podobnej zasadzie możemy zacząć liczyć unit testy i pliki readme.

---------------------------------------------
Cytat
OOP ma sens owszem, ale nie w przypadku gdy tworzy sie klasy na 1-3 metod

Wiesz, co to jest Observer? Abstract Factory? Iterator? Registry? Intercepting Filter? Chain of Responsibility? Command? Strategy? Takie różne wzorce projektowe, ale niestety bez sensu, bo mają za mało metod.

Cytat
Oczywiscie ze rozbijanie problemu na mniejsze czescie jest bardzo dobra technika ale sa pewne granice. Czasami mozna kilka z tych czesci polaczyc w jedna wieksza calosc bez szkody dla ostatecznego rozwiazania.

To ty zacząłeś tą dyskusję, więc odpowiedz: dlaczego rozbijanie problemu na mniejsze klasy jest szkodliwe? Bo z tego, co piszesz, wynika, że wg ciebie jest.
Go to the top of the page
+Quote Post
matid
post 16.06.2005, 22:08:29
Post #97





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

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


Cytat(serafin)
Ma to sens?

A dlaczego nie? Mi osobiście bardzo się podoba sposób potraktowania typów zmiennych jako klas, a samych zmiennych jako obiektów.
Oprócz php programuję też w Javie i uważam to za świetne rozwiązanie, więc dlaczego by nie używać tego w php?

Teraz pewnie padnie pytanie, co mi da takie "utrudnianie" sobie życia. Ale zdecydowaną korzyścią płynącą z takiego rozwiązania jest możliwość programowania własnych typów danych, czego przy standardowym traktowaniu zmiennych przez php nie zrobisz.

Do notki poniżej: Skoro w php są typy podstawowe, to dlaczego miałoby nie być rozszerzonych? Nie będę nikogo nawracał rzucenia podstawowych typów w php na rzecz klas, bo dla niektórych to może być masochizm. Ja osobiście nie mam nic przeciwko smile.gif
A co do pisania w php systemu operacyjnego. Wiem, że to było pytanie retoryczne, ale odpowiem - bo php się do tego kompletnie nie nadaje tongue.gif

A teraz wracając do autoloadera. Zaimplementowałem parsowanie tagów phpDoc, ale jeszcze borykam się z jedym problemem.
Powiedzmy, że moja mapa wygląda tak:
  1. <?php
  2.  
  3. /*
  4. * File generated by OpenForce Autoloader
  5. */
  6.  
  7. $aMap = array(
  8. 'GLOBAL' => array(
  9. 'IteratorFilter' => '/var/www/matid/Current/Autoloader/lib/IteratorFilter.class.php',
  10. 'iClassMapGenerator' => '/var/www/matid/Current/Autoloader/lib/autoloader/interfaces/ClassMapGenerator.interface.php',
  11. 'iClassMapEntry' => '/var/www/matid/Current/Autoloader/lib/autoloader/interfaces/ClassMapEntry.interface.php',
  12. 'iClassMapWriter' => '/var/www/matid/Current/Autoloader/lib/autoloader/interfaces/ClassMapWriter.interface.php',
  13. 'iClassMapCreator' => '/var/www/matid/Current/Autoloader/lib/autoloader/interfaces/ClassMapCreator.interface.php',
  14. 'ClassMapGenerator' => '/var/www/matid/Current/Autoloader/lib/autoloader/ClassMapGenerator.class.php',
  15. 'OFClassMapWriter' => '/var/www/matid/Current/Autoloader/lib/autoloader/OFClassMapWriter.class.php',
  16. 'ClassMapEntry' => '/var/www/matid/Current/Autoloader/lib/autoloader/ClassMapEntry.class.php',
  17. 'ClassMapCreator' => '/var/www/matid/Current/Autoloader/lib/autoloader/ClassMapCreator.class.php',
  18. 'ClassMapWriter' => '/var/www/matid/Current/Autoloader/lib/autoloader/ClassMapWriter.class.php',
  19. 'ClassNotFoundException' => '/var/www/matid/Current/Autoloader/lib/exceptions/ClassNotFoundException.class.php',
  20. 'Autoloader' => '/var/www/matid/Current/Autoloader/lib/Autoloader.class.php',
  21. 'Test2' => '/var/www/matid/Current/Autoloader/test/1/2.php',
  22. 'Test3' => '/var/www/matid/Current/Autoloader/test/3.php',
  23. ),
  24. '/var/www/matid/Current/Autoloader/test/1' => array(
  25. 'Test1' => '/var/www/matid/Current/Autoloader/test/1/1.php',
  26. ),
  27. );
  28.  
  29. Autoloader::addMap( $aMap );
  30.  
  31. ?>

Klasa Test1 ma ustawiony zasięg directory, reszta jest global. I teraz mam taką sytuację:

1. Jakaś klasa próbuje się odwołać do klasy Test1, ale nie znajduje się w tym samym folderze, autoloader rzuca ClassNotFoundException (a w zasadzie tworzy klasę Test1, której kostruktor rzuca wyjątek).
2. Jakaś inna klasa próbuje się odwołać do klasy Test1 i znajduje się w tym samym folderze, niestety, wcześniej została już utworzona klasa Test1, która domyślnie rzuca ClassNotFoundException.

Ma ktoś jakiś inny pomysł na implementację tego? Chyba jedynym wyjściem jest pozbycie się wyjątków z autoloadera, ale może ktoś wymyśli coś innego.

Ten post edytował matid 16.06.2005, 22:23:05
Go to the top of the page
+Quote Post
bela
post 16.06.2005, 22:12:29
Post #98


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

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


Cytat(matid @ 2005-06-16 23:08:29)
Cytat(serafin)
Ma to sens?

A dlaczego nie? Mi osobiście bardzo się podoba sposób potraktowania typów zmiennych jako klas, a samych zmiennych jako obiektów.

To było takie pytanie retoryczne :] Nie ma to sensu. Po co opakowywać typy wbudowane jak i tak nic nie zyskasz, no może poza estetyką kodu winksmiley.jpg

Cytat
Oprócz php programuję też w Javie i uważam to za świetne rozwiązanie, więc dlaczego by nie używać tego w php?

W Javie też są typy podstawowe i jakoś nikt z tego powodu nie umarł :]
Btw. czemu nie piszesz w php systemu operacyjnego winksmiley.jpg

Cytat
Teraz pewnie padnie pytanie, co mi da takie "utrudnianie" sobie życia. Ale zdecydowaną korzyścią płynącą z takiego rozwiązania jest możliwość programowania własnych typów danych, czego przy standardowym traktowaniu zmiennych przez php nie zrobisz.

Emm a czy klasy nie są typami danych?


--------------------
Go to the top of the page
+Quote Post
Imperior
post 17.06.2005, 07:20:58
Post #99





Grupa: Zarejestrowani
Postów: 105
Pomógł: 0
Dołączył: 16.10.2004

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


Cytat(matid @ 2005-06-16 21:08:29)
Ma ktoś jakiś inny pomysł na implementację tego? Chyba jedynym wyjściem jest pozbycie się wyjątków z autoloadera, ale może ktoś wymyśli coś innego.

1. Olać tworzenie pustej klasy
2. Olać zasięgi
3. Każdą klasę tworzyć pośrednio

ad 3. Proxy... zamiast $obj = new Test1(); robić $obj = Class::New('Test1');
A metoda New z Class wszystkim sie zajmie (zwróci instancję, rzuci wyjątek itp)


--------------------
Com powiedział, powiedziałem.
Go to the top of the page
+Quote Post
matid
post 17.06.2005, 07:42:50
Post #100





Grupa: Zarejestrowani
Postów: 362
Pomógł: 0
Dołączył: 18.02.2004
Skąd: Knurów

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


Chyba jednak skorzystam z opcji 1, ponieważ zasięgów nie chcę olewać, a tworzenie instancji przez proxy wyklucza takie przypadki jak dziedziczenie, implementowanie interfaców, itp.
Go to the top of the page
+Quote Post

10 Stron V   1 2 3 > » 
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: 19.05.2024 - 15:33