ネーミングスペース学習ノート

8564 ワード

断続的に名前空間に関する知識点を読み続けたが、仕事関係では常に関連コードに触れていないため、しばらくすると忘れてしまい、前回の名前空間に関するブログから9ヶ月が経ち、新版のThinkPHP 3.2バージョンにネーミングスペースが付いていて、昨年見たsymfony 2のフレームワークも使いましたが、今回は思い切ってしっかり整えていきたいと思います.
ネーミングスペースはphp 3.0バージョン以降に追加されるため、phpバージョンを使用するには3.0以上が必要です.キーワードはnamespaceです.ネーミングスペースを宣言する前に、唯一の合法的な文はdeclareで、他の文を書き込むとエラーが発生します.スクリプト内にネーミングスペースが宣言されている場合、その影響を受けるのは定数、関数、クラスの3種類だけです.他の言語とは異なり、同じネーミングスペースを複数のファイルに定義することができ、ThinkPHP 3を見たことがある.2ソースの友达は深く体得するべきです.以下はネーミングスペースでよく使われるいくつかの書き方です.
書き方一、トップネームスペース
namespace script

書き方二、サブネーミングスペース
namespace script\subScript

書き方三、同じファイルに複数のネーミングスペースを定義する.
namespace myScriptOne {
    function test() {}
}
namespace myScriptTwo {
    function test() {}
}

書き方四、複数のネーミングスペースとネーミングスペースに含まれないコードを定義することも珍しく
namespace myScriptOne {
    function test() {}
}
namespace myScriptTwo {
    function test() {}
}
namespace {
    function test() {}
}

ネーミングスペースの正確な書き方を理解した後,ネーミングスペース内の3つの基本概念を把握する必要がある.
概念1、限定されていない名前、または接頭辞を含まない名前.クラスを例にとるとnew action()またはaction::password()、すなわちネーミングスペースを使用する前の通常の書き方となる.現在のスクリプトのネーミングスペースがscriptの場合、new scriptaction()またはscriptaction::passwordとして解析されます.ネーミングスペースでグローバルなtest()メソッドが使用されている場合、異なる優先ポリシーを使用して解析されます.トップページは現在のネーミングスペース内を解析し、見つからない場合はグローバルに昇格するか、ない場合はエラーを報告します.これは定数にも適用されますが、クラスはそうではありません.クラス名は常に現在のネーミングスペースの名前に解析され、現在のネーミングスペースにクラスがない場合はエラーが発生します.
namespace script{
    echo test('123');
}
namespace {
    function test($num) {
        return 3;
    }
}

コンセプト2、限定名、または接頭辞を含む名前.クラスを例にとると、new subActionaction()またはsubActionaction::password()と表記され、現在のスクリプトのネーミングスペースがscriptの場合、new scriptsubActionaction()またはscriptsubActionaction::passwordとして解析されます.
namespace script\subAction;

class action {
    public static function password () {}
}
namespace script;
include 'script.php';
class action {
    public static function password () {}
}

new subAction\action;
subAction\action::password();

コンセプト3、名前を完全に限定するか、グローバル接頭辞オペレータを含む名前.クラスを例にとると、newsubActionaction()またはsubActionaction::password()と表記されますが、この場合、その解析は行われず、直接呼び出されます.任意のグローバルクラス、関数、定数にアクセスするには、ThinkPHP 3.2などの完全修飾名を使用します.3,PHPExcelクラスをインスタンス化するにはnewPHPExcel()のみです.
namespace script;
include 'script.php';
class action {
    public static function password () {}
}

new \script\subAction\action;
\script\subAction\action::password();

function strlen($str) {
    return 3;
}

//       strlen  
echo \strlen('test'); // 4

//            
echo strlen('test'); //3

3つの基本概念を理解してから、PHP動的言語の特徴と結びつけて、上のコードを変更して、結果を見てみましょう.
namespace script;
class action {
    public static function password () {}
}

$action = 'script\action';
new $action;

$action = '\script\action';
new $action;

上記の例で知られているように、
ネーミングスペースでは、動的処理後は解析されず、ネーミングスペース接頭辞を含むクラス名を完全に限定する必要があります.注意:動的クラス名、関数名、定数名では、修飾名と完全修飾名は区別されないため、先頭のスラッシュは必要ありません.
次にnamespaceキーワードと__についてお話ししますNAMESPACE__マジック定数.namespaceキーを使用すると、ネーミングスペース内の定数、クラス、関数に直接アクセスできます.NAMESPACE__マジック定数は通常動的文に関連付けられており、このマジック定数はネーミングスペースの文字列名を出力します.次の例を見てわかります.
namespace script;

