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