Не удается найти класс с пространством имен PHP - PullRequest
22 голосов
/ 23 декабря 2011

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

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

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

E: \ Controller \ testing.php File

<?php
use \Controller;

include('testcontroller.php');

$controller = new Controller;
$controller->show();
?>

E: \ Controller \ testcontroller.php File

<?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 File

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

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

Ответы [ 5 ]

33 голосов
/ 23 декабря 2011

Даже при использовании оператора 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();
?>

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

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();
?>

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

8 голосов
/ 23 декабря 2011

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

use Controller;
$class = new Controller\Controller;

или

$class = new \Controller\Controller;

или

use Controller\Controller;
$class = new Controller;

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

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 -алиасом строкой выше.

Подробнее об этом можно прочитать в руководстве по пространствам имен .

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

5 голосов
/ 23 декабря 2011

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

$controller = new Controller\Controller();

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

2 голосов
/ 23 декабря 2011

Странно, но я обнаружил, что в моем примере кода из Вопроса выше, если я изменю все 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, вместо этого я бы сделал это так, как я показал в этом ответе, чтобы получить доступ к нему, просто вызвав имя класса.

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

0 голосов
/ 23 декабря 2011

1001 * попробовать *

<?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';
    }
}
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...