PHPの名前空間の使い方の詳しい説明

php中世界最好的语言
リリース: 2023-03-26 16:16:01
オリジナル
2711 人が閲覧しました

今回は、php名前空間の使用方法と、php名前空間を使用する際の注意事項について詳しく説明します。以下は実際のケースです。

1: ネームスペースの概念: ネームスペースは、ディレクトリやファイルと同様に、物事をカプセル化する方法です。

名前空間によって解決される問題 (マニュアルも非常に明確に書かれており、以下では私自身の理解に従って簡略化されています):

1: プログラム作成者自身および PHP またはサードパーティの内部のクラス、定数、関数によって作成されたクラス、定数、関数の出現を解決します。当事者の名前が競合している状況。

2: クラス、定数、関数の名前が長すぎる問題を解決し、コードの読みやすさを向上させるためにエイリアスを作成します。また、名前が長すぎる場合は、通常、最初のタイプの問題を軽減することが原因です。

2: 名前空間を定義する方法

1: 名前空間は、キーワード namespace を使用して宣言されます。同時に、名前空間は、PHP 以外のコードや空白文字を含む他のコードの前に配置される必要があります (宣言キーワードを除く)。 php) を使用しないと、致命的なエラーがスローされます。

例:

<?php 
namespace Index; 
?>
ログイン後にコピー

注 1: 名前空間の前にコードや空白がないにもかかわらず、致命的なエラーが発生する場合は、BOM ヘッダーが原因であると考えられます。BOM ヘッダーを削除してください。
注 2: すべての正当な PHP コードを名前空間の下に配置できますが、名前空間の影響を受けるのはクラス (抽象クラスと特性) とインターフェイス、定数、および関数だけです。

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

例:

