2011-12-22 20 views
12

Ho pubblicato alcune domande precedentemente riguardanti l'uso di Namespace in PHP e da quello che ho ottenuto, questo codice di esempio che ho qui sotto dovrebbe funzionare.Impossibile trovare la classe con lo spazio dei nomi PHP

Tuttavia sto ricevendo errori quando provo a utilizzare Namespace in PHP come questo. Ecco il primo errore quando si esegue il codice qui sotto come è ...

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: file \ Libreria \ Registry.class.php

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

Come puoi vedere ho cercato di renderlo il più semplice possibile solo per far funzionare la parte Namespace. Ho provato diverse varianti e non riesco a capirlo.

risposta

22

Anche quando si utilizza l'istruzione use, è necessario specificare lo spazio dei nomi della classe che si sta tentando di creare un'istanza. Ci sono molti esempi qui: http://www.php.net/manual/en/language.namespaces.importing.php

Per capirlo meglio, ti descriverò come funziona. Nel tuo caso, quando esegui lo use \Controller, l'intero spazio dei nomi Controller diventa disponibile per te, ma non le classi che si trovano in questo spazio dei nomi. Così, per esempio:

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

Un altro esempio:

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

Se si desidera importare esattamente la Controllerclasse, devi fare use Controller\Controller - allora questa classe sarà accessibile nel tuo ambito attuale.

+0

Buon esempio, l'ho capito ieri sera ma è buono per te descriverlo. Quindi penso che sarebbe meglio mettere tutte le 'classi della libreria' nello stesso spazio dei nomi come 'Library' e quindi sul testcontroller precedente potrei usare' use Library \ Classname' per ogni classe nella mia libreria che mi serve in quel controller quindi posso quindi valutarli come questo 'nuovo Registro di sistema 'ecc ... su http://www.php.net/manual/en/language.namespaces.importing.php Penso che stia dicendo che sta importando un class' quindi non ero sicuro se fosse una cattiva idea – JasonDavis

+0

Sto cercando di limitare le dipendenze di ogni classe, ecco perché per me non è difficile usare il nome completo per la classe. – Timur

+0

Questo è sbagliato: con 'use' si definisce anche un alias per una classe concreta. Nell'esempio 'use \ Controller; nuovo controller; 'non è molto ovvio, ma puoi provare' use Vendor \ Package \ Component \ Controller; nuovo controller'. Cosa intendo: è sbagliato, è necessario definire lo spazio dei nomi di una classe _in ogni caso_. Vedi il link nel commento di jasondeavis. Come descritto, come PHP risolve i nomi di classi relativi. – KingCrunch

5

Quando si inserisce una classe Controller nello spazio dei nomi Controller, poi si deve fare riferimento in questo modo:

$controller = new Controller\Controller(); 

\Controller sarebbe una classe nel (default) namespace globale, vale a dire come se si è utilizzato alcun spazio dei nomi.

+0

non pensate di doverlo fare a causa dell'istruzione "use Controller;" – Ascherer

+0

@Cassy sì, è per questo che ho usato "use Controller;" quindi spero di non dover fare quel metodo più brutto – JasonDavis

+0

@Casey ho provato è comunque solo per vedere cosa succederebbe e ha cambiato l'errore in 'Errore irreversibile: Classe 'Controller \ Registry'' – JasonDavis

0

provare

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

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

Ho fatto una prova ma non ho ancora avuto lo stesso messaggio di errore – JasonDavis

2

Stranamente Ho scoperto che nel mio codice di esempio dalla domanda di cui sopra, se cambio tutto il Namespace's che sono definite a qualcosa di simile MyLibrary quindi sarebbe essere come questo codice qui sotto ...

E: \ Library \ Registry.class.php File

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

Poi quando uso use MyLibrary\Registry; in un altro file, sono in grado di accedervi come avevo previsto ...

$this->registry = new Registry; 

Il motivo di questo è molto strano per me è questo ora che fa un il nome della classe sembra essere anche uno Namespace. Quindi non avrei bisogno di impostare un Namespace su "MyLibrary \ Library" per accedere allo Registry, invece lo farei come mostrato in questa risposta per poterlo accedere con il solo nome della classe.

Spero che questo abbia un senso e aiuti qualcun altro. Non accetterò questo come risposta come spero che qualcuno con più know-how arriverà e pubblicherà una risposta migliore con spiegazione

6

Non è una buona idea denominare lo spazio dei nomi, come la classe, perché è confuso (e penso che questo sia quello che succede qui).Ci momento in cui si definiscono l'alias tramite use Controller questo referenes o ad una classe di \Controller, o lo spazio dei nomi \Controller, ma la classe, perché è all'interno dello spazio dei nomi, è chiamato \Controller\Controller1

use Controller; 
$class = new Controller\Controller; 

o

$class = new \Controller\Controller; 

o

use Controller\Controller; 
$class = new Controller; 

l'idea è che il momento in cui si tenta di ac terminare una classe con il relativo nome prova a mappare la "prima parte" rispetto a qualsiasi alias definito utilizzando use (il riferimento use MyClass corrisponde a use MyClass as MyClass. La cosa dopo lo as è l'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; 
} 

Come si può vedere PHP trova SomeComponent come la prima parte e la mappa contro il SomeComponent -alias riga sopra.

Ulteriori informazioni a riguardo sono disponibili nel numero manual about namespaces.

1 È chiamato "Nome classe completo", se si nomina una classe con il nome completo.

Problemi correlati