J'ai déjà posté quelques questions concernant l'utilisation des espaces de noms dans PHP. D'après ce que j'ai obtenu, cet exemple de code ci-dessous devrait fonctionner.
Cependant, je reçois des erreurs lorsque j'essaie d'utiliser Namespace dans PHP comme ceci. Voici la première erreur lors de l'exécution du code ci-dessous tel quel ...
Fatal error: Class 'Controller' not found in E:\Controllers\testing.php on line 6
Fichier E:\Controller\testing.php
<?php
use \Controller;
include('testcontroller.php');
$controller = new Controller;
$controller->show();
?>
Fichier 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>';
}
}
}
?>
Fichier E:\Library\Registry.class.php
<?php
namespace Library\Registry
{
class Registry
{
function __construct()
{
return 'Registry.class.php Constructor was ran';
}
}
}
?>
Comme vous pouvez le constater, j’ai essayé de rendre la chose aussi simple que possible, simplement pour que la partie Namespace fonctionne. J'ai essayé différentes variantes et n'arrive pas à comprendre.
Même lorsque vous utilisez l'instruction use
, vous devez spécifier l'espace de nom de la classe que vous essayez d'instancier. Il existe de nombreux exemples ici: http://www.php.net/manual/fr/language.namespaces.importing.php
Pour mieux le comprendre, je vais vous décrire comment cela fonctionne. Dans votre cas, lorsque vous utilisez use \Controller
, tout l'espace de noms Controller
devient disponible, mais pas les classes qui se trouvent dans cet espace de noms. Donc, par exemple:
<?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 autre exemple:
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 vous souhaitez importer exactement la Controller
class, vous devez faire use Controller\Controller
- cette classe sera accessible dans votre portée actuelle.
Ce n’est pas une bonne idée de nommer l’espace de noms, comme la classe, parce que cela prête à confusion (et je pense que c’est ce qui se passe ici). À ce moment, vous définissez l’alias via use Controller
qui se réfère soit à une classe \Controller
, soit à l’espace de nommage \Controller
, mais votre classe, parce qu’elle se trouve dans l’espace de nommage, est nommée \Controller\Controller
1
use Controller;
$class = new Controller\Controller;
ou
$class = new \Controller\Controller;
ou
use Controller\Controller;
$class = new Controller;
L'idée est que, dès que vous essayez d'accéder à une classe portant son nom relatif, elle tente de mapper la "première partie" avec tout alias défini à l'aide de use
(remeber use MyClass
est identique à use MyClass as MyClass
. L'option après as
est 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;
}
Comme vous pouvez le constater, PHP trouve SomeComponent
en tant que première partie et la mappe avec la SomeComponent
- alias de la ligne ci-dessus.
Vous pouvez en savoir plus à ce sujet dans le manuel sur les espaces de noms .
1 Il s'appelle "Nom de classe qualifié complet", si vous nommez une classe avec son nom complet.
Lorsque vous mettez une classe Controller
dans l'espace de noms Controller
, vous devez la référencer de la manière suivante:
$controller = new Controller\Controller();
\Controller
serait une classe de l’espace de noms global (par défaut), c’est-à-dire comme si vous n’utilisiez aucun espace de noms.
Étrangement, j'ai trouvé cela dans mon exemple de code de la question ci-dessus, si je modifie tous les Namespace's
définis en quelque chose comme MyLibrary
, ce serait donc comme ce code ci-dessous ...
Fichier E:\Library\Registry.class.php
<?php
namespace MyLibrary
{
class Registry
{
function __construct()
{
echo 'Registry.class.php Constructor was ran';
}
}
}
?>
Ensuite, lorsque j'utilise use MyLibrary\Registry;
dans un autre fichier, je peux y accéder comme je l'avais prévu ...
$this->registry = new Registry;
La raison pour laquelle cela m'est très étrange est que cela fait maintenant apparaître un nom de classe comme étant une variable Namespace
. Je n'aurais donc pas besoin de définir un espace de noms sur 'MyLibrary\Library' pour accéder à Registry
. Je le ferais comme je l'ai montré dans cette réponse pour pouvoir y accéder simplement en appelant le nom de la classe.
J'espère que cela a du sens et aide quelqu'un d'autre. Je n'accepterai pas cela comme réponse car j'espère qu'une personne plus expérimentée viendra poster une meilleure réponse avec explication
essayer
<?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>';
}
}
?>
et
<?php
namespace Library\Registry;
class Registry
{
function __construct()
{
return 'Registry.class.php Constructor was ran';
}
}
?>