PHPの名前空間

PHPの名前空間には、名前空間に関する多くの記事がありますが、これは私を助けてくれたので、共有したいと思います。 確かに、この翻訳が役立つ人々がいます。

PHPでの名前空間サポートへのパスは厄介でした。 しかし幸いなことに、PHP 5.3の言語に追加され、それ以来PHPコードの構造が大幅に改善されました。 しかし、どのように正確に使用しますか?

名前空間とは何ですか?


「名前空間名を文字列として保存するときは、バックスラッシュを忘れないでください!」

名前空間を、鉛筆、定規、紙など、何でも入れられるボックスとして想像してください。 これらはあなたのものです。 あなたの引き出しのすぐ下に、他の誰かの引き出しがあり、その所有者は同じものを保管しています。 互いのアイテムを使用しないように、ボックスにラベルを付けて、誰のものかが明確になるようにしました。

以前は、開発者はクラス、関数、および定数でアンダースコア付きのプレフィックスを使用してコードを分離する必要がありました。 これは、誰もが自分の物にマークを付け、1つの大きな箱に保管されるという事実と同等です。 もちろん、これは少なくとも何らかの組織ですが、非常に非効率的です。

名前空間が役立ちます! 致命的なエラーを受け取ることなく、同じ関数、クラス、インターフェイスを宣言し、別々のネームスペースで定数を定義できます。 コアでは、名前空間は、通常のPHPコードを含むコードの階層ラベル付きブロックにすぎません。

それらを使用します!


名前空間を間接的に使用していることを理解することが重要です。 PHP 5.3以降、ユーザー定義の名前空間でまだ宣言されていないすべての定義は、グローバル名前空間に分類されます。

グローバル名前空間には、 mysqli_connect()などのすべての内部PHP定義、およびExceptionクラスも格納されます。 グローバル名前空間には一意の識別名がないため、ほとんどの場合、 グローバル名前空間と呼ばれます。
名前空間の使用はオプションであることに注意してください。
PHPスクリプトはそれらがなくても正常に機能しますが、この動作はすぐに変わることはありません。

名前空間の定義


名前空間を含むファイルには、他のコードの前に宣言を最初に含める必要があります。 名前空間の前で宣言できるのは予約語declareです。 declare式は名前空間宣言の前に現れてファイルのエンコーディングを示すことができます。

