Maison  >  Article  >  développement back-end  >  Maîtrise complète des espaces de noms php

Maîtrise complète des espaces de noms php

小云云
小云云original
2018-03-06 13:38:181525parcourir

L'espace de noms est utilisé pour résoudre les conflits de noms entre le code écrit par l'utilisateur et les classes/fonctions/constantes internes de PHP ou les classes/fonctions/constantes tierces. Créez un nom d'alias (ou court) pour un nom d'identifiant très long afin d'améliorer la lisibilité du code source.

Bien que tout code PHP légal puisse être inclus dans un espace de noms, seuls les types de code suivants sont affectés par l'espace de noms : classes (y compris les classes et traits abstraits), interfaces, fonctions et constantes.

Si un fichier contient un espace de noms, il doit déclarer l'espace de noms avant tout autre code sauf un : declare mot-clé, utilisé pour définir l'encodage du fichier source déclarer instruction. Le code, y compris les espaces, ne peut pas apparaître avant une déclaration d'espace de noms.

Contrairement aux autres fonctionnalités du langage PHP, le même espace de noms peut être défini dans plusieurs fichiers, ce qui permet au contenu du même espace de noms d'être divisé et stocké dans différents fichiers.

Définir des sous-espaces de noms

<?phpnamespace MyProject\Sub\Level;const CONNECT_OK = 1;class Connection { /* ... */ }function connect() {/* ... */ }

Définir plusieurs espaces de noms dans le même fichier

<?phpnamespace MyProject;const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */  }namespace AnotherProject;const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */  }

Il n'est pas recommandé d'utiliser cette syntaxe pour définir plusieurs espaces de noms dans un seul espace de noms de fichier. Il est recommandé d’utiliser la forme de syntaxe suivante entre accolades.

<?phpnamespace MyProject {const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */  }
}namespace AnotherProject {const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */  }
}

Dans la pratique réelle de la programmation, il est fortement déconseillé de définir plusieurs espaces de noms dans le même fichier. Cette méthode est principalement utilisée pour combiner plusieurs scripts PHP dans le même fichier.

Pour combiner du code global sans espace de noms avec du code d'espace de noms, seule la syntaxe des accolades peut être utilisée. Le code global doit être placé entre accolades avec une instruction d'espace de noms sans nom.

les classes peuvent être référencées de trois manières :

  1. Un nom non qualifié, ou un nom de classe sans préfixe, tel que $a=new foo(); ou foo::staticmethod();. Si l'espace de noms actuel est currentnamespace, foo sera résolu en currentnamespacefoo. Si le code utilisant foo est global et ne contient de code dans aucun espace de noms, foo sera analysé comme foo. Avertissement : Si une fonction ou une constante dans l'espace de noms n'est pas définie, la fonction ou le nom de constante non qualifié est résolu en une fonction globale ou un nom de constante.

  2. nom qualifié, ou un nom qui inclut un préfixe, tel que $a = new subnamespacefoo(); ou subnamespacefoo::staticmethod (); . Si l'espace de noms actuel est currentnamespace, alors foo sera résolu en currentnamespacesubnamespacefoo. Si le code utilisant foo est global, code non contenu dans aucun espace de noms, foo sera analysé comme subnamespacefoo.

  3. Un nom complet ou un nom qui inclut un opérateur de préfixe global, par exemple, $a = new currentnamespacefoo(); ou currentnamespacefoo : :staticmethod ();. Dans ce cas, foo est toujours résolu en nom littéral currentnamespacefoo dans le code.

Notez que pour accéder à n'importe quelle classe, fonction ou constante globale, vous pouvez utiliser un nom complet, tel que strlen() ou Exception ou INI_ALL.

Remarque : Le chemin relatif du fichier contenu dans le fichier enfant contenu par le fichier parent concerne le répertoire du fichier parent, pas le répertoire du fichier enfant.

PHP prend en charge deux méthodes abstraites pour accéder aux éléments dans l'espace de noms actuel, les __NAMESPACE__constantes magiques et le mot-clé namespace.

__NAMESPACE__ peut représenter une chaîne, et les autres sont identiques à nameapce.

Utilisez l'opérateur use pour importer/utiliser des alias

<?phpnamespace foo;use My\Full\Classname as Another;// 下面的例子与 use My\Full\NSname as NSname 相同use My\Full\NSname;// 导入一个全局类use ArrayObject;// importing a function (PHP 5.6+)use function My\Full\functionName;// aliasing a function (PHP 5.6+)use function My\Full\functionName as func;// importing a constant (PHP 5.6+)use const My\Full\CONSTANT;$obj = new namespace\Another; // 实例化 foo\Another 对象$obj = new Another; // 实例化 My\Full\Classname 对象NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func$a = new ArrayObject(array(1)); // 实例化 ArrayObject 对象// 如果不使用 "use ArrayObject" ,则实例化一个 foo\ArrayObject 对象func(); // calls function My\Full\functionNameecho CONSTANT; // echoes the value of My\Full

Importer/utiliser des alias via l'opérateur use, y compris plusieurs instructions use sur une seule ligne

<?phpuse My\Full\Classname as Another, My\Full\NSname;$obj = new Another; // 实例化 My\Full\Classname 对象NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func

Import et noms dynamiques

L'opération d'importation est effectuée lors de la compilation, mais le nom de la classe dynamique, le nom de la fonction ou le nom de la constante est pas .

<?phpuse My\Full\Classname as Another, My\Full\NSname;$obj = new Another; // 实例化一个 My\Full\Classname 对象$a = &#39;Another&#39;;$obj = new $a;      // 实际化一个 Another 对象

Import et noms complets

Les opérations d'import n'affectent que les noms non qualifiés et qualifiés. Les noms pleinement qualifiés ne sont pas affectés par les importations car ils sont déterministes.

