Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Najoptymalniejszy sposób na __autoload z wielu katalogów
Forum PHP.pl > Forum > PHP
Ultear
Witam, zrobiłem __autoload, który wygląda tak o:

  1. $classes_dirs = array('libs/', 'application/controllers/', 'application/models/');
  2.  
  3. function __autoload($class){
  4.  
  5. global $classes_dirs;
  6.  
  7.  
  8.  
  9. try{
  10. require_once(autoload_class_existance($class, $classes_dirs));
  11. } catch(Exception $e){
  12. echo 'Caught exception'.$e->getMessage()."\n";
  13. }
  14. }


funkcja autoload_class_existance:

  1. function autoload_class_existance($class, $dirs){
  2.  
  3. foreach($dirs as $dir){
  4.  
  5. $path = APP_PATH.$dir.$class.'.php';
  6.  
  7. if(file_exists($path)){
  8. return $path;
  9. break;
  10. } else{
  11. continue;
  12. }
  13.  
  14. return false;
  15. }
  16.  
  17. }


Czy jest to dość optymalny sposób, czy da radę zrobić to lepiej?
irekk
A nie lepiej oprzeć to o PSR-0?
pedro84
Zasadnicze pytanie: po co potrzebujesz bawić się w pisanie swojej funkcji ładującej?
Ultear
Nie potrzebuje się bawić, po prostu zastanawiam się na nad najmniejszym i najoptymalniejszym wyjściem smile.gif
pedro84
Poczytaj sobie o klasie ładującej z PSR-0, jak Ci zaproponował @irekk. Z całym szacunkiem, ale wątpię, żebyś coś lepszego wymyślił wink.gif
by_ikar
Taa zwłaszcza że jest już kilkanaście gotowych klas do autoładowania, które istnieją już od jakiegoś czasu, są przetestowane przez dziesiątki ludzi którzy nie tylko piszą w php, ale i go tworzą. Zawsze możesz użyć include_path, który wraca ostatnimi dniami jak bumerang wink.gif
Pyton_000
Proszę bardzo. 10 stron postów. Same dobre rzeczy
Temat: Wlaczanie plikow autoloader
Ultear
Ok, zastosowałem klasę SplClassLoader, teraz tylko jest jeden problem:

Stuktura wygląda tak o:

-root
--application
-----models
-----views
-----controllers
--libs
-----Bootstrap.php



No i sprawa wygląda tak, że:

  1. require_once APP_PATH.'libs/SplClassLoader.php';
  2.  
  3. $loader = new SplClassLoader('Application', __DIR__);
  4. $loader->register();
  5.  
  6.  
  7. $Bootstrap = new Application\Libs\Bootstrap(); //Nie do konca wiem jak z tym postapic, z kolei, bez Application nie moze znaleźć klasy Libs\Bootstrap
  8.  


Bo jezeli chce autoloadowac biblioteke, ktora jest poza katalogiem application, to jest mały problem, bo:


Warning: require(X:\Server\root\Application\Libs\Bootstrap.php) [function.require]: failed to open stream: No such file or directory in X:\Server\blog\libs\SplClassLoader.php on line 152

Co w takim wypadku zrobic?
Pyton_000
libs wpakuj do aplications.
Ultear
Chciałbym później użyć libs w aplikacji backendowej, więc odpada
pedro84
Cytat(Ultear @ 8.09.2014, 22:43:58 ) *
Chciałbym później użyć libs w aplikacji backendowej, więc odpada

Dlaczego? Nie możesz zastosować normalnej struktury?
Kod
src
src/Application
Ultear
Mógłbyś mi rozpisać prawidłową strukture MVC?
Byłbym wdzięczny smile.gif
pedro84
Cytat(Ultear @ 8.09.2014, 23:03:25 ) *
Mógłbyś mi rozpisać prawidłową strukture MVC?

Nie chcę Ci zmartwić, ale... nie ma czegoś takiego smile.gif Obecnie spora część projektów, korzysta z loadera z PSR-0, co wiąże się z pewnymi wymaganiami odnośnie struktury. Zobacz na ten projekt na Githubie: https://github.com/thephpleague/flysystem.

Masz główny katalog src (ewentualnie lib - jest to główny katalog Twojej aplikacji), katalog tests (gdzie siedzą testy). Przykładowa struktura biblioteki z namespacem Foo:
Kod
src/
src/Foo
src/Foo/Parsers
src/Foo/Parsers/HtmlParser
src/Foo/Builder
src/Foo/MenuBuilder


