2011-12-22 3 views
12

Я уже задал некоторые вопросы относительно использования пространств имен в 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(); 
?> 

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>'; 
     } 
    } 
} 
?> 

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

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

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

ответ

22

Даже при использовании инструкции 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 - тогда этот класс будет доступен в вашей текущей области.

+0

Хороший пример, я понял это вчера вечером, но хорошо для вас, чтобы описать это. Поэтому я думаю, что мне было бы лучше поставить все мои «Библиотечные классы» в такое же пространство имен, как «Библиотека», а затем на тестовом контролере выше я мог бы использовать «использовать библиотеку \ класс» для каждого класса в моей библиотеке, который мне нужен в этом поэтому я могу оценить их как этот «новый реестр» и т. д. на http://www.php.net/manual/en/language.namespaces.importing.php. Думаю, это говорит о том, что это «импорт глобального class', поэтому я не был уверен, что это была плохая идея. – JasonDavis

+0

Я пытаюсь ограничить зависимости каждого класса, поэтому для меня нетрудно использовать полное квалифицированное имя для класса. – Timur

+0

Thats wrong: с 'use' вы также определяете псевдоним для конкретного класса. В примере 'use \ Controller; новый контроллер, 'его не очень очевидно, но вы можете попробовать 'использовать Vendor \ Package \ Component \ Controller; новый контроллер. Я имею в виду: неправильно, что вам нужно определить пространство имен класса _ в каждом случае. См. Ссылку в комментарии jasondeavis. Описывается, как PHP разрешает относительные имена классов. – KingCrunch

5

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

$controller = new Controller\Controller(); 

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

+0

Не думайте, что вам нужно это сделать из-за 'use Controller;' statement – Ascherer

+0

@ Касси, да, поэтому я использовал 'use Controller', поэтому надеюсь, что мне не пришлось бы делать этот уродливый метод – JasonDavis

+0

@Casey Я попробовал в любом случае, просто посмотреть, что произойдет, и это изменило ошибку на «Неустранимая ошибка: Class 'Controller \ Registry» ' – JasonDavis

0

попробовать

<?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'; 
    } 
} 
?> 
+0

Я дал эту попытку, но не повезло по прежнему тому же сообщению об ошибке – JasonDavis

2

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

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

6

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

use Controller; 
$class = new Controller\Controller; 

или

$class = new \Controller\Controller; 

или

use Controller\Controller; 
$class = new Controller; 

идея заключается в том, что момент вы пытаетесь переменного тока cess класс с его относительным именем, он пытается сопоставить «первую часть» с любым псевдонимом, определенным с помощью use (remeber 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 -alias в строке выше.

Подробнее об этом можно узнать в manual about namespaces.

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

Смежные вопросы