2010-07-21 5 views
3

Я пытаюсь преобразовать несколько сценариев php для использования функции __autoload. Сейчас я могу использовать включать и требуют такие функции, как это:include path и функция __autoload в php

require_once('path/to/script.php'); 

Но внутри функции __autoload, я не могу использовать линию выше. Я должен использовать это:

require_once('absolute/path/to/script.php'); 

Почему кажется, как будто функция __autoload не использует включаемые путь я указанный в php.ini?

+0

Технически это не ответ на ваш вопрос, но вы могли бы найти это полезным поэтому я поставлю это как комментарий: так как все ваши включения теперь проходят через автозагрузку, зачем вообще беспокоиться о пути php.ini?Вы можете просто определить папку include относительно файла, который содержит функцию автозагрузки. Например, если файл находится в корневом каталоге и включает в себя/include/then, просто добавьте 'include /' внутри автозагрузки. –

+0

Не могли бы вы предоставить вывод 'echo get_include_path();'? Единственный случай, когда я могу думать, что это может произойти, - это когда '.' не входит в ваш путь включения. – NikiC

+0

@nikic: Там я проверяю использование этого утверждения эха, а также, глядя на сам файл php.ini. – cskwrd

ответ

9

Не используйте __autoload ... У этого есть несколько недостатков (включая ограничение на один за выполнение). Вместо этого используйте spl_autoload_register, если вы в 5.2+.

Так что я обычно делаю, это есть класс:

class AutoLoader { 
    protected static $paths = array(
     PATH_TO_LIBRARIES, 
    ); 
    public static function addPath($path) { 
     $path = realpath($path); 
     if ($path) { 
      self::$paths[] = $path; 
     } 
    } 
    public static function load($class) { 
     $classPath = $class; // Do whatever logic here 
     foreach (self::$paths as $path) { 
      if (is_file($path . $classPath)) { 
       require_once $path . $classPath; 
       return; 
      } 
     } 
    } 
} 
spl_autoload_register(array('AutoLoader', 'load')); 

Таким образом, если вы добавить набор библиотек, вы можете просто «добавить его» своим дорожкам по телефону AutoLoader::AddPath($path);. Это делает тестирование с вашим автозагрузчиком более легким (IMHO).

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

Лично мне не нравится использовать относительные пути с включенными. Особенно с несколькими включенными каталогами (например, груша), очень сложно точно узнать, какой файл импортируется, когда вы видите require 'foo/bar.php';. Я предпочитаю определять абсолютный путь в начале набора файлов define('PATH_ROOT', dirname(__FILE__));, а затем определять все мои другие полезные пути из этого каталога (PATH_LIBRARIES, PATH_TEMPLATES и т. Д.). Таким образом, все абсолютно определено ... И не нужно иметь дело с относительными путями (например, вопрос, который у вас сейчас есть) ...

0

Не уверен, не видя всей настройки. Моя функция автозагрузки находится в моем глобальной функции файл, и выглядит следующим образом:

function __autoload($class) { 
    if (file_exists("includes/{$class}.php")) { 
     require_once("includes/{$class}.php"); 
    } 
    /** 
    * Add any additional directories to search in within an else if statement here 
    */ 
    else { 
     // handle error gracefully 
    } 
} 

Я использую относительный путь, потому что скрипт включен в моем index.php файле и все HTTP-запросы проходят через него.

+0

Кажется, что часть вашего ответа была отрезана по какой-то причине. Часть после «потому что» отсутствует. – NikiC

+0

Спасибо! Не знаю, что там произошло. –

0

Я подозреваю, что ваша функция __autoload() находится в отдельном файле, а затем код, который его называет. Путь к включенным файлам будет относиться к файлу, который содержит объявление функции __autoload().

+0

Я тоже так думал, но затем я использовал настройку в файле php.ini под названием «auto_prepend_file» и файл, содержащий функцию __autoload в папке, где начинаются все относительные пути, и это все равно не сработает. – cskwrd

+0

-1, потому что я думаю, что этот ответ неверен (поправьте меня, если это я, кто не прав): Насколько я знаю, файл включен относительно сценария exeucted. То есть, если вызывается index.php, но автозагрузка находится в foo/bar/autoload.php, все же путь будет разрешен относительно index.php. PHP будет только возвращаться к foo/bar в качестве последнего шага, после попытки всех include_paths. – NikiC

0

Похоже, что . не входит в ваш путь включения. Поэтому добавьте его:

set_include_path('.' . PATH_SEPARATOR . get_include_path()); 

Теперь PHP должен выглядеть относительно исполняемого каталога сценариев. (Выполненный сценарий здесь что-то вроде index.php, не autoload.php.

Но почему не использовать просто использовать обычный относительный путь ./path/to/class.php?

+0

'.' уже в пути. '.' относится к текущему рабочему каталогу текущего файла (другими словами, он эквивалентен' dirname (__ FILE __) ') ... Вот почему он отлично работает с одним файлом, но не с другим (потому что относительный рабочий каталог изменения между ними) ... – ircmaxell

+0

@ircmaxell: И вы действительно уверены, что то, что вы говорите, верно? У меня был опыт, что PHP рассматривает каталог как cwd, там есть * первоначально выполненный скрипт, а не файл, который вы включаете из лжи. [Дополнительная информация (хотя немецкий)] (https://www.lima-city.de/thread/inclusion-path-resolution) и мой [класс разрешения пути] (http://github.com/nikic/prephp/blob /master/prephp/classes/Path.php). (Класс разрешения еще не совершенен.) – NikiC

 Смежные вопросы

  • Нет связанных вопросов^_^