ネームスペースとは

肚皮会动
肚皮会动オリジナル
2017-11-14 10:34:002090ブラウズ

名前空間 最も明確な目的の 1 つは、重複する名前の問題を解決することです。PHP では、2 つの関数またはクラスが同じ名前を持つことを許可しません。そうしないと、致命的なエラーが発生します。この場合、名前の重複を避ける限り解決できます。最も一般的な方法は、プレフィックスを合意することです。

例: プロジェクトには記事とメッセージボードの 2 つのモジュールがあり、それぞれにユーザーのコメントを処理するクラス Comment があります。後で、すべてのユーザー メッセージに情報統計関数を追加する場合があります。たとえば、すべてのメッセージの数を取得したいとします。この時点で、Comment によって提供されるメソッドを呼び出すことは良い考えですが、それぞれの Comment クラスを同時に導入することは明らかに不可能であり、コードでエラーが発生し、Comment を別の場所に書き換えるとエラーが発生します。メンテナンス性が低下します。次に、クラス名をリファクタリングするだけで、次のようにクラス名の前にモジュール名を追加するという名前付けルールに同意しました。将来的には、より多くのコード (少なくともより多くの文字) が記述される予定です。さらに、将来的に各モジュールに統合関数を追加したり、相互に呼び出したりする場合は、名前が重複した場合に名前を再構築する必要があります。もちろん、プロジェクトの開始時にこの問題に気づき、名前付けルールを指定することで、この問題は回避できます。別の解決策は、

名前空間

を使用することです。 名前空間

を宣言する場合、中かっこには変数だけでなく次の型も含めることができます:

変数 (初期化可能)

定数

関数 (定義または宣言可能)

構造

class

template

namespace

(namespaceはネスト定義可能)

namespace

使用法の概要:

ヒント: 次の例では、Demo.php、index.php、2つのファイルの2つのファイルがあります。同じディレクトリ内に、Demo.php ファイルに namespace

と Demo クラスを記述し、index.php が Demo.php 内の Demo クラスを呼び出します。次の例の「出力結果」は、ブラウザがindex.php にアクセスすることを意味します。

簡単な例

Demo.php file code

<?php
  namespace DemoNameSpace;
 class Demo {   
     private $mysqlHandle;  
     public function construct(){     
     echo &#39;This is namespace of PHP demo ,The Demo magic constant "NAMESPACE" is &#39;.NAMESPACE; 
     }}?>

index.php file code

<?php 
 include &#39;Demo.php&#39;; 
 use DemoNameSpace\Demo;
 $DemoObj = new Demo();
 ?>

出力結果1:「これはPHPデモのネームスペースです、デモのマジック定数「NAMESPACE」はDemoNameSpaceです」

上記の説明例の例: Demo.php には _NAMESPACE マジック定数があります。「これには、現在の名前空間名の文字列が含まれています。グローバルには、どの名前空間コードにも含まれておらず、空の文字列が含まれています。」 次に、例を続けます。

Demo.php は何も変更しませんが、index.php ファイルを次のように変更します:

<?php
include &#39;Demo.php&#39;;
$Demo = new Demo();
?>

出力結果 2: 「致命的なエラー: クラス 'Demo' が F:JJserverdemoindex.php の 4 行目に見つかりません」

これは一般的な「致命的なエラー」メッセージです。従来の PHP プログラミングの考え方によれば、ここでの出力は「出力結果 1」と一致するはずですが、ここには致命的なエラーがあります。 ~

それでは、まず問題を解決し、Demo.php ファイル内のステートメント「namespace DemoNameSpace;」を削除 (またはコメントアウト) すれば正常になります。これは、通常、クラスを作成してクラスを呼び出す最も一般的な方法です。名前空間を使用せずにこの状況を説明することはしません。

名前空間を使用する場合と使用しない場合の 2 つの出力状況を比較し、理解するために名前空間の定義を追加すると、上記の致命的なエラーの状況が理解しやすくなります。名前空間は Demo.php で定義されます。つまり、名前空間の後に Demo クラスが定義され、その後 Demo クラスが DemoNameSpace 名前空間にマージされるため、この Demo クラスを呼び出す場合は、最初にこの DemoNameSpace を呼び出す必要があります。つまり、index.php ファイル内の「useDemoNameSpaceDemo」ステートメントを使用します。

2 つ目は、より複雑な例です

Demo.php file code

<?php
namespace DemoNameSpace; 
class Demo {  
  private $mysqlHandle;    
  public function construct(){        
  echo &#39;This is namespace of PHP demo ,The Demo magic constant "NAMESPACE" is &#39;.NAMESPACE;
  }} 
  namespace DemoNameSpace1; 
  const constDefine = &#39;JJonline1&#39;; 
  class Demo {   
  private $mysql; 
  const constDefine = &#39;JJonline2&#39;; 
  public function construct() { 
  echo &#39;The const constant outside class is: &#39;.constDefine; 
  echo &#39;===cut-off rule of god!!!!===&#39;;
  echo &#39;The const constant inside class is: &#39;.self::constDefine;
   }}?>

