ホームページ  >  記事  >  バックエンド開発  >  php名前空間とは何ですか?名前空間の使用例の詳細な説明

php名前空間とは何ですか?名前空間の使用例の詳細な説明

伊谢尔伦
伊谢尔伦オリジナル
2017-06-30 09:23:211255ブラウズ

PHP は 5.3.0 以降のバージョンで namespace のサポートを開始します。ネームスペースとは何ですか?大まかに言えば、名前空間は物事をカプセル化する方法です。この抽象的な概念はさまざまな場所で見られます。

名前空間の概要

PHP では、名前空間は、クラス ライブラリやアプリケーションを作成するときにクラスや関数などの再利用可能なコードを作成するときに発生する 2 種類の問題を解決するために使用されます:

ユーザーが作成したコードと PHP 内部クラス間の名前の競合/関数/定数またはサードパーティのクラス/関数/定数。
非常に長い識別子名 (通常、最初の種類の問題を軽減するために定義される) のエイリアス (または短い) 名を作成し、ソース コードの可読性を向上させます。
PHP 名前空間は、関連するクラス、関数、定数をグループ化する方法を提供します。以下は、PHP 名前空間の構文を示す例です。

名前空間を定義する

正当な PHP コード を名前空間に含めることができますが、名前空間の影響を受けるコードはクラス、関数の 3 種類のみです。そして定数。名前空間は、キーワード namespace を使用して宣言されます。ファイルに名前空間が含まれている場合は、他のすべてのコードの前に名前空間を宣言する必要があります。さらに、PHP の他の言語機能とは異なり、同じ名前空間を複数のファイルで定義できるため、同じ名前空間の内容を別のファイルに分割して保存できます。もちろん、同じファイル内に複数の名前空間を定義することもできます。

namespace MyProject;
class MyClass
{
    #code...
}

サブ名前空間を定義する: ディレクトリとファイルの関係と同様に、PHP 名前空間でも階層的な名前空間名を指定できます。したがって、名前空間の名前は階層的な方法で定義できます:

namespace MyProject\helper\http;
class MyClass
{
    #code...
}

同じファイル内で複数の名前空間を定義します: 同じファイル内で複数の名前空間を宣言するには 2 つの方法がありますが、実際のプログラミングの実践では、この方法は強くお勧めしません。同じファイル内で Dogo 名前空間を定義します。この方法は主に、同じファイル内の複数の PHP スクリプトを結合するために使用されます。最初の方法を以下に示します。

namespace MyProject\helper\http;
class MyClass
{
    #code...
}
namespace MyProject\helper\request;
class MyClass
{
    #code...
}

ただし、このメソッドの使用は強く推奨されません。次の中括弧定義メソッドを参照してください:

namespace MyProject\helper\http;
{
    class MyClass
    {
        #code...
    }
}
namespace MyProject\helper\request;
{
    class MyClass
    {
        #code...
    }
}

PHP 名前空間での要素の使用

名前空間の使用方法について説明する前に、PHP がどのように認識するかを理解する必要があります。要素に何を使用するか。クラス名は 3 つの方法で参照できます:

非修飾名、または $a=new foo(); や foo::staticmethod(); などの接頭辞のないクラス名。現在の名前空間が currentnamespace の場合、foo は currentnamespacefoo に解決されます。 foo を使用するコードがグローバルであり、どの名前空間にもコードが含まれていない場合、foo は foo として解決されます。 警告: 名前空間内の関数または定数が未定義の場合、修飾されていない関数または定数名は グローバル関数 名または定数名に解決されます。詳細については、「名前空間の使用: フォールバック グローバル関数名/定数名」を参照してください。

修飾名、またはプレフィックスを含む名前 ($a = new subnamespacefoo(); または subnamespacefoo::staticmethod(); など)。現在の名前空間が currentnamespace の場合、foo は currentnamespacesubnamespacefoo に解決されます。 foo を使用するコードがグローバルであり、コードがどの名前空間にも含まれていない場合、foo はサブ名前空間 foo に解決されます。

完全修飾名、またはグローバル接頭辞 operator を含む名前 ($a = new currentnamespacefoo(); または currentnamespacefoo::staticmethod(); など)。この場合、foo はコード内で常にリテラル名 currentnamespacefoo に解決されます。
名前空間の使用: エイリアス/インポート

エイリアスを介して外部完全修飾名を参照またはインポートできるようにすることは、名前空間の重要な機能です。 PHP 名前空間のサポート エイリアスまたはインポートを使用するには、クラス名にエイリアスを使用する方法と、名前空間名にエイリアスを使用する方法の 2 つがあります。 PHP では、エイリアスは演算子を使用して実装されます。

PHP はインポートされた関数や定数をサポートしていないことに注意してください。

namespace foo;
use My\Full\Classname as Another;
// 下面的例子与 use My\Full\NSname as NSname 相同
use My\Full\NSname;
// 导入一个全局类
use \ArrayObject;

名前解決ルール

名前解決ルールを説明する前に、いくつかの重要な定義を見てみましょう:

非修飾名非修飾名: 名前に名前空間区切り文字が含まれていない識別子 (Foo
修飾名修飾名) : 名前に名前空間区切り文字が含まれる識別子 (FooBar など) 完全修飾名: 名前に名前空間区切り文字が含まれ、名前空間区切り文字で始まる識別子 (FooBar など)。 namespaceFoo も完全修飾名です。
名前解決は次のルールに従います:

对完全限定名称的函数,类和常量的调用在编译时解析。例如 new \A\B 解析为类 A\B。
所有的非限定名称和限定名称(非完全限定名称)根据当前的导入规则在编译时进行转换。例如,如果命名空间 A\B\C 被导入为 C,那么对 C\D\e() 的调用就会被转换为 A\B\C\D\e()。
在命名空间内部,所有的没有根据导入规则转换的限定名称均会在其前面加上当前的命名空间名称。例如,在命名空间 A\B 内部调用 C\D\e(),则 C\D\e() 会被转换为 A\B\C\D\e() 。
非限定类名根据当前的导入规则在编译时转换(用全名代替短的导入名称)。例如,如果命名空间 A\B\C 导入为C,则 new C() 被转换为 new A\B\C() 。
在命名空间内部(例如A\B),对非限定名称的函数调用是在运行时解析的。例如对函数 foo() 的调用是这样解析的:
1) 在当前命名空间中查找名为 A\B\foo() 的函数
2) 尝试查找并调用 全局(global) 空间中的函数 foo()。
在命名空间(例如A\B)内部对非限定名称或限定名称类(非完全限定名称)的调用是在运行时解析的。下面是调用 new C() 及 new D\E() 的解析过程: new C()的解析:
在当前命名空间中查找A\B\C类。
尝试自动装载类A\B\C。

new D\E()的解析:
在类名称前面加上当前命名空间名称变成:A\B\D\E,然后查找该类。
尝试自动装载类 A\B\D\E。

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

Example 名称解析示例

<?php
namespace 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。