<?php 
namespace Index\Col\File; 
define(&#39;MESSAGE&#39;,&#39;hello world&#39;); 
?>
ログイン後にコピー

3: 1 つのファイルで複数の名前空間を定義できます。 1 つは単純な組み合わせ構文、もう 1 つは中括弧構文です。 別のファイルで複数の名前を定義します。スペースの使用は通常、次のとおりです。複数のファイルを 1 つのファイルにマージするシナリオですが、コードが複雑になり、可読性が低下するため、絶対に必要な場合を除き、これを行わないことをお勧めします。一般に、この方法を使用する必要はありません。 。

単純な組み合わせ構文:

<?php 
namespace Index; 
const INSTANCE=1; 
 
namespace Col; 
const INSTANCE=2; 
?>
ログイン後にコピー

中括弧構文。1 つのファイルに複数の名前空間があります。非名前空間コードを記述する必要がある場合は、中括弧構文のみを使用できます。非名前空間コードは名前空間を使用して名前空間を宣言します。

<?php 
/*命名空间Index*/ 
namespace Index{ 
  const INSTANCE=1; 
} 
 
/*命名空间Col*/ 
namespace Col{ 
  const INSTANCE=2; 
} 
 
/*全局非命名空间代码*/ 
namespace { 
  const INSTANCE=3; 
} 
?>
ログイン後にコピー

4: 複数の異なるファイルで同じ名前空間を定義できます。これは、同じ名前空間の内容を複数の異なるファイルに保存できることを意味します。これ以上の例はありません。

3: 名前空間の識別原則

名前空間の使用には 3 つの状況があります。マニュアルでは実際に詳しく説明していますが、翻訳の問題により混乱を招く可能性があります。ここでは簡略化して私自身の例を使用します。

1: 修飾名はありません。つまり、読み込むクラス、定数、関数、インターフェイスの名前が直接使用されます。コンテンツが属する名前空間の名前が読み込まれますが、名前空間に関連する名前がない場合、データがクラスまたはインターフェイス名の場合、致命的なエラーが返されます。関数または定数、グローバル関数の場合は、致命的なエラーが返されます。グローバル関数または定数がない場合は、定数が自動的に読み取られ、致命的なエラーが報告されます。

次の例:

<?php 
/*全局非命名空间代码*/ 
namespace { 
  const INSTANCE=1; 
 
  function test(){ 
    echo 1; 
  } 
 
  class foo{ 
    static function fool(){ 
          echo 1; 
        } 
  } 
 
  var_dump(INSTANCE);   //打印出来的是1 
 
  test();       //输出1 
 
  foo::fool();      //输出1 
 
} 
 
/*命名空间Index*/ 
namespace Index{ 
  const INSTANCE=2; 
 
  function test(){ 
    echo 2; 
  } 
 
  class foo{ 
    static function fool(){ 
          echo 2; 
        } 
  } 
 
  var_dump(INSTANCE);   //打印出来的是2 
 
  test();     //输出2 
 
  foo::fool();    //输出2 
} 
 
/*命名空间Col*/ 
namespace Col{ 
  const INSTANCE=3; 
 
  function test(){ 
    echo 3; 
  } 
 
  class foo{ 
    static function fool(){ 
          echo 3; 
        } 
  } 
 
  var_dump(INSTANCE);   //打印出来的是3 
 
  test();     //输出2 
   
  foo::fool();    //输出2 
} 
?>
ログイン後にコピー

上記の例では、各名前空間出力には修飾名がないため、現在の名前空間に設定されている対応するデータ値が取得されます。

現在の名前空間が設定されていない場合、関数と定数はグローバルに設定された対応するデータ値を読み取ります。致命的なエラーは、対応するグローバル設定がない場合にのみ報告されます。次に示すように、クラスとインターフェイスは致命的なエラーを直接報告します。次のコード。

<?php 
/*全局非命名空间代码*/ 
namespace { 
  const INSTANCE=1;  
  function test(){ 
    echo 1; 
  } 
 
  class foo{ 
    static function fool(){ 
          echo 1; 
        } 
  } 
 
  var_dump(INSTANCE);   //打印出来的是1  
  test();     //输出1  
  foo::fool();    //输出1  
} 
 
/*命名空间Index*/ 
namespace Index{ 
  var_dump(INSTANCE);   //打印出来的是1  
  test();     //输出1  
  foo::fool();    //fatal error 
 
} 
?>
ログイン後にコピー

2: 修飾名は 2 つの状況に分けられます。1 つはプレフィックスを含む修飾名の場合、もう 1 つはグローバル修飾名を含む場合です。マニュアルではこれら 2 つのタイプを個別に分けていますが、これら 2 つは両方とも修飾名を持っていますが、前者にはグローバル修飾子がありませんが、後者にはグローバル修飾子があります。

① 接頭辞を含む修飾名。この接頭辞は複数または 1 つのレベルを持つことができますが、この場合、コードが配置されている名前空間に対応するデータと接頭辞で修飾された名前を指定することはできません。読み取られます。つまり:

所处命名空间\前缀限定\名称来读取,如果该代码是全局没有命名空间的,则直接用前缀限定名称来读取,也就是:前缀限定\名称来读取。

实例代码:

<?php 
/*命名空间Col\Index*/ 
namespace Col\Index{ 
  const INSTANCE=1; 
} 
 
/*命名空间Index*/ 
namespace Index{ 
  const INSTANCE=2; 
} 
 
/*命名空间Col*/ 
namespace Col{ 
  const INSTANCE=3; 
  var_dump(Index\INSTANCE); //打印出来的是1 读取的是Col\Index\INSTANCE 
} 
 
/*全局非命名空间代码*/ 
namespace { 
  const INSTANCE=4; 
  var_dump(Index\INSTANCE); //打印出来的是2 读取的是Index\INSTANCE 
} 
 
?>
ログイン後にコピー

②全局限定前缀名称:也就是在最左侧有全局操作符\进行修饰的前缀限定名称,当然也可以没有前缀限定直接全局操作符\加上名称也是可以的。但加上全局操作符后就跟目录里的绝对路径一样,只会按照全局限定后的所设置的进行读取。

具体实例如下:

<?php 
/*命名空间Col\Index*/ 
namespace Col\Index{ 
  const INSTANCE=1; 
} 
 
/*命名空间Index*/ 
namespace Index{ 
  const INSTANCE=2; 
} 
 
/*命名空间Col*/ 
namespace Col{ 
  const INSTANCE=3; 
  var_dump(\Index\INSTANCE); //打印出来的是2 读取的是Index\INSTANCE 
} 
 
/*全局非命名空间代码*/ 
namespace { 
  const INSTANCE=4; 
  var_dump(\Index\INSTANCE); //打印出来的是2 读取的是Index\INSTANCE 
} 
 
namespace Lin{ 
  const INSTANCE=5; 
  var_dump(\INSTANCE); //打印出来的是4 读取的是INSTANCE,是全局非命名空间里的INSTANCE,如果没有全局操作符\,读取的会是当前命名空间的Lin\INSTANCE=5 
} 
 
?>
ログイン後にコピー

四:命名空间在字符串中的转义

有时候命名空间会放在字符串中使用,如果是单引号不会通过编译器解释,所以没有任何问题,但是如果是双引号,那么就会有些意外情况了,要知道双引号里的内容是需要经过编译器进行解释然后再进行输出的,而\在编译器里的解释容易造成歧义

例如"index\name"这里就有\n会被解释成换行,除此之外还有很多这种造成意外的情况。

因此一般我们推荐命名空间如果要放在字符串中使用,最好使用单引号,一是效率,二是安全,如果使用双引号,则必须增加一个\进行转义避免歧义,例如"index\\name"这样就没有问题了。

随手双引号的举个例子:

<?php 
/*全局非命名空间代码*/ 
namespace Index\Name{ 
  class foo{ 
    function construct(){ 
      echo 2; 
    } 
  } 
} 
 
namespace{ 
  $a= "Index\\Name\\foo"; //用\转义了\所以可以正常运行,但是如果去掉转义的话会报错Class 'Index\Nameoo',因为/f被解释成了换页符 
  $obj=new $a; 
}
ログイン後にコピー

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Laravel实现密码重置步骤详解

php爬取天猫和淘宝商品数据步骤详解(附代码)

以上がPHPの名前空間の使い方の詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート