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 4 > »   
Reply to this topicStart new topic
> Włączanie plików + autoloader, chętnie bym posłuchał ciekawych pomysłów
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

10 Stron V  < 1 2 3 4 > » 
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: 29.03.2024 - 16:10