Не удается найти класс с пространством имен PHP

Я ранее сообщал некоторые вопросы об использовании пространств имен в PHP и о том, что я получил, этот примерный код, который у меня ниже, должен работать.

Однако я получаю ошибки, когда я пытаюсь использовать пространство имен в PHP, как это. Вот первая ошибка при запуске кода ниже, как …

Fatal error: Class 'Controller' not found in E:\Controllers\testing.php on line 6 

Файл E: \ Controller \ testing.php

 <?php use \Controller; include('testcontroller.php'); $controller = new Controller; $controller->show(); ?> в <?php use \Controller; include('testcontroller.php'); $controller = new Controller; $controller->show(); ?> 

Файл E: \ Controller \ testcontroller.php

 <?php use \Library\Registry; namespace Controller { class Controller { public $registry; function __construct() { include('E:\Library\Registry.class.php'); $this->registry = new Registry; } function show() { echo $this->registry; echo '<br>Registry was ran inside testcontroller.php<br>'; } } } ?> в <?php use \Library\Registry; namespace Controller { class Controller { public $registry; function __construct() { include('E:\Library\Registry.class.php'); $this->registry = new Registry; } function show() { echo $this->registry; echo '<br>Registry was ran inside testcontroller.php<br>'; } } } ?> 

Файл E: \ Library \ Registry.class.php

 <?php namespace Library\Registry { class Registry { function __construct() { return 'Registry.class.php Constructor was ran'; } } } ?> 

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

Даже при use оператора use вам нужно указать пространство имен класса, который вы пытаетесь создать. Здесь есть много примеров: http://www.php.net/manual/en/language.namespaces.importing.php

Чтобы лучше понять это, я опишу вам, как это работает. В вашем случае, когда вы use \Controller , все пространство имен Controller становится доступным для вас, но не классы, которые находятся в этом пространстве имен. Так, например:

 <?php include('testcontroller.php'); use \Controller; // Desired class is in namespace! $controller = new Controller\Controller(); // Error, because in current scope there is no such class $controller = new Controller(); $controller->show(); ?> в <?php include('testcontroller.php'); use \Controller; // Desired class is in namespace! $controller = new Controller\Controller(); // Error, because in current scope there is no such class $controller = new Controller(); $controller->show(); ?> 

Другой пример:

testcontoller.php:

 <?php namespace Some\Path\To\Controller; class Controller { function __construct() { } function show() { echo '<br>Was run inside testcontroller.php<br>'; } } ?> 

testing.php:

 <?php include('testcontroller.php'); use \Some\Path\To\Controller; // We now can access Controller using only Controller namespace, // not Some\Path\To\Controller $controller = new Controller\Controller(); // Error, because, again, in current scope there is no such class $controller = new Controller(); $controller->show(); ?> в <?php include('testcontroller.php'); use \Some\Path\To\Controller; // We now can access Controller using only Controller namespace, // not Some\Path\To\Controller $controller = new Controller\Controller(); // Error, because, again, in current scope there is no such class $controller = new Controller(); $controller->show(); ?> 

Если вы хотите импортировать именно класс Controller , вам нужно use Controller\Controller – тогда этот класс будет доступен в вашей текущей области.

Не такая хорошая идея назвать пространство имен, как класс, потому что это запутывает (и я думаю, что это то, что здесь происходит). В тот момент, когда вы определяете псевдоним с помощью use Controller это относится либо к классу \Controller , либо к пространству имен \Controller , но ваш класс, поскольку он находится в пространстве имен, называется \Controller\Controller 1

 use Controller; $class = new Controller\Controller; 

или

 $class = new \Controller\Controller; 

или

 use Controller\Controller; $class = new Controller; 

Идея состоит в том, что в тот момент, когда вы пытаетесь получить доступ к классу с его относительным именем, он пытается сопоставить «первую часть» с любым псевдонимом, определенным с use (remeber use MyClass – это то же самое, что use MyClass as MyClass . псевдоним).

 namespace MyNamespace\MyPackage\SomeComponent\And\So\On { class MyClass {} } namespace Another { use MyNamespace\MyPackage\SomeComponent; // as SomeComponent $class = new SomeComponent\An\So\On\MyClass; } 

Как вы можете видеть, PHP находит SomeComponent в качестве первой части и сопоставляет ее с SomeComponent -alias над линией выше.

Вы можете узнать больше об этом в руководстве об пространствах имен .

1 Его называют «Полное имя класса», если вы назовете класс с его полным именем.

Когда вы помещаете Controller класса в Controller пространства имен, вам необходимо ссылаться на него следующим образом:

 $controller = new Controller\Controller(); 

\Controller будет классом в глобальном (по умолчанию) пространстве имен, т. Е. Как будто вы не использовали пространство имен вообще.

Странно я обнаружил, что в моем примере кода из Вопроса выше, если я изменю все Namespace's , которые определены как-то вроде MyLibrary так что это будет как этот код ниже …

Файл E: \ Library \ Registry.class.php

 <?php namespace MyLibrary { class Registry { function __construct() { echo 'Registry.class.php Constructor was ran'; } } } ?> 

Затем, когда я использую use MyLibrary\Registry; в другом файле, я могу получить к нему доступ, как я планировал …

 $this->registry = new Registry; 

Причина, по которой это очень странно для меня, заключается в том, что теперь имя класса также является Namespace . Поэтому мне не нужно было устанавливать пространство имен в «MyLibrary \ Library» для доступа к Registry вместо этого я бы сделал это, как я показал в этом ответе, чтобы иметь доступ к нему, просто называя имя класса.

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

пытаться

 <?php use \Library\Registry; namespace Controller; class Controller { public $registry; function __construct() { include('E:\Library\Registry.class.php'); $this->registry = new Registry; } function show() { echo $this->registry; echo '<br>Registry was ran inside testcontroller.php<br>'; } } ?> в <?php use \Library\Registry; namespace Controller; class Controller { public $registry; function __construct() { include('E:\Library\Registry.class.php'); $this->registry = new Registry; } function show() { echo $this->registry; echo '<br>Registry was ran inside testcontroller.php<br>'; } } ?> 

а также

 <?php namespace Library\Registry; class Registry { function __construct() { return 'Registry.class.php Constructor was ran'; } } ?>