名前空間は、予約語namespaceを使用して宣言されnamespace 。 名前空間は、PHPの他の識別子と同じ規則に従います。 したがって、名前空間は文字またはアンダースコアで始まり、その後に任意の数の文字、数字またはアンダースコアが続く必要があります

 <?php namespace MyProject { //  PHP   , -  function run() { echo 'Running from a namespace!'; } } 

グローバルスペースでコードブロックを定義する場合は、 namespaceを追加せずにnamespaceキーワードを使用できます。

 <?php namespace { //  ! } 

1つのファイルで複数の名前空間を使用できます。

 <?php namespace MyProject { } namespace MySecondProject { } namespace { } 

複数の異なるファイルに同じ名前空間を使用することもできます。 ファイルを接続するプロセスは自動的にそれらをマージします。 クラスの場合と同様に、名前空間定義の数を1つのファイルに制限することは、コーディングの良い習慣です。
名前空間は、定義の競合を回避し、プログラムコードの柔軟性と編成を高めるために使用されます。

中括弧は完全にオプションであることに注意してください。 実際、1つのファイルで1つの名前空間の規則を使用し、中括弧を省略すると、コードがよりきれいになります-埋め込みコードのインデント(タブ)は不要です。

名前空間


名前空間は、コンピューター上のファイルシステムのディレクトリのように、特定の階層に従うことができます。 名前空間は、プロジェクト構造の編成に非常に役立ちます。 たとえば、プロジェクトがデータベースへのアクセスを必要とする場合、データベース例外ハンドラーと接続ハンドラーのコードをDatabase名前空間に配置できます。

柔軟性のために、ネストされた名前空間をサブディレクトリに保存するのが賢明です。 これは、プロジェクトの構造化に役立ち、PSR-4標準に準拠したオートローダーでの使用をはるかに容易にします。

PHPは、名前空間の区切り文字としてバックスラッシュを使用します。

画像

興味深い事実: RFCでは 、どの名前空間区切り文字を使用するかを決定するために、絵文字を使用するオプションが検討されました。

 // myproject/database/connection.php <?php namespace MyProject\Database class Connection { //      } 

ネストされたネームスペースは必要な数だけ使用できます。

 <?php namespace MyProject\Blog\Auth\Handler\Social; class Twitter { //    Twitter } 

ネストされたコードブロックで名前空間を定義することはサポートされていません。 次の例は致命的なエラーを返します:「名前空間宣言はネストできません」。

 <?php namespace MyProject { namespace Database { class Connection { } } } 

名前空間からコードを呼び出す


オブジェクトの新しいインスタンスを作成したり、関数を呼び出したり、異なる名前空間の定数を使用したりする場合は、バックスラッシュを使用します。 名前空間名の定義には3つのタイプがあります。




不完全な名前


これは、名前空間への参照を含まないクラス、関数、または定数の名前です。 名前空間で作業を始めたばかりの人にとって、これは一般的な視点です。

 <?php namespace MyProject; class MyClass { static function static_method() { echo 'Hello, world!'; } } //  ,      (MyProject\MyClass) MyClass:static_method(); 

氏名


したがって、名前空間の階層にアクセスできます。 バックスラッシュで区切られます。

 <?php namespace MyProject; require 'myproject/database/connection.php'; //  ,      MyProject $connection = new Database\Connection(); 

次の例は致命的なエラーを返します。「致命的なエラー:クラス 'MyProject \ Database \ MyProject \ FileAccess \ Input' not found」 MyProject\FileAccess\Input現在のネームスペースに関連していない

 <?php namespace MyProject\Database; require 'myproject/fileaccess/input.php'; //    MyProject\FileAccess\Input  $input = new MyProject\FileAccess\Input(); 

絶対名


現在の名前空間に関連して、完全な名前と不完全な名前が使用されます。 これらは、このレベルでアクセスを定義するか、名前空間の階層をより深く掘り下げるためにのみ使用できます。

階層の上位レベルにある関数、クラス、または定数にアクセスする場合は、相対名ではなく絶対パスを使用する必要があります。 呼び出しはバックスラッシュで始まる必要があります。 これにより、PHPは、この呼び出しは現在の位置に関連してアクセスするのではなく、グローバルスペースから行う必要があることを理解できます。

 <?php namespace MyProject\Database; require 'myproject/fileaccess/input.php'; //    MyProject\FileAccess\Input  //     ,      ,     $input = new \MyProject\FileAccess\Input(); 

PHPの内部関数にフルネームを使用する必要はありません。 関数および定数の不完全な名前は、現在のネームスペースで定義されていない場合、グローバルネームスペースで定義されます。

これを知って、元の関数(または定数)を呼び出すことができる一方で、PHPの内部関数をオーバーロードできるようになりました。

 <?php namespace MyProject; var_dump($query); //  \var_dump($query); //  //       Exception  //      ,    Exception     MyProject\Database           // throw new Exception('Query failed!'); //  ,    ,  ,        throw new \Exception('ailed!'); function var_dump() { echo 'Overloaded global var_dump()!<br />'; } 

動的な呼び出し


PHPは動的なプログラミング言語です。 そのため、この機能を使用して名前空間からコードを呼び出すことができます。 これは、動的クラス名を使用すること、または変数を使用してその名前を保存する動的ファイルをアタッチすることと本質的に同じです。 PHPの名前区切り文字は、文字列で同じメタ文字を使用します。 名前空間名を文字列として保存するときは、バックスラッシュを忘れないでください!

 <?php namespace OtherProject; $project_name = 'MyProject'; $package_name = 'Database'; $class_name = 'Connection'; //    require strtolower($project_name . '/'. $package_name . '/' . $class_name) . '.php'; //       .        $fully_qualified_name = $project_name . '\\' . $package_name . '\\' . $class_name; $connection = new $fully_qualified_name(); 

キーワードnamespace


namespaceキーワードは、名前空間を定義するために使用されるだけでなく、機能selfはクラスのselfキーワードと同様に、現在の名前空間を呼び出すためにも使用できます。

 <?php namespace MyProject; function run() { echo 'Running from a namespace!'; } // Resolves to MyProject\run run(); // Explicitly resolves to MyProject\run namespace\run(); 

__NAMESPACE__


selfキーワードを使用して現在のクラスの名前を決定できないように、 namespaceキーワードを現在のネームスペースに使用することはできません。 したがって、定数__NAMESPACE__を使用し__NAMESPACE__

 <?php namespace MyProject\Database; // 'MyProject\Database' echo __NAMESPACE__; 

この定数は、名前空間の調査の開始時に非常に役立ちます。 また、デバッグ時に非常に便利です。 これは文字列であるため、上記の動的コード呼び出しと組み合わせて使用​​できます。

名前のエイリアスをインポートまたは作成する


名前空間で使用するオプション

PHPの名前空間の重要な機能は、 エイリアスまたはインポートによって外部の絶対名を参照する機能です。

インポートは、名前空間の非常に便利で基本的な側面です。 これにより、名前の競合を心配することなく、ライブラリなどの外部パッケージを使用できます。 インポートは、useキーワードを使用して行われます。 オプションで、asキーワードを使用してカスタムエイリアスを指定できます。

 use [name of class, interface or namespace] as [optional_custom_alias] 

使い方


絶対名は、より短い不完全な名前に結び付けることができるため、使用するたびに絶対名を記述する必要はありません。 エイリアスの作成またはインポートは、親ネームスペースで、またはグローバルに行われる必要があります。 メソッドまたは関数内でこれを実行しようとするのは無効な構文です。

 <?php namespace OtherProject; // This holds the MyProject\Database namespace with a Connection class in it require 'myproject/database/connection.php'; //         MyProject,      ,         $connection = new \MyProject\Database\Connection(); //   Connection (     ) use MyProject\Database\Connection; //   !     Connection   , PHP    OtherProject\Connection $connection = new Connection(); //    MyProject\Database use MyProject\Database; $connection = new Database\Connection() 

別の方法は、別名を別の名前で割り当てる機能です

 <?php namespace OtherProject; require 'myproject/database/connection.php'; use MyProject\Database\Connection as MyConnection; $connection = new MyConnection(); use MyProject\Database as MyDatabase; $connection = new MyDatabase\Connection(); 

例外などのグローバルクラスをインポートすることもできます。 インポートするとき、その絶対名を書く必要はありません。

インポートされた名前は絶対でなければならず、現在のネームスペースに関連して処理されないため、ネームスペース内の名前には最初のバックスラッシュは不要であり、その存在は推奨されません。

 <?php namespace MyProject; // Fatal error: Class 'SomeProject\Exception' not found throw new Exception('An exception!'); // OK! throw new \Exception('An exception!'); //   Exception. use Exception; // OK! throw new Exception('An exception!'); 

動的な名前空間の呼び出しがサポートされていますが、動的なインポートはサポートされていません。

 <?php namespace OtherProject; $parser = 'markdown'; //   require 'myproject/blog/parser/' . $parser . '.php'; //    use MyProject\Blog\Parser\$parser; 

おわりに


名前空間は、定義の競合を回避し、プログラムコードに柔軟性と編成を導入するために使用されます。 名前空間を使用する必要はないことに注意してください。 この機能は、オブジェクト指向のアプローチと組み合わせて使用​​されます。 名前空間を使用して(将来の)PHPプロジェクトを新しいレベルに引き上げることを検討してください。

Source: https://habr.com/ru/post/J245893/


All Articles