class action {
    public function password() {}
}

//    namespace      self  
new namespace\action;

//              ,    
echo __NAMESPACE__; //script
$action = __NAMESPACE__ . '\\action';
new $action;

またuseについて話しましょう.プロジェクト開発では、ネーミングスペースを使用すると、各スクリプトに独立したネーミングスペースがあり、ネーミングスペース名にはAスクリプトネーミングスペース名がABCD、BスクリプトネーミングスペースがEFGなどの階層がある可能性があります.この形式では、AスクリプトがBスクリプトのクラスを継承したり、対応するクラスを参照したりする場合は、ネーミングスペースの列を大きく書く必要があります.これは不便ですが、ネーミングスペースを使用する前に、クラスの重複を避けるために、長いクラス名を定義したほうがお得です.このような状況を避けるためにuseの役割が現れた.useの意味は「別名/インポート」ですね.見ましたね.別名、つまり長い文字列を短い名前に縮小することで、大いに手間が省けます.use namespacename[as alias]と使います.まずuseを使用していないコードとuseを使用しているコードを見てみましょう.比較すると、使いやすいところがわかります.
namespace E\F\G;
class father {}
//     use

namespace A\B\C\D;

include 'father.php';

class son extends \E\F\G\father {}
//   use

namespace A\B\C\D;
use E\F\G\father; //     use E\F\G\father as father
include 'father.php';

class son extends father {}

別名による外部参照やインポートを許可する完全限定名は、ネーミングスペースの重要な特徴であり、この特徴がなければ、ネーミングスペースは鶏の肋骨に属さない.useは、前例のようにクラスに別名を使用したり、ネーミングスペースに別名を使用したりすることができます.ここを見ると、なぜ「ABCDEFGfather」と解析しなかったのか疑問に思う友人もいるかもしれませんが、これは導入された名前が完全に限定されていなければならず(その前置の区切り文字は付けなくてもよい)、現在のネーミングスペースに基づいて相対的に解析しないからです.エイリアスの使用は、外部のネーミングスペースをインポートする前提で行われます.同時にPHPは定数や関数のインポートをサポートしていません.つまり、useの多くはクラスサービスです.多くの場合、useはネーミングスペースに別名を使用することもできます.次の例を見てください.
namespace C\D\E;

class action {
    public static function password() {}
}

function passward() {}
const COUNT = 1;
use C\D as dd;
include 'cde.php';

dd\E\passward(); //     C\D\E\passward
dd\E\COUNT; //     C\D\E\COUNT
new dd\E\action; //     C\D\E\action

useネーミングスペースをインポートすると、非限定名と限定名に影響しますが、完全限定名は名前が確定しているため影響を受けません.同様に影響を受けないのは動的に作成された名前です.使用する場合、1つの文に複数のuse文を含めることができます.
namespace test;

class action {
    public function __construct() {
        echo __METHOD__;
    }
}
namespace alias;

class action {
    public function __construct() {
        echo __METHOD__;
    }
}
namespace script{

    include 'action.php';
    include 'alias.php';

    use test\action as aliasScript, alias;

    new aliasScript; //       test\action::__construct
    new alias\action; //      alias\action::__construct
    new \action; //        action::__construct

    $action = 'action';
    new $action; //    aciton action::__construct
}

namespace {
    class action {
        public function __construct() {
            echo __METHOD__;
        }
    }
}

最後に、ネーミングスペースの解析ルールについて、公式ドキュメントから抜粋します.
1、          ,             。   new \A\B      A\B。

2、             (       )                 。  ,       A\B\C      C,    C\D\e()           A\B\C\D\e()。

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()   :
    1)、          A\B\C 。
    2)、       A\B\C。

new D\E()   :
    1)、                  :A\B\D\E,      。
    2)、        A\B\D\E。

                   ,           new \C()。

ここを見て、ネーミングスペースについて大まかに理解したと説明し、次の例を読めばネーミングスペースは把握できます.
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"

ps:本学習ノートは公式教材を参照して来ました.