PHP5 автозагрузчик SPL_AutoLoad не работает - PullRequest
4 голосов
/ 02 сентября 2011

У меня есть код ниже в качестве класса автозагрузки, однако кажется, что метод clean просто не работает, и он всегда прибегает к методу dirty.

Я неправильно использую spl_autoload? Если так, каков правильный (лучший) способ? Разве это неэффективно, как это можно улучшить?

Я всегда получаю вывод, такой как дно, когда использую этот метод, и в некоторых случаях он просто не находит класс, но не выдает никакой ошибки У меня есть ошибки отображения, равные 1 и проверил журнал ошибок, но просто полностью отсутствует.

Код инициализируется как

require "vendor/AutoLoader.class.php";
self::setGlobal("autoloader", AutoLoader::init());

И класс выглядит следующим образом:

public static $instance;
private $_src=array('vendor/', 'lib/', '');
private $_sub=array('base/', '');
private $_ext=array('.php', 'class.php', 'lib.php');

/* initialize the autoloader class */
public static function init(){
    if(self::$instance==NULL){
        self::$instance=new self();
    }
    return self::$instance;
}

/* put the custom functions in the autoload register when the class is initialized */
private function __construct(){
    spl_autoload_register(array($this, 'clean'));
    spl_autoload_register(array($this, 'dirty'));
}

/* the clean method to autoload the class without any includes, works in most cases */
private function clean($class){
    $class=str_replace('_', '/', $class);
    spl_autoload_extensions(implode(',', $this->_ext));
    foreach($this->_src as $resource){
      foreach($this->_sub as $sub){
        echo 'Trying to load ', $class, ' via ', __METHOD__, "()<br />";
        set_include_path(pegFramework::getGlobal("baseDir") . $resource.$sub);
        spl_autoload($class);
        if(class_exists($class)) {
          echo 'Found and clean included '.$class.' in '.$resource.$sub."<br />";
          break 2;
        }
      }
    }
}

/* the dirty method to autoload the class after including the php file containing the class */
private function dirty($class){
    global $docroot;
    $class=str_replace('_', '/', $class);
    foreach($this->_src as $resource){
        foreach($this->_ext as $ext){
          foreach($this->_sub as $sub){
            echo 'Trying to load ', $class, ' via ', __METHOD__, "()<br />";
            if(@include(pegFramework::getGlobal("baseDir") . $resource . $sub. $class . $ext)) {
              echo 'Found and dirty included '.$class.' as '.$resource . $sub. $class . $ext."<br />";
              break 3;
            }
          }
        }
    }
    spl_autoload($class);
}

Trying to load pegDatabase via pegAutoloader::clean()
...snip...
Trying to load pegDatabase via pegAutoloader::clean()
Trying to load pegDatabase via pegAutoloader::dirty()
Trying to load pegDatabase via pegAutoloader::dirty()
Trying to load basepegDatabase via pegAutoloader::clean()
...snip...
Trying to load basepegDatabase via pegAutoloader::clean()
Trying to load basepegDatabase via pegAutoloader::dirty()
Found and dirty included basepegDatabase as vendor/base/basepegDatabase.php
Found and dirty included pegDatabase as vendor/pegDatabase.php
Trying to load pegRequest via pegAutoloader::clean()
...snip...
Trying to load pegRequest via pegAutoloader::clean()
Trying to load pegRequest via pegAutoloader::dirty()
Trying to load pegRequest via pegAutoloader::dirty()
Found and dirty included pegRequest as vendor/pegRequest.php
Trying to load pegFacebook via pegAutoloader::clean()
...snip...
Trying to load pegFacebook via pegAutoloader::clean()
Trying to load pegFacebook via pegAutoloader::dirty()
...snip...
Trying to load pegFacebook via pegAutoloader::dirty()
Trying to load Facebook via pegAutoloader::clean()
Trying to load Facebook via pegAutoloader::clean()
...snip...
Trying to load Facebook via pegAutoloader::dirty()
Trying to load Facebook via pegAutoloader::dirty()
Trying to load Facebook via pegAutoloader::dirty()
...snip...
Trying to load Facebook via pegAutoloader::dirty()
Trying to load Facebook via pegAutoloader::dirty()
...snip...
Trying to load Facebook via pegAutoloader::dirty()

1 Ответ

2 голосов
/ 12 сентября 2011

Я думаю, что вызов spl_autoload сбивает вас с толку.В комментариях к документации php я обнаружил this :

Обратите внимание, что эта функция LOWERCASE ищет имена классов, которые она ищет, не путайте, когда онане могу найти Foo_Bar.php

Итак, вызовы spl_autoload с pegFacebook или Facebook просто инициируют поиск файлов с именами pegfacebook.php или facebook.class.php.

На вашем месте я бы посмотрел UniversalClassLoader от Symfony, чтобы найти примеры гораздо более упрощенной обработки загрузки классов.Возможно, вы могли бы настроить его для использования определенных расширений, но я бы хотя бы подумал о том, чтобы найти новый способ решения этой проблемы.

...