<?phpuse My\Full\Classname as Another, My\Full\NSname;$obj = new Another; // instantiates object of class My\Full\Classname$obj = new \Another; // instantiates object of class Another$obj = new Another\thing; // instantiates object of class My\Full\Classname\thing$obj = new \Another\thing; // instantiates object of class Another\thing

Utiliser les instructions d'espace global

<?phpnamespace A\B\C;/* 这个函数是 A\B\C\fopen */function fopen() { 
     /* ... */
     $f = \fopen(...); // 调用全局的fopen函数
     return $f;
}

Dans un espace de noms, lorsque PHP rencontre une classe, une fonction ou un nom de constante non qualifié, il utilise une stratégie de priorité différente pour résoudre le nom. Les noms de classe sont toujours résolus en noms dans l'espace de noms actuel. Par conséquent, lorsque vous accédez à un nom de classe interne au système ou non contenu dans un espace de noms, vous devez utiliser le nom complet. Pour les fonctions et les constantes, si la fonction ou la constante n'existe pas dans l'espace de noms actuel, PHP reviendra à l'utilisation de la fonction ou de la constante dans l'espace global.

<?phpnamespace A\B\C;class Exception extends \Exception {}$a = new Exception(&#39;hi&#39;); // $a 是类 A\B\C\Exception 的一个对象$b = new \Exception(&#39;hi&#39;); // $b 是类 Exception 的一个对象$c = new ArrayObject; // 致命错误, 找不到 A\B\C\ArrayObject 类
<?phpnamespace 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_ALLecho strlen(&#39;hi&#39;), "\n"; // 输出 "1"if (is_array(&#39;hi&#39;)) { // 输出 "is not array"
    echo "is array\n";
} else {    echo "is not array\n";
}

La résolution de noms suit les règles suivantes :

  1. Les appels aux fonctions, classes et constantes avec des noms complets sont résolus au moment de la compilation. Par exemple, le nouveau AB se résout en classe AB.

  2. Tous les noms non qualifiés et les noms qualifiés (noms non pleinement qualifiés) sont convertis au moment de la compilation selon les règles d'importation en vigueur. Par exemple, si l'espace de noms ABC est importé en tant que C, alors les appels à CDe() sont convertis en ABCDe().

  3. 在命名空间内部,所有的没有根据导入规则转换的限定名称均会在其前面加上当前的命名空间名称。例如,在命名空间 A\B 内部调用 C\D\e(),则 C\D\e() 会被转换为 A\B\C\D\e() 。

  4. 非限定类名根据当前的导入规则在编译时转换(用全名代替短的导入名称)。例如,如果命名空间 A\B\C 导入为C,则 new C() 被转换为 new A\B\C() 。

  5. 在命名空间内部(例如A\B),对非限定名称的函数调用是在运行时解析的。例如对函数 foo() 的调用是这样解析的:

    1. 在当前命名空间中查找名为 A\B\foo() 的函数

    2. 尝试查找并调用 全局(global) 空间中的函数 foo()。

  6. 在命名空间(例如A\B)内部对非限定名称或限定名称类(非完全限定名称)的调用是在运行时解析的。下面是调用 new C() 及 new D\E() 的解析过程: new C()的解析:

    new D\E()的解析:

    为了引用全局命名空间中的全局类,必须使用完全限定名称 new \C()。

    1. 在类名称前面加上当前命名空间名称变成:A\B\D\E,然后查找该类。

    2. 尝试自动装载类 A\B\D\E。

    3. 在当前命名空间中查找A\B\C类。

    4. 尝试自动装载类A\B\C。

<?phpnamespace A;use B\D, C\E as F;// 函数调用foo();      // 首先尝试调用定义在命名空间"A"中的函数foo()
            // 再尝试调用全局函数 "foo"\foo();     // 调用全局空间函数 "foo" my\foo();   // 调用定义在命名空间"A\my"中函数 "foo" F();        // 首先尝试调用定义在命名空间"A"中的函数 "F" 
            // 再尝试调用全局函数 "F"// 类引用new B();    // 创建命名空间 "A" 中定义的类 "B" 的一个对象
            // 如果未找到,则尝试自动装载类 "A\B"new D();    // 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象
            // 如果未找到,则尝试自动装载类 "B\D"new F();    // 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象
            // 如果未找到,则尝试自动装载类 "C\E"new \B();   // 创建定义在全局空间中的类 "B" 的一个对象
            // 如果未发现,则尝试自动装载类 "B"new \D();   // 创建定义在全局空间中的类 "D" 的一个对象
            // 如果未发现,则尝试自动装载类 "D"new \F();   // 创建定义在全局空间中的类 "F" 的一个对象
            // 如果未发现,则尝试自动装载类 "F"// 调用另一个命名空间中的静态方法或命名空间函数B\foo();    // 调用命名空间 "A\B" 中函数 "foo"B::foo();   // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
            // 如果未找到类 "A\B" ,则尝试自动装载类 "A\B"D::foo();   // 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法
            // 如果类 "B\D" 未找到,则尝试自动装载类 "B\D"\B\foo();   // 调用命名空间 "B" 中的函数 "foo" \B::foo();  // 调用全局空间中的类 "B" 的 "foo" 方法
            // 如果类 "B" 未找到,则尝试自动装载类 "B"// 当前命名空间中的静态方法或函数A\B::foo();   // 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\A\B" 未找到,则尝试自动装载类 "A\A\B"\A\B::foo();  // 调用命名空间 "A\B" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\B" 未找到,则尝试自动装载类 "A\B"?>

相关推荐:

PHP命名空间详细使用方法

PHP命名空间、性状与生成器详解

实例详解PHP命名空间用法

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn