2011-12-22 12 views
12

Publiqué algunas preguntas con anterioridad sobre el uso de Namespaces en PHP y, por lo que obtuve, este código de ejemplo que tengo a continuación debería estar funcionando.No se puede encontrar la clase con PHP Namespace

Sin embargo, recibo errores cuando trato de usar Namespace en PHP de esta manera. Aquí está el primer error cuando se ejecuta el código de abajo como es ...

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

E: \ Controller \ testing.php archivo

<?php 
use \Controller; 

include('testcontroller.php'); 

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

E: \ Controller \ testcontroller.php archivo

<?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: \ Biblioteca \ Registry.class.php archivo

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

Como puedes ver, traté de hacerlo lo más simple posible para que funcione la parte del espacio de nombres. He intentado diferentes variaciones y parece que no puedo entenderlo.

Respuesta

22

Incluso cuando usa la instrucción use, necesita especificar el espacio de nombres de la clase que está intentando crear una instancia. Aquí hay muchos ejemplos: http://www.php.net/manual/en/language.namespaces.importing.php

Para entenderlo mejor, le describiré cómo funciona. En su caso, cuando lo hace use \Controller, el espacio de nombres entero Controller estará disponible para usted, pero no las clases que se encuentran en este espacio de nombres. Así, por ejemplo:

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

Otro ejemplo:

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

Si desea importar exactamente el Controllerclase, necesita hacer use Controller\Controller - entonces esta clase estará accesible en su alcance actual.

+0

Buen ejemplo, lo descubrí anoche pero es bueno para ti describirlo. Así que creo que sería mejor que coloque todas mis 'Bibliotecas 'en el mismo espacio de nombres como' Biblioteca' y luego en el controlador de prueba anterior podría usar 'Usar Biblioteca \ Nombre de clase' para cada clase en mi biblioteca que necesito en ese controlador para que pueda evaluarlos así '' nuevo Registro', etc. en http://www.php.net/manual/en/language.namespaces.importing.php Creo que está diciendo que esto es 'importar un global class' así que no estaba seguro de si era una mala idea – JasonDavis

+0

Estoy tratando de limitar las dependencias de cada clase, por eso para mí no es difícil usar un nombre completamente calificado para la clase. – Timur

+0

Eso está mal: con 'use' también defines un alias para una clase concreta. En el ejemplo 'use \ Controller; nuevo controlador; 'no es muy obvio, pero puede intentar' usar Vendor \ Package \ Component \ Controller; nuevo controlador'. Lo que quiero decir: es incorrecto, que necesitas definir el espacio de nombres de una clase _en todos los casos_. Ver el enlace en el comentario jasondeavis. Se describe cómo PHP resuelve los nombres de clase relativos. – KingCrunch

5

Cuando se pone una clase Controller en el espacio de nombres Controller, entonces usted tiene que hacer referencia a ella de esa manera:

$controller = new Controller\Controller(); 

\Controller habría una clase en el espacio de nombres global (por defecto), es decir, como si se ha utilizado ningún espacio de nombres en absoluto.

+0

No creo que deba hacer eso debido a la instrucción 'use Controller;' – Ascherer

+0

@Cassy Sí, es por eso que utilicé 'use Controller;' así que con suerte no tendría que hacer ese método más feo – JasonDavis

+0

@Casey Probé de todos modos solo para ver qué pasaría y cambió el error a 'Fatal error: Class 'Controller \ Registry'' – JasonDavis

0

tratar

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

y

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

Lo intenté pero aún no tuve suerte el mismo mensaje de error – JasonDavis

2

extraño que he encontrado que en mi ejemplo de código de la pregunta anterior, si cambio de toda la Namespace's que se definen a algo así como MyLibrary por lo que sería ser como este código a continuación ...

E: \ Library \ Registry.class.php Archivo

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

Entonces cuando uso use MyLibrary\Registry; en otro archivo, soy capaz de acceder a él cómo había planeado ...

$this->registry = new Registry; 

La razón de esto es muy extraño para mí es esto ahora tiene una el nombre de clase parece ser un Namespace también. Así que no necesitaría establecer un Namespace en 'MyLibrary \ Library' para acceder al Registry sino que lo haría como lo mostré en esta respuesta para poder acceder con solo llamar al nombre de la clase.

Espero que esto tenga sentido y ayude a otra persona. No aceptaré esto como la respuesta, ya que espero que alguien con más conocimientos ingrese y publique una mejor Respuesta con explicación

6

No es buena idea nombrar el espacio de nombres, como la clase, porque es confuso (y creo que esto es lo que sucede aquí).Hay momento en que se defina el alias a través de use Controller este referencias al respecto ya sea a una clase \Controller, o el espacio de nombres \Controller, pero su clase, ya que se encuentra dentro del espacio de nombres, se nombra \Controller\Controller1

use Controller; 
$class = new Controller\Controller; 

o

$class = new \Controller\Controller; 

o

use Controller\Controller; 
$class = new Controller; 

la idea es, que en el momento de intentar ac Como clase con su nombre relativo, intenta mapear la "primera parte" contra cualquier alias definido usando use (recuerda use MyClass es lo mismo que use MyClass as MyClass. La cosa después de as es el alias).

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

Como se puede ver php encuentra SomeComponent como la primera parte y lo asigna en contra de la SomeComponent -alias la línea anterior.

Puede leer más al respecto en el manual about namespaces.

1 Se denomina "Clase completa", si se nombra una clase con su nombre completo.

Cuestiones relacionadas