ホームページ > バックエンド開発 > PHPチュートリアル > PHPの名前空間(Namespace)の使い方を詳しく解説

PHPの名前空間(Namespace)の使い方を詳しく解説

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
リリース: 2016-06-23 13:26:55
オリジナル
832 人が閲覧しました

名前空間については、公式ドキュメントで詳細に説明されています [表示] ので、ここでいくつかの練習と要約を行いました。

名前空間の最も明確な目的の 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

// スクリプトの前にいくつかの文字が出力されます


namespace Article;

?>

なぜ最初の名前空間を言う必要がありますか?同じスクリプト ファイル内に複数の名前空間を作成できるためです。

以下では、2 つの名前空間を作成し、これら 2 つの空間のそれぞれに Comment クラス要素を追加しました:

次のようにコードをコピーします:

//名前付きの 'Article' 名前空間を作成します

namespace Article;

//このコメントは Article space の要素に属します

class Comment { }


//「MessageBoard」という名前の名前空間を作成します

namespace MessageBoard;

//この Comment は MessageBoard に属する要素ですspace

class Comment { }
?>


名前空間構文を使用する必要があります:

< ?php


namespace Article;

class Comment { }


namespace MessageBoard;

class Comment { }

//現在のスペース (MessageBoard) の Comment クラスを呼び出します

$comment = new Comment();


//Call Article スペースの Comment クラス

$article_comment = new ArticleComment();

?>


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();

//Article スペースの定数、関数、クラスを呼び出す

echo ArticlePATH; ///article
echo ); //100
$article_comment = new ArticleComment();

?>

そして、Article スペースの要素データを取得しました。


サブスペース
ネームスペースの呼び出し構文はファイル パスに似ており、これにより、各スペース間の関係を記述するためにサブスペースをカスタマイズできます。

申し訳ありませんが、2 つのモジュールの記事と掲示板が実際には同じブログ プロジェクト内にあることを言及するのを忘れていました。名前空間を使用してそれらの関係を表現すると、次のようになります:

次のようにコードをコピーします:

//このような名前空間を使用して、ブログの下の記事モジュールを表します

namespace BlogArticle ;

class Comment { }

//この名前空間を使用して、ブログの下のメッセージ ボード モジュールを表します
namespace BlogMessageBoard;

class Comment { }

//現在のスペースのクラスを呼び出します

$comment = new Comment( );
调 // blogarticle スペースを呼び出すクラス

$ Article_Comment = New BlogarticalComment (); パブリック スペース


いくつかの便利な関数とクラスが含まれる common_inc.php スクリプト ファイルがあります。


function getIP() { }

class FilterXSS { }

?>

このスクリプトを名前空間に導入すると、スクリプト内の要素は次の名前空間に属しません。この名前空間。このスクリプトで他の名前空間が定義されていない場合、その要素は常にパブリック スペースにあります:

次のようにコードをコピーします:


namespace BlogArticle;

//スクリプト ファイルを紹介します

include ' ./common_inc.php';

$filter_XSS = new FilterXSS(); //致命的なエラー: BlogArticleFilterXSS クラスが見つかりません

$filter_XSS = new FilterXSS()?>

パブリック スペースを呼び出す方法は、要素名の直前にパブリック スペースを追加することです。そうしないと、PHP パーサーは現在のスペース内の要素を呼び出す必要があると認識します。カスタム要素に加えて、PHP 独自の要素も含まれており、それらはすべてパブリック スペースに属します。


実際、パブリックスペースの関数や定数は追加しなくても通常どおり呼び出すことができますが (なぜ 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)を参照するとわかりやすいかもしれません。

それらを表すためにいくつかの例を使用しました:


次のようにコードをコピーします:



//スペースを作成する Blog
namespace Blog;

class Comment { }

/ /現在のブログ スペースを示す非修飾名です

//この呼び出しは BlogComment();

$blog_comment = new Comment(); に解析されます

//ブログスペースに関連することを示す修飾名
//この呼び出しは BlogArticleComment();
$article_comment = new ArticleComment(); //クラスの前にバックスラッシュはありません

//完全ブログスペースへの絶対を示す修飾名
//この呼び出しは BlogComment();
$article_comment = new BlogComment() //クラスの前にバックスラッシュがあります

//完全修飾名を示しますブログスペースへの絶対値
// この呼び出しは BlogArticleComment();
$article_comment = new BlogArticleComment(); //クラスの前にバックスラッシュがあります


//ブログ記事
名前空間のサブスペースを作成しますBlogArticle;

class Comment { }

?>


実はこれまで非修飾名と完全修飾名を使ってきましたが、ようやく名前で呼べるようになりました。


エイリアスとインポート
エイリアスとインポートは、名前空間要素を呼び出すためのショートカットと考えることができます。 PHP は関数や定数のインポートをサポートしていません。

これらはすべて use 演算子を使用して実装されます:

次のようにコードをコピーします:


namespace BlogArticle;

class Comment { }


//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 BlogArticle;

class Comment { }


namespace BBS;

クラス コメント { }

Class Comt { }


//クラスをインポートします
use BlogArticleComment;
$article_comment = new Comment(); //現在のスペースのコメントと競合するため、プログラムは致命的なエラーを生成します

// class
use BlogArticleComment as Comt;
$article_comment = new Comt(); //現在のスペースの Comt と競合するため、プログラムは致命的なエラーを生成します

?>


動的呼び出し
PHP は名前空間キーワードを提供しますおよび __NAMESPACE__ マジック定数 Dynamic アクセス要素 __NAMESPACE__ は、文字列を組み合わせることで動的にアクセスできます:

次のようにコードをコピーします:


namespace BlogArticle;

const PATH = '/Blog/article' ;

class Comment { }


//namespace キーワードは現在のスペースを表します
echo namespacePATH; ///Blog/article
$comment = new namespaceComment();

//マジック定数 __NAMESPACE__ の値は現在のスペース名
echo __NAMESPACE__; //BlogArticle
// を文字列に結合して、
$comment_class_name = __NAMESPACE__ と呼びます。

文字列形式の呼び出しの問題

上記の動的呼び出しの例では、文字列形式の動的呼び出しメソッドを示しましたが、このメソッドを使用する場合は、2 つの問題に注意する必要があります。



1. 二重引用符を使用する場合、特殊文字はエスケープされる可能性があります

次のようにコードをコピーします:


namespace BlogArticle;

class name { }

// 私はBlogArticlename

$class_name = __NAMESPACE__ . "name"; //ただし、n は改行文字としてエスケープされます

?>


;

2. 修飾名とは見なされません

PHP は、スクリプトのコンパイル時に要素が配置されるスペースとインポート ステータスを決定します。スクリプトを解析するとき、文字列形式の呼び出しは非修飾名と完全修飾名のみとみなされ、修飾名であることはできません。


次のようにコードをコピーします:

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 クラスが存在しません実践なしにいくつかの提案をすることはできません。個人的には、プラグインや一般的なライブラリを作成する場合、名前空間の役割と機能は非常に強力だと思います。名前の重複を心配する必要はなくなりました。ただし、プロジェクトがある程度進み、名前空間の追加によって名前の重複の問題を解決する必要がある場合、名前のリファクタリング以上の作業量になると思います。その構文によってプロジェクトがある程度複雑になることは認めざるを得ません。そのため、プロジェクトの開始時からよく計画し、命名規則を策定する必要があります。




このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート