2015-04-07 4 views
1

Я установил простую автозагрузку, чтобы понять принципы при работе вместе с пространствами имен.PHP - пространства имен и проблемы с автозагрузкой

test.php:

namespace House; 

function __autoload($classname) 
{ 
    $parts = explode('\\', $classname); 

    $class = 'Room/'.end($parts).'.php'; 

    require_once($class); 
} 


$Toy = new Toy(); 
echo $Toy->hello(); 

номер/Toy.php:

namespace House; 

class Toy 
{ 
    public function hello() { return "HELLO"; } 
} 

При объявлении $ Игрушку я получаю Фатальная ошибка: класс 'Дом \ Игрушка' не найден in test.php on line 18

Что я здесь делаю?

При удалении функции __autoload и вместо того, чтобы просто положить в

require_once('Room/Toy.php'); 

Это работает!

ответ

1

Ваш test.php должен выглядеть следующим образом:

use House\Toy as Toy; 

function __autoload($classname) 
{ 
    $parts = explode('\\', $classname); 
    $class = 'Room/'.end($parts).'.php'; 
    require_once($class); 
} 

$Toy = new Toy(); 
echo $Toy->hello(); 

Если вы ставите namespace House на верхней части файла, все функции, объявленные в этом файле будет принадлежать к пространству имен House. Значение __autoload() get's House\__autoload() и потеряет его magic значение.

Другое дело, не лучше ли хранить файлы пространства имен House в папке с именем House? (В настоящее время вы используете Room). Если вы делаете так, то функция __autoload() может быть записана в более общем плане:

function __autoload($classname) 
{ 
    $parts = explode('\\', $classname); 
    $path = implode('/', $parts) . '.php'; 
    require_once($path); 
} 
+0

Вы имеете в виду, что __autoload не называется вообще, если пространство имен объявлено перед ним? Я знаю, что структура плохая, это я экспериментирую, чтобы понять пространства имен на самом деле. – DJJQ

+0

Да, я имел в виду это. Он не вызывается, так как он не реализован. Вы только реализовали 'House \ __ autoload()', но PHP будет вызывать '\ __ autoload()', что означает '__autoload()', определяемый в глобальном пространстве имен. Однако вы можете использовать любую функцию из любого пространства имен (и/или класса), которое вы хотите, используя 'spl_autoload_register()'. – hek2mgl

+0

Хорошо, теперь я понял. Спасибо вам за помощь! – DJJQ

0

Попробуйте использовать этот автозагрузчик вместо :) и добавить абсолютный путь к каталогу номеру к вашему включить путь. Внутри комнаты есть другой каталог под названием House, где будет находиться Toy.php.

<?php 

spl_autoload_register (function ($className, $fileExtensions = null) { 
    $className = str_replace ('_', '/', $className); 
    $className = str_replace ('\\', '/', $className); 
    $file = stream_resolve_include_path ($className . '.php'); 
    if ($file !== false) { 
     include $file; 
     return true; 
    } 
    return false; 
}); 
Смежные вопросы