Я ранее сообщал некоторые вопросы об использовании пространств имен в 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'; } } ?>