spl_autoload_register может выполнять такую работу, но я не понимаю, как это делается? 
 spl_autoload_register(array('Doctrine', 'autoload')); 
  Основная идея заключается в том, что вам больше не нужно писать инструкции include / require : всякий раз, когда вы пытаетесь использовать не определенный класс, PHP вызовет автозагрузчик. 
  Тогда задача автозагрузчика – определить, какой файл должен быть загружен, и include его, чтобы класс стал определяться. 
  Затем PHP может использовать этот класс, как если бы вы были тем, кто написал инструкцию include , которая фактически была выполнена в функции автозагрузки. 
«Уловкой» является то, что функция автозагрузки:
  Это и есть причина соглашения об именах, например, PEAR, в котором говорится, что класс, такой как Project_SubProject_Component_Name , сопоставляется с такими файлами, как Project/SubProject/Component/Name.php то есть « _ » в именах классов заменяется с помощью косой черты (каталоги, подкаталоги) в файловой системе. 
  Например, если вы посмотрите на метод Doctrine_Core::autoload , который будет вызываться как автозагрузчик в вашем случае, он содержит эту часть кода (после рассмотрения некоторых конкретных случаев) : 
 $class = self::getPath() . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; if (file_exists($class)) { require $class; return true; } return false; 
  Это означает, что имя класса сопоставляется с файловой системой, заменяя « _ » на « / » и добавляя окончательный .php к имени файла. 
  Например, если вы пытаетесь использовать класс Doctrine_Query_Filter_Chain , и он не известен PHP, будет вызвана функция Doctrine_Core::autoload ;  он определит, что файл, который должен быть загружен, – Doctrine/Query/Filter/Chain.php ;  и поскольку этот файл существует, он будет включен – это означает, что теперь PHP «знает» класс Doctrine_Query_Filter_Chain .