ホームページ >バックエンド開発 >PHPチュートリアル >PHPの名前空間(Namespace)の使い方を詳しく解説
名前空間については、公式ドキュメントで詳細に説明されています [表示] ので、ここでいくつかの練習と要約を行いました。
名前空間の最も明確な目的の 1 つは、重複した名前の問題を解決することです。PHP では、2 つの関数またはクラスが同じ名前を持つことを許可しません。そうしないと、致命的なエラーが発生します。この場合、名前の重複を避ける限り解決できます。最も一般的な方法は、プレフィックスを合意することです。
例: プロジェクトには記事とメッセージボードの 2 つのモジュールがあり、それぞれにユーザーのコメントを処理するクラス Comment があります。後で、すべてのユーザー メッセージの情報統計関数を追加する場合があります。たとえば、すべてのメッセージの数を取得したいとします。この時点で、Comment によって提供されるメソッドを呼び出すことは良い考えですが、それぞれの Comment クラスを同時に導入することは明らかに不可能であり、コードでエラーが発生し、Comment を別の場所に書き換えるとエラーが発生します。メンテナンス性が低下します。現時点では、クラス名のみをリファクタリングできます。私は、Article_Comment、MessageBoard_Comment のように、クラス名の前にモジュール名を追加するという命名規則に同意しました。ご覧のとおり、名前は非常に長くなります。将来コメントが使用されることを意味します。そのときが来たら、さらに多くのコード (少なくともさらに多くの文字) が記述されることになります。さらに、将来的に各モジュールに統合関数を追加したり、相互に呼び出したりする場合は、名前が重複した場合に名前を再構築する必要があります。もちろん、プロジェクトの開始時にこの問題に気づき、名前付けルールを指定することで、この問題は回避できます。別の解決策は、名前空間を使用することです。
注:
この記事で言及されている定数: PHP5.3 以降、const キーワードはクラスの外で使用できるようになりました。 const と define はどちらも定数の宣言に使用されます (その違いについては詳しく説明しません) が、名前空間では、define はグローバルに機能するのに対し、const は現在の空間に対して機能します。記事内で言及した定数は、const を使用して宣言された定数を指します。
名前空間は、コードを異なる空間(領域)に分割します。各空間内の定数、関数、クラスの名前(面倒なので、以下では要素と呼びます)は相互に影響しません。私たちがよく言及する「カプセル化」の概念に少し似ています。
名前空間を作成するには、次のように namespace キーワードを使用する必要があります:
次のようにコードをコピーします:
//「Article」という名前の名前空間を作成します
namespace記事;
?>
次のようにコードをコピーします。 //例 1
$path = "/";
class Comment { }
namespace Article;
?>
// 例 2
// スクリプトの前にいくつかの文字が出力されます
?>
以下では、2 つの名前空間を作成し、これら 2 つの空間のそれぞれに Comment クラス要素を追加しました:
//名前付きの 'Article' 名前空間を作成します
namespace Article;
//このコメントは Article space の要素に属します
class Comment { }
namespace MessageBoard;
class Comment { }
?>
名前空間構文を使用する必要があります:
class Comment { }
namespace MessageBoard;
class Comment { }
//現在のスペース (MessageBoard) の Comment クラスを呼び出します
$comment = new Comment();
//Call Article スペースの Comment クラス
?>
MessageBoard スペースの Article スペースで Comment クラスを呼び出すと、構文: Space のようなファイル パスが使用されることがわかります。 name 要素名
クラスを除き、関数と定数の使い方は同じです。 以下では、2 つのスペースに新しい要素を作成し、その値をメッセージボード スペースに出力します。
次のようにコードをコピーします。
namespace Article;
const PATH = '/article';
function getCommentTotal() {
return 100;
}class Comment { }
namespace MessageBoard;
const PATH = '/message_board';
function getCommentTotal() {
return 300;
}
class Comment { }
//現在のスペースの定数、関数、クラスを呼び出す
echo PATH ; ///message_board
echo getCommentTotal(); //300
$comment = new Comment();
echo ArticlePATH; ///article
echo ); //100
$article_comment = new ArticleComment();
そして、Article スペースの要素データを取得しました。
サブスペース
ネームスペースの呼び出し構文はファイル パスに似ており、これにより、各スペース間の関係を記述するためにサブスペースをカスタマイズできます。
次のようにコードをコピーします:
//このような名前空間を使用して、ブログの下の記事モジュールを表します
namespace BlogArticle ;
//この名前空間を使用して、ブログの下のメッセージ ボード モジュールを表します
namespace BlogMessageBoard;
//現在のスペースのクラスを呼び出します
$comment = new Comment( );
调 // blogarticle スペースを呼び出すクラス
いくつかの便利な関数とクラスが含まれる common_inc.php スクリプト ファイルがあります。
function getIP() { }
class FilterXSS { }
?>
このスクリプトを名前空間に導入すると、スクリプト内の要素は次の名前空間に属しません。この名前空間。このスクリプトで他の名前空間が定義されていない場合、その要素は常にパブリック スペースにあります:
次のようにコードをコピーします:
namespace BlogArticle;
//スクリプト ファイルを紹介します
include ' ./common_inc.php';$filter_XSS = new FilterXSS(); //致命的なエラー: BlogArticleFilterXSS クラスが見つかりません
$filter_XSS = new FilterXSS()?>
実際、パブリックスペースの関数や定数は追加しなくても通常どおり呼び出すことができますが (なぜ PHP がこれを行うのか理解できません)、要素を正しく区別するために、追加することをお勧めします。
関数呼び出し時の名前 用語
エイリアスとインポートについて話す前に、スペースの 3 つの名前の用語と、PHP がそれらを解析する方法を理解する必要があります。公式ドキュメントは非常に優れていたので、そのまま使用しました。
1. 非修飾名、またはプレフィックスのないクラス名 ($comment = new Comment(); など)。現在の名前空間が BlogArticle の場合、Comment は BlogArticleComment として解析されます。コメントを使用するコードに名前空間 (グローバル空間) のコードが含まれていない場合、コメントはコメントとして解析されます。
2. 修飾名、またはプレフィックスを含む名前 ($comment = new ArticleComment(); など)。現在の名前空間が Blog の場合、Comment は BlogArticleComment として解析されます。コメントを使用するコードに名前空間 (グローバル空間) のコードが含まれていない場合、コメントはコメントとして解析されます。
3. 完全修飾名、または $comment = new ArticleComment(); などのグローバル接頭辞演算子を含む名前。この場合、Comment はコード内で常にリテラル名 ArticleComment に解決されます。
それらを表すためにいくつかの例を使用しました:
次のようにコードをコピーします:
/ /現在のブログ スペースを示す非修飾名です
//この呼び出しは BlogComment();$blog_comment = new Comment(); に解析されます //ブログスペースに関連することを示す修飾名 //完全ブログスペースへの絶対を示す修飾名 //完全修飾名を示しますブログスペースへの絶対値 class Comment { } ?> これらはすべて use 演算子を使用して実装されます: 次のようにコードをコピーします: namespace BlogArticle; class Comment { } //名前空間をインポートします / /ネームスペースのエイリアスを使用します //クラスをインポートします //クラスのエイリアスを使用します ?> 例: 次のようにコードをコピーします: namespace BlogArticle; class Comment { } クラス コメント { } Class Comt { } // class ?> 次のようにコードをコピーします: namespace BlogArticle; const PATH = '/Blog/article' ; class Comment { } //マジック定数 __NAMESPACE__ の値は現在のスペース名
//この呼び出しは BlogArticleComment();
$article_comment = new ArticleComment(); //クラスの前にバックスラッシュはありません
//この呼び出しは BlogComment();
$article_comment = new BlogComment() //クラスの前にバックスラッシュがあります
// この呼び出しは BlogArticleComment();
$article_comment = new BlogArticleComment(); //クラスの前にバックスラッシュがあります
//ブログ記事
名前空間のサブスペースを作成しますBlogArticle;
実はこれまで非修飾名と完全修飾名を使ってきましたが、ようやく名前で呼べるようになりました。
エイリアスとインポート
エイリアスとインポートは、名前空間要素を呼び出すためのショートカットと考えることができます。 PHP は関数や定数のインポートをサポートしていません。
//Create a BBS スペース (フォーラムを開く予定です)
namespace BBS;
use BlogArticle;
//名前空間をインポートした後、修飾名を使用して要素を呼び出すことができます
$article_comment = new ArticleComment();
use BlogArticle as Arte;
//スペース名の代わりにエイリアスを使用します
$article_comment = new ArteComment();
use BlogArticleComment;
//クラス名の呼び出し要素をインポートした後、unqualified を使用できます
$article_comment = new Comment();
use BlogArticleComment as Comt;
//スペース名の代わりにエイリアスを使用します
$article_comment = new Comt ();
要素をインポートするときに、現在のスペースに同じ名前の要素があった場合はどうなるのでしょうか?明らかに、結果は致命的なエラーになります。
namespace BBS;
//クラスをインポートします
use BlogArticleComment;
$article_comment = new Comment(); //現在のスペースのコメントと競合するため、プログラムは致命的なエラーを生成します
use BlogArticleComment as Comt;
$article_comment = new Comt(); //現在のスペースの Comt と競合するため、プログラムは致命的なエラーを生成します
動的呼び出し
PHP は名前空間キーワードを提供しますおよび __NAMESPACE__ マジック定数 Dynamic アクセス要素 __NAMESPACE__ は、文字列を組み合わせることで動的にアクセスできます:
//namespace キーワードは現在のスペースを表します
echo namespacePATH; ///Blog/article
$comment = new namespaceComment();
echo __NAMESPACE__; //BlogArticle
// を文字列に結合して、
$comment_class_name = __NAMESPACE__ と呼びます。
1. 二重引用符を使用する場合、特殊文字はエスケープされる可能性があります
次のようにコードをコピーします:
namespace BlogArticle;
class name { }
// 私はBlogArticlename
$class_name = __NAMESPACE__ . "name"; //ただし、n は改行文字としてエスケープされます?>
;
次のようにコードをコピーします:
namespace Blog;
//Common クラスをインポートします
use BlogArticleCommon;
//非修飾名を使用して BlogArticleCommon を呼び出したいです
$common_class_name = 'Common';
//実際には非修飾名とみなされます。これは、しかし、現在のクラスは共通クラスを作成しません
$common = new $common_class_name(); //致命的なエラーが発生しました: 共通クラスが存在しません
//修飾名で BlogArticleCommon を呼び出したいです
$common_class_name = 'ArticleCommon';
// 実際には完全修飾名とみなされ、つまり Article スペースの下の Common クラスを意味しますが、以下の Article スペースではなく BlogArticle スペースのみを定義しました
$common = new $common_class_name( ); //致命的なエラーが発生しました: ArticleCommon クラスが存在しません実践なしにいくつかの提案をすることはできません。個人的には、プラグインや一般的なライブラリを作成する場合、名前空間の役割と機能は非常に強力だと思います。名前の重複を心配する必要はなくなりました。ただし、プロジェクトがある程度進み、名前空間の追加によって名前の重複の問題を解決する必要がある場合、名前のリファクタリング以上の作業量になると思います。その構文によってプロジェクトがある程度複雑になることは認めざるを得ません。そのため、プロジェクトの開始時からよく計画し、命名規則を策定する必要があります。