English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
PHP namespaces (namespace) are in PHP 5.3included, if you have learned C# and Java, namespaces are not a new thing. However, in PHP, they still have significant importance.
PHP namespaces can solve the following two types of problems:
User-written code versus PHP internal classes/Functions/Constants or third-party classes/Functions/Name conflicts between constants
Create an alias (or short) name for a very long identifier name (usually defined to alleviate the first-class problem) to improve the readability of the source code.
By default, all constants, class, and function names are placed in the global space, just as PHP supported namespaces before.
Namespaces are declared using the namespace keyword. If a file contains a namespace, it must be declared before any other code. The syntax format is as follows;
<?php // Define code within the 'MyProject' namespace namespace MyProject; // ... code ...
You can also define different namespace code within the same file, such as:
<?php namespace MyProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } namespace AnotherProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } ?>
It is not recommended to define multiple namespaces within a single file using this syntax. It is suggested to use the following syntax with curly braces.
<?php namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace AnotherProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } ?>
To combine global code outside of a namespace with code within a namespace, the syntax using curly braces must be used. Global code must be enclosed within a namespace statement without a name and curly braces, for example:
<?php namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace { // Code global session_start(); $a = MyProject\connect(); echo MyProject\Connection::start(); } ?>
Before declaring a namespace, the only valid code is the declare statement used to define the encoding of the source file. No non-PHP code, including whitespace, can appear before the namespace declaration.
<?php declare(encoding='UTF-8')-8);}} //Définir plusieurs namespaces et code non inclus dans un namespace namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace { // Code global session_start(); $a = MyProject\connect(); echo MyProject\Connection::start(); } ?>
Le code suivant produira une erreur de syntaxe :
<html> <?php namespace MyProject; // Un namespace précédé de « <html> » entraînera une erreur fatale - Le namespace doit être la première instruction du script ?>
Comme pour les répertoires et fichiers, les namespaces PHP permettent également de spécifier des noms de namespaces hiérarchiques. Par conséquent, le nom d'un namespace peut être défini de manière hiérarchique :
<?php namespace MyProject\Sub\Level; //Déclaration de namespace hiérarchique const CONNECT_OK = 1; class Connection { /* ... */ } function Connect() { /* ... */ } ?>
L'exemple suivant crée la constante MyProject\Sub\Level\CONNECT_OK, la classe MyProject\Sub\Level\Connection et la fonction MyProject\Sub\Level\Connect.
Le nom d'une classe dans un namespace PHP peut être utilisé de trois manières :
Nom non qualifié, ou nom de classe sans préfixePar exemple $a=new foo(); ou foo::staticmethod();. Si le namespace actuel est currentnamespace, foo sera interprété comme currentnamespace\foo. Si le code utilisant foo est global, sans être contenu dans un namespace, foo sera interprété comme foo. Avertissement : Si une fonction ou une constante du namespace n'est pas définie, le nom non qualifié de la fonction ou de la constante sera interprété comme le nom de la fonction ou de la constante globale.
Nom qualifié, ou nom contenant un préfixePar exemple $a = new subnamespace\foo(); ou subnamespace\foo::staticmethod();. Si le namespace actuel est currentnamespace, foo sera interprété comme currentnamespace\subnamespace\foo. Si le code utilisant foo est global, sans être contenu dans un namespace, foo sera interprété comme subnamespace\foo.
Nom qualifié complet, ou contenant un opérateur de préfixe globalPar exemple, $a = new \currentnamespace\foo(); ou \currentnamespace\foo::staticmethod();. Dans ce cas, foo est toujours analysé comme le nom littéral (literal name) currentnamespace\foo dans le code.
Voici un exemple utilisant ces trois méthodes :
file1Code du fichier .php
<?php espace de noms Foo\Bar\subnamespace; const FOO = 1; function foo() {} class foo { function static staticmethod() {} } ?>
file2Code du fichier .php
<?php espace de noms Foo\Bar; include 'file1.php'; const FOO = 2; function foo() {} class foo { function static staticmethod() {} } /* Nom non qualifié */ foo(); // Analyser la fonction Foo\Bar\foo foo::staticmethod(); // Analyser la classe Foo\Bar\foo, méthode static echo FOO; // Analyser la constante Foo\Bar\FOO /* Nom qualifié */ subnamespace\foo(); // Analyser la fonction Foo\Bar\subnamespace\foo subnamespace\foo::staticmethod(); // Analyser la classe Foo\Bar\subnamespace\foo, // ainsi que les méthodes de la classe static echo subnamespace\FOO; // Analyser la constante Foo\Bar\subnamespace\FOO /* Nom qualifié complet */ \Foo\Bar\foo(); // Analyser la fonction Foo\Bar\foo \Foo\Bar\foo::staticmethod(); // Analyser la classe Foo\Bar\foo, ainsi que les méthodes de la classe static echo \Foo\Bar\FOO; // Analyser la constante Foo\Bar\FOO ?>
Attention, pour accéder à n'importe quelle classe globale, fonction ou constante, vous pouvez utiliser un nom qualifié complet, par exemple \strlen() ou \Exception ou \INI_ALL.
Accès aux classes globales, fonctions et constantes à l'intérieur d'un espace de noms :
<?php espace de noms Foo; function strlen() {} const INI_ALL = 3; class Exception {} $a = \strlen('hi'); // Appel de la fonction globale strlen $b = \INI_ALL; // Accès à la constante globale INI_ALL $c = new \Exception('error'); // Exemple de classe globale Exception ?>
L'implémentation de l'espace de noms PHP est influencée par les caractéristiques dynamiques du langage lui-même. Par conséquent, si vous devez convertir le code suivant dans un espace de noms, accéder dynamiquement aux éléments.
example1Code du fichier .php :
<?php class classname { function __construct() { echo __METHOD__, '\n'; } } function funcname() { echo __FUNCTION__, '\n'; } const constname = 'global'; $a = 'classname'; $obj = new $a; // imprime classname::__construct $b = 'funcname'; $b(); // imprime funcname echo constant('constname'), '\n'; // imprime global ?>
Il est nécessaire d'utiliser des noms complètement qualifiés (y compris les noms des classes avec le préfixe d'espace de noms). Notez que dans les noms de classes, les noms de fonctions ou les noms de constantes dynamiques, il n'y a pas de différence entre les noms qualifiés et les noms complètement qualifiés, donc l'antislash initial n'est pas nécessaire.
Accès dynamique aux éléments des espaces de noms
<?php namespace namespacename; class classname { function __construct() { echo __METHOD__, '\n'; } } function funcname() { echo __FUNCTION__, '\n'; } const constname = 'namespaced'; include 'example1.php'; $a = 'classname'; $obj = new $a; // Sortie classname::__construct $b = 'funcname'; $b(); // Sortie le nom de la fonction echo constant('constname'), '\n'; // Sortie global /* Si vous utilisez des guillemets doubles, la méthode est "\\namespacename\\classname"*/ $a = '\namespacename\classname'; $obj = new $a; // Sortie namespacename\classname::__construct $a = 'namespacename\classname'; $obj = new $a; // Sortie namespacename\classname::__construct $b = 'namespacename\funcname'; $b(); // sortie namespacename\funcname $b = 'namespacename\funcname'; $b(); // sortie namespacename\funcname echo constant('\namespacename\constname'), "\n"; // sortie namespaced echo constant('namespacename\constname'), "\n"; // sortie namespaced ?>
PHP supporte deux méthodes d'accès aux éléments internes de l'espace de noms courant, la constante magique __NAMESPACE__ et le mot-clé namespace.
La valeur de la constante __NAMESPACE__ est une chaîne contenant le nom de l'espace de noms courant. Dans le code global, qui n'est pas inclus dans aucun espace de noms, il contient une chaîne vide.
Exemple de __NAMESPACE__, dans le code de l'espace de noms
<?php namespace MyProject; echo '"', __NAMESPACE__, '"'; // sortie "MyProject" ?>
Exemple de __NAMESPACE__, code global
<?php echo '"', __NAMESPACE__, '"'; // sortie "" ?>
La constante __NAMESPACE__ est très utile pour la création dynamique de noms, par exemple :
Création dynamique de noms en utilisant __NAMESPACE__
<?php namespace MyProject; function get($classname) { $a = __NAMESPACE__ . '\\' . $classname; retourne new $a; } ?>
Le mot-clé namespace peut être utilisé pour accéder explicitement aux éléments de l'espace de noms courant ou des sous-espaces de noms. Il est équivalent à l'opérateur self dans une classe.
opérateur namespace, code dans l'espace de noms
<?php namespace MyProject; utilise blah\blah en tant que mine; // voir "Using namespaces: importing/aliasing" blah\mine(); // appelle la fonction blah\blah\mine() namespace\blah\mine(); // appelle la fonction MyProject\blah\mine() namespace\func(); // appelle la fonction MyProject\func() namespace\sub\func(); // appelle la fonction MyProject\sub\func() namespace\cname::method(); // appelle la méthode statique "method" de la classe MyProject\cname $a = new namespace\sub\cname(); // instancie un objet de la classe MyProject\sub\cname $b = namespace\CONSTANT; // assigne la valeur de la constante MyProject\CONSTANT à $b ?>
opérateur namespace, code global
<?php namespace\func(); // appelle la fonction func() namespace\sub\func(); // appelle la fonction sub\func() namespace\cname::method(); // appelle la méthode statique "method" de la classe cname $a = new namespace\sub\cname(); // instancie un objet de la classe sub\cname $b = namespace\CONSTANT; // assigne la valeur de la constante CONSTANT à $b ?>
PHP supporte deux types d'alias ou de méthode d'importation : utiliser un alias pour le nom de la classe ou utiliser un alias pour le nom de l'espace de noms.
En PHP, les alias sont implémentés par l'opérateur use. Voici un exemple d'utilisation de tous les trois types possibles d'importations:
1、使用use操作符导入/使用别名
<?php namespace foo; use My\Full\Classname as Another; // Les exemples suivants sont équivalents à use My\Full\NSname as NSname use My\Full\NSname; // 导入一个全局类 use \ArrayObject; $obj = new namespace\Another; // Exemple d'un objet foo\Another $obj = new Another; // Exemple d'un objet de classe My\Full\Classname NSname\subns\func(); // Appel de la fonction My\Full\NSname\subns\func $a = new ArrayObject(array(1)); // Exemple d'un objet ArrayObject // Si l'on ne utilise pas "use \ArrayObject", on exemple un objet foo\ArrayObject ?>
2、多个use语句在一行中
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // Exemple d'un objet de classe My\Full\Classname NSname\subns\func(); // Appel de la fonction My\Full\NSname\subns\func ?>
Les opérations d'importation sont exécutées lors de la compilation, mais les noms de classes, de fonctions ou de constantes dynamiques ne le sont pas.
3、导入和动态名称
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // Exemple d'un objet de classe My\Full\Classname $a = 'Another'; $obj = new $a; // 实际化一个 Another 对象 ?>
另外,导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的,故不受导入的影响。
4、导入和完全限定名称
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // 示例化 My\Full\Classname 类 $obj = new \Another; // 示例化 Another 类 $obj = new Another\thing; // 示例化 My\Full\Classname\thing 类 $obj = new \Another\thing; // 示例化 Another\thing 类 ?>
在一个命名空间中,当 PHP 遇到一个非限定的类、函数或常量名称时,它使用不同的优先策略来解析该名称。类名称总是解析到当前命名空间中的名称。因此在访问系统内部或不包含在命名空间中的类名称时,必须使用完全限定名称,例如:
1、在命名空间中访问全局类
<?php namespace A\B\C; class Exception extends \Exception {} $a = new Exception('hi'); // $a 是类 A\B\C\Exception 的一个对象 $b = new \Exception('hi'); // $b 是类 Exception 的一个对象 $c = new ArrayObject; // 致命错误, 找不到 A\B\C\ArrayObject 类 ?>
对于函数和常量来说,如果当前命名空间中不存在该函数或常量,PHP 会退而使用全局空间中的函数或常量。
2、命名空间中后备的全局函数/常量
<?php namespace A\B\C; const E_ERROR = 45; function strlen($str) { return \strlen($str) - 1; } echo E_ERROR, "\n"; // 输出 ""45" echo INI_ALL, "\n"; // 输出 ""7" - 使用全局常量 INI_ALL echo strlen('hi'), "\n"; // 输出 ""1" if (is_array('hi')) { // 输出 "is not array" echo "is array\n"; } else { echo "is not array\n"; } ?>
Si aucun espace de noms n'est défini, toutes les définitions de classes et de fonctions sont dans l'espace de noms global, comme avant l'introduction du concept d'espace de noms dans PHP. Ajoutez un préfixe \ devant le nom pour indiquer que ce nom est dans l'espace de noms global, même si ce nom se trouve dans un autre espace de noms.
Utilisation de l'indication de l'espace de noms global
<?php namespace A\B\C; /* Cette fonction est A\B\C\fopen */ function fopen() { /* ... */ $f = \fopen(...); // Appeler la fonction globale fopen return $f; } ?>
Depuis l'introduction des espaces de noms, l'erreur la plus facile à faire est d'utiliser une classe, quel est le chemin de recherche de cette classe ?
<?php namespace A; use B\D, C\E as F; // Appel de fonction foo(); // Tentez d'abord d'appeler la fonction définie dans l'espace de noms "A" // Tentez à nouveau d'appeler la fonction globale "foo" \foo(); // Appeler la fonction globale "foo" my\foo(); // Appeler la fonction "foo" définie dans l'espace de noms "A\my" F(); // Tentez d'abord d'appeler la fonction définie dans l'espace de noms "A" // Tentez à nouveau d'appeler la fonction globale "F" // Référence de classe new B(); // Créer un objet de la classe "B" définie dans l'espace de noms "A" // Si elle n'est pas trouvée, essayez de charger automatiquement la classe "A\B" new D(); // Utilisez les règles d'importation pour créer un objet de la classe "D" définie dans l'espace de noms "B" // Si elle n'est pas trouvée, essayez de charger automatiquement la classe "B\D" new F(); // Utilisez les règles d'importation pour créer un objet de la classe "E" définie dans l'espace de noms "C" // Si elle n'est pas trouvée, essayez de charger automatiquement la classe "C\E" new \B(); // Créer un objet de la classe "B" définie dans l'espace de noms global // Si elle n'est pas trouvée, essayez de charger automatiquement la classe "B" new \D(); // Créer un objet de la classe "D" définie dans l'espace de noms global // Si elle n'est pas trouvée, essayez de charger automatiquement la classe "D" new \F(); // Créer un objet de la classe "F" définie dans l'espace de noms global // Si elle n'est pas trouvée, essayez de charger automatiquement la classe "F" // Appeler une méthode statique ou une fonction d'espace de noms d'un autre espace de noms B\foo(); // Appeler la fonction "foo" dans l'espace de noms "A\B" B::foo(); // Appeler la méthode "foo" de la classe "B" définie dans l'espace de noms "A" // Si la classe "A\B" n'est pas trouvée, essayez de charger automatiquement la classe "A\B" D::foo(); // Utilisez les règles d'importation pour appeler la méthode "foo" de la classe "D" définie dans l'espace de noms "B" // Si la classe "B\D" n'est pas trouvée, essayez de charger automatiquement la classe "B\D" \B\foo(); // Appeler la fonction "foo" de l'espace de noms "B" \B::foo(); // Appeler la méthode "foo" de la classe "B" dans l'espace global // Si la classe "B" n'est pas trouvée, essayez de charger automatiquement la classe "B" // Méthodes statiques ou fonctions de l'espace de noms actuel A\B::foo(); // Appeler la méthode "foo" de la classe "B" définie dans l'espace de noms "A\A" // Si la classe "A\A\B" n'est pas trouvée, essayez de charger automatiquement la classe "A\A\B" \A\B::foo(); // Appeler la méthode "foo" de la classe "B" définie dans l'espace de noms "A" // Si la classe "A\B" n'est pas trouvée, essayez de charger automatiquement la classe "A\B" ?>
Les règles d'analyse des noms sont les suivantes :
Les appels aux fonctions, classes et constantes complètement qualifiés sont analysés à la compilation. Par exemple new \A\B est analysé comme une classe A\B.
Tous les noms non qualifiés et les noms qualifiés (noms non complètement qualifiés) sont convertis en compilation suivant les règles d'importation actuelles. Par exemple, si l'espace de noms A\B\C est importé en tant que CAlors l'appel à C\D\e() de l'appel serait converti en A\B\C\D\e().
Dans l'espace de noms, tous les noms qualifiés non convertis suivant les règles d'importation actuelles sont ajoutés au nom de l'espace de noms actuel. Par exemple, dans l'espace de noms A\B Appel interne C\D\e(), alors C\D\e() est converti en A\B\C\D\e() .
Les noms de classes non qualifiés sont convertis en compilation suivant les règles d'importation actuelles (remplacement des noms courts par des noms complets). Par exemple, si l'espace de noms A\B\C Importé en tant que C, alors new C() est converti en new A\B\C() .
Appel interne à des fonctions non qualifiées dans l'espace de noms (par exemple A\B) se fait à l'exécution. Par exemple, l'appel à la fonction foo() dans l'espace de noms actuel.
Recherchez le nom A\B\foo() fonction
Essayer de trouver et d'appeler global(global) fonction de l'espace foo().
dans l'espace de noms (par exempleA\BAppel interne à des noms non qualifiés ou des classes qualifiées (noms non complètement qualifiés) se fait à l'exécution. Voici l'appel : new C() et new D\E() Processus d'analyse : new C()Analyse : new D\E()Analyse : Pour faire référence à une classe globale de l'espace de noms global, il est nécessaire d'utiliser un nom complet. new \C().
Ajoutez le nom de l'espace de noms actuel à l'avant du nom de la classe pour obtenir :A\B\D\E, puis recherchez cette classe.
Essayer de charger automatiquement la classe A\B\D\E.
Recherche dans l'espace de noms actuelA\B\Cclasse.
Essayer de charger automatiquement la classeA\B\C.