index.php file code

<?php 
include &#39;Demo.php&#39;; 
use DemoNameSpace1\Demo as Test; 
$Demo = new Test(); 
echo &#39;||||&#39;.DemoNameSpace1\constDefine;?>

出力結果 3: "クラス外の const 定数は次のとおりです: JJonline1===神のカットオフ ルール!! !!===クラス内の定数は次のとおりです: JJonline2||||JJonline1”

这个结果在没有命名空间的时候,就直接报诸如“Fatal error: Cannot redeclare class Demo”的致命错误了。但运行没有报错,这也就是php5.3以后引入的命名空间的好处了,就诸如本文开头引用的官方解释中以不同目录下的相同文件名的文件可以存在一样是一个道理了。Demo.php文件中,定义的第一个名称叫做Demo的class类被归并到了DemoNameSpace的命名空间,而定义的第二个名称叫做Demo的class被归并到了DemoNameSpace1的命名空间,故而并不会出现不能重复定义某一个类的致命错误。以上的书写方法是要尽量避免的,因为类外部const常量名与类内部const常量名是一样的,很容易混淆,这里这样书写的目的就是看看不同位置申明的const常量,在调用时的情况;输出结果3已经很明显了,就不再多墨迹解释了。

Demo.php中DemoNameSpace1命名空间下还将const常量constDefine提出,拿到了定义class之外,这又要抓狂了,因为之前的知识是define定义全局常量,const定义class内部常量;这儿却将const拿出来玩了...具体就不再讲解了,Demo.php文件代码以及运行后的结果已经很明确的表明了相关知识。class内部定义的const只能在class的内部调用,采用self::constName形式,而class内部调用命名空间下、class外的const常量,则可以直接使用诸如define定义的常量一样使用。当需要使用该命名空间下、class外定义的const常量时,就使用类似路径形式的方式调用(index.php文件中的输出)。

该例子还有一点说明,就是在index.php中使用了use as语句,看index.php的代码,意义一目了然,new的一个class名称叫Test,但Test这个类并没有在Demo.php中定义,却没有出错,这就在于了use as语句了,具体意义不再解释。

通过上述的了解,namespace关键字可以将实现各种功能的class通过指定不同的命名空间分门别类存放,而且不同命名空间下的class可以同名;另外const常量定义也可以提出到class外部,当然也会有作用范围这么一个“内涵”~

总结下namespace的相关知识:

1、当前脚本文件的第一个命名空间前面不能有任何代码,例如如下代码就是会报致命错误的:

<?php
define("GREETING","Hello world!"); 
namespace DemoNameSpace;
class Demo { 
private $mysqlHandle; 
public function construct() { 
echo &#39;This is namespace of PHP demo ,The Demo magic constant "NAMESPACE" is &#39;.NAMESPACE;
 }}
 $Demo = new Demo();
 ?>

运行上述代码,会出现致命错误:“Fatal error: Namespace declaration statement has to be the very first statement in xxxx”

2、命名空间下直接new该命名空间中的class名称,可以省略掉use语法,这是php按脚本书写顺序执行导致的。例如如下代码是可以运行的

<?php
namespace DemoTest;
class Demo {   
 public function construct() {       
 echo &#39;this is a test script&#39;;   
 }}
 namespace DemoNameSpace;
 class Demo {   
 private $mysqlHandle;
 public function construct() { 
 echo &#39;This is namespace of PHP demo ,The Demo magic constant "NAMESPACE" is &#39;.NAMESPACE; 
 }}$
 Demo = new Demo();
 ?>

运行结果4:“This is namespace of PHP demo ,The Demo magic constant "NAMESPACE" is DemoNameSpace”

这个结果表明,同一脚本下new一个没有指定use哪个命名空间时,会顺着该脚本,使用最靠近new语句之前的一个命名空间中的class

3、公共空间:可以简单的理解,没有定义命名空间的方法(函数)、类库(class)、属性(变量)都默认归属于公共空间。这样就解释了为php5.3.0以前版本书写的代码大部分为何在php5.3.0及其以上版本还能正常运行的原因。另外:公共空间中的代码段被引入到某个命名空间下后,该公共空间中的代码段不属于任何命名空间!

命名空间的引入,让php面向对象编程更加的贴切,合理利用命名空间,也可以让项目文件规划,以上就是介绍命名空间的所有内容。

相关推荐:

实例详解PHP命名空间用法

PHP命名空间、性状与生成器相关介绍

php中命名空间与性状以及生成器新特性的详解

php namespace命名空间的定义方法实例详解

以上がネームスペースとはの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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