Coś takiego. Mam nadzieję, że załapiesz. Poczytaj sobie poza tym, PSR - warto wiedzieć i wdrażać.
Crozin
1. MVC to jedynie wzorzec architektoniczny i nie ma on ścisłej implementacji - w przeciwieństwie do samej jego definicji.
2. Jeżeli chodzi o strukturę plików w projekcie to właściwie nie ma o czym mówić: PSR-0 oraz jego następna PSR-4 właściwie kończą temat.
3. Jeżeli chodzi o implementację autoloadera to rzuć okiem na tego udostępnianego przez Composera (zresztą w ogóle rzuć okiem na to narzędzie). W środowisku deweloperskim właściwie w pełni przejmuje to zadanie od programisty (można by powiedzieć, że jest to najoptymalniejszy autoloader względem czasu programisty), a w środowisku produkcyjnym wygeneruje Ci zoptymalizowany pod względem czasu działania autoloader.
Ultear
Dziękuje wszystkim za udzielanie się tutaj, będę praktykował standardy narzucane przez PSR, a także zobaczę narzędzie wspomnianie przez @Crozin.

Witam ponownie, by nie zaśmiecać forum piszę tutaj. Mianowicie mam jeszcze jeden problem, napotkałem go przy ładowaniu PDO z SplClassLoader

Kod
Warning: require(C:\WebServ\httpd\mvc\Application\Libs\PDO.php) [function.require]: failed to open stream: No such file or directory in C:\WebServ\httpd\mvc\Application\Libs\SplClassLoader.php on line 152


  1. function __construct(){
  2. $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
  3. try{
  4. $this->db = new PDO($dsn, $this->user, $this->pass, $this->options);
  5. } catch(PDOException $e){
  6. $this->error = $e->getMessage();
  7. }
  8. }


[php][/php]
pedro84
Msz zagadkę ma dziś smile.gif Poprawiłem Twój kod, ale nie wyjaśnię, spróbuj dojść do tego sam, jak będziesz miał problemy, to pisz, ale spróbuj chociaż.

  1. function __construct(){
  2. $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
  3. try{
  4. $this->db = new \PDO($dsn, $this->user, $this->pass, $this->options);
  5. } catch(\PDOException $e){
  6. $this->error = $e->getMessage();
  7. }
  8. }
Ultear
Już widzę wink.gif

Chodzi o \ przy PDO, dziękuje zap moc smile.gif

Z tego co się domyślam jest to nadpisanie przestrzeni nazw, tak?

Niestety wciąż uzyskuje błąd :c

Kod
Warning: require(X:\Server\mvc\Application\Libs\PDO.php) [function.require]: failed to open stream: No such file or directory in X:\Server\blog\Application\Libs\SplClassLoader.php on line 152

Fatal error: require() [function.require]: Failed opening required 'X:\Server\mvc\Application\Libs\PDO.php' (include_path='.;C:\php\pear') in X:\Server\mvc\Application\Libs\SplClassLoader.php on line 152


  1. function __construct(){
  2. $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
  3. try{
  4. $this->db = new \PDO($dsn, $this->user, $this->pass, $this->options);
  5. } catch(\PDOException $e){
  6. $this->error = $e->getMessage();
  7. }
  8. }
pedro84
Nie nadpisanie, ale przestrzeń globalna: http://php.net/manual/en/language.namespaces.global.php.
Ultear
Wciąż mam problem, pomimo dodania \ wciąż autoloader chce mi czytać z Libsów
pedro84
A Ty coś ten autoloader modyfikowałeś? Jeśli tak, wklej go tutaj, aczkolwiek wszystko powinno działać.
Ultear
Nie modyfikowąłem, wygląda standardowo, czyli tak o:

  1. <?php
  2.  
  3. /*
  4.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  5.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  6.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  7.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  8.  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  9.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  10.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  11.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  13.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  14.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  15.  *
  16.  * This software consists of voluntary contributions made by many individuals
  17.  * and is licensed under the MIT license. For more information, see
  18.  * <http://www.doctrine-project.org>.
  19.  */
  20.  
  21. /**
  22.  * SplClassLoader implementation that implements the technical interoperability
  23.  * standards for PHP 5.3 namespaces and class names.
  24.  *
  25.  * <a href="http://groups.google.com/group/php-standards/web/psr-0-final-proposal?pli=1" target="_blank">http://groups.google.com/group/php-standar...-proposal?pli=1</a>
  26.  *
  27.  * // Example which loads classes for the Doctrine Common package in the
  28.  * // Doctrine\Common namespace.
  29.  * $classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine');
  30.  * $classLoader->register();
  31.  *
  32.  * @license <a href="http://www.opensource.org/licenses/mit-license.html" target="_blank">http://www.opensource.org/licenses/mit-license.html</a> MIT License
  33.  * @author Jonathan H. Wage <jonwage@gmail.com>
  34.  * @author Roman S. Borschel <roman@code-factory.org>
  35.  * @author Matthew Weier O'Phinney <matthew@zend.com>
  36.  * @author Kris Wallsmith <kris.wallsmith@gmail.com>
  37.  * @author Fabien Potencier <fabien.potencier@symfony-project.org>
  38.  */
  39. class SplClassLoader
  40. {
  41. private $_fileExtension = '.php';
  42. private $_namespace;
  43. private $_includePath;
  44. private $_namespaceSeparator = '\\';
  45.  
  46. /**
  47.   * Creates a new <tt>SplClassLoader</tt> that loads classes of the
  48.   * specified namespace.
  49.   *
  50.   * @param string $ns The namespace to use.
  51.   */
  52. public function __construct($ns = null, $includePath = null)
  53. {
  54. $this->_namespace = $ns;
  55. $this->_includePath = $includePath;
  56. }
  57.  
  58. /**
  59.   * Sets the namespace separator used by classes in the namespace of this class loader.
  60.   *
  61.   * @param string $sep The separator to use.
  62.   */
  63. public function setNamespaceSeparator($sep)
  64. {
  65. $this->_namespaceSeparator = $sep;
  66. }
  67.  
  68. /**
  69.   * Gets the namespace seperator used by classes in the namespace of this class loader.
  70.   *
  71.   * @return void
  72.   */
  73. public function getNamespaceSeparator()
  74. {
  75. return $this->_namespaceSeparator;
  76. }
  77.  
  78. /**
  79.   * Sets the base include path for all class files in the namespace of this class loader.
  80.   *
  81.   * @param string $includePath
  82.   */
  83. public function setIncludePath($includePath)
  84. {
  85. $this->_includePath = $includePath;
  86. }
  87.  
  88. /**
  89.   * Gets the base include path for all class files in the namespace of this class loader.
  90.   *
  91.   * @return string $includePath
  92.   */
  93. public function getIncludePath()
  94. {
  95. return $this->_includePath;
  96. }
  97.  
  98. /**
  99.   * Sets the file extension of class files in the namespace of this class loader.
  100.   *
  101.   * @param string $fileExtension
  102.   */
  103. public function setFileExtension($fileExtension)
  104. {
  105. $this->_fileExtension = $fileExtension;
  106. }
  107.  
  108. /**
  109.   * Gets the file extension of class files in the namespace of this class loader.
  110.   *
  111.   * @return string $fileExtension
  112.   */
  113. public function getFileExtension()
  114. {
  115. return $this->_fileExtension;
  116. }
  117.  
  118. /**
  119.   * Installs this class loader on the SPL autoload stack.
  120.   */
  121. public function register()
  122. {
  123. spl_autoload_register(array($this, 'loadClass'));
  124. }
  125.  
  126. /**
  127.   * Uninstalls this class loader from the SPL autoloader stack.
  128.   */
  129. public function unregister()
  130. {
  131. spl_autoload_unregister(array($this, 'loadClass'));
  132. }
  133.  
  134. /**
  135.   * Loads the given class or interface.
  136.   *
  137.   * @param string $className The name of the class to load.
  138.   * @return void
  139.   */
  140. public function loadClass($className)
  141. {
  142. if (null === $this->_namespace || $this->_namespace.$this->_namespaceSeparator === substr($className, 0, strlen($this->_namespace.$this->_namespaceSeparator))) {
  143. $fileName = '';
  144. $namespace = '';
  145. if (false !== ($lastNsPos = strripos($className, $this->_namespaceSeparator))) {
  146. $namespace = substr($className, 0, $lastNsPos);
  147. $className = substr($className, $lastNsPos + 1);
  148. $fileName = str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
  149. }
  150. $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . $this->_fileExtension;
  151.  
  152. require ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName;
  153. }
  154. }
  155. }
pedro84
Pokaż swoją strukturę katalogów oraz w którym miejscu masz rzucany ten błąd.
Ultear
pedro84
Mały hint: stałe w tablicy w zmiennej $options.
Ultear
  1. public $options = array(
  2. \PDO::ATTR_PERSISTENT => true,
  3. \PDO::ATR_ERRMODE => \PDO::ERRMODE_EXCEPTION
  4. );


Zapomniałem o tamtym wink.gif

Dziękuje za pomoc haha biggrin.gif
pedro84
Będziesz pamiętał na przyszłość (mam nadzieję smile.gif). Aż się chce takim ludziom pomagać, gdzie mały hint wystarczy, żeby sami doszli do rozwiązania.
Ultear
Dopiero zaczynam tematy z przestrzeniami nazw, dlatego tak smile.gif Jeszcze raz dziękuje za pomoc
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.