Intereting Posts
Использование MySQL, как мне выбрать ранг результата запроса для одной конкретной строки? Какой уникальный идентификатор используется для блогов и комментариев? Можно ли использовать xdebug на Ubuntu? PHP: Может включать файл, который file_exists () говорит, не существует Как получить переданные опции в форме Symfony laravel как перейти на другую функцию в том же контроллере Вызов функции undefined pg_connect () – Wamp PHP: Правильное регулярное выражение для того, чтобы каждая буква слева от первого нижнего регистра двоеточия 3-уровневая развертка столбчатой ​​диаграммы в режиме highchart? Как передать переменную JS в php? Как я могу вызвать функцию в другом файле? Более сжатый способ проверить, содержит ли массив только числа (целые числа) Как использовать настраиваемую PHP-шаблонную систему Функция обратного вызова PHP, не работающая над объектными функциями Вычислить разницу между 2 раза в часах в PHP

PHP: как автозагрузочные интерфейсы и тезисы

У меня есть этот класс автозагрузчика для первоначальной загрузки classes , но теперь я хочу также авторизовать interfaces и abstracts .

Поэтому я внес изменения после этого ответа ,

 $reflection = new ReflectionClass($class_name); # Return boolean if it is an interface. if ($reflection->isInterface()) { $file_name = 'interface_'.strtolower(array_pop($file_pieces)).'.php'; } else { $file_name = 'class_'.strtolower(array_pop($file_pieces)).'.php'; } 

Я тестировал его, но этот класс автозагрузчика вообще не загружает интерфейсы. Любые идеи, что я пропустил?

Например, это мой файл интерфейса,

 interface_methods.php 

и его содержание,

 interface methods { public function delete(); } 

Ниже приведен весь мой класс автозагрузчика .

 class autoloader { /** * Set the property. */ public $directory; public $recursive; public function __construct($directory, $recursive = array('search' => 'models') ) { # Store the data into the property. $this->directory = $directory; $this->recursive = $recursive; # When using spl_autoload_register() with class methods, it might seem that it can use only public methods, though it can use private/protected methods as well, if registered from inside the class: spl_autoload_register(array($this,'get_class')); } private function get_class($class_name) { # List all the class directories in the array. if ($this->recursive) { $array_directories = self::get_recursive_directory($this->directory); } else { if (is_array($this->directory)) $array_directories = $this->directory; else $array_directories = array($this->directory); } # Determine the class is an interface. $reflection = new ReflectionClass($class_name); $file_pieces = explode('\\', $class_name); # Return boolean if it is an interface. if ($reflection->isInterface()) { $file_name = 'interface_'.strtolower(array_pop($file_pieces)).'.php'; } else { $file_name = 'class_'.strtolower(array_pop($file_pieces)).'.php'; } # Loop the array. foreach($array_directories as $path_directory) { if(file_exists($path_directory.$file_name)) { include $path_directory.$file_name; } } } public function get_recursive_directory($directory) { $iterator = new RecursiveIteratorIterator ( new RecursiveDirectoryIterator($directory), RecursiveIteratorIterator::CHILD_FIRST ); # This will hold the result. $result = array(); # Loop the directory contents. foreach ($iterator as $path) { # If object is a directory and matches the search term ('models')... if ($path->isDir() && $path->getBasename() === $this->recursive['search']) { # Add it to the result array. # Must replace the slash in the class - dunno why! $result[] = str_replace('\\', '/', $path).'/'; //$result[] = (string) $path . '/'; } } # Return the result in an array. return $result; } } 

PHP не имеет никакого значения между любым классом или интерфейсом или абстрактным классом. Функция автозагрузчика, которую вы определяете, всегда получает имя объекта для автозагрузки, и никакой намек на то, какой он был.

Таким образом, ваша стратегия именования не может быть автоматически загружена, потому что вы префиксные интерфейсы с «интерфейсом» и классами с «class_». Лично я считаю такое соглашение об именах довольно раздражающим.

С другой стороны, ваш автозагрузчик полностью неэффективен. Он рекурсивно сканирует все деревья каталога, чтобы найти один класс! И следующий класс должен снова выполнить всю работу, не имея возможности сделать это раньше!

Пожалуйста, используйте автозагрузчик PSR-0, если вы действительно хотите сделать это самостоятельно (а не использовать такие вещи, как композитор, чтобы сделать это для вас) и придерживаться этой схемы именования для классов и интерфейсов.

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

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