PHP の名前空間のサポートは、困難な道のりを経てきました。幸いなことに、PHP は 5.3 から名前空間を導入しました。 PHP に名前空間が導入されて以来、適用可能な PHP コードの構造も大幅に改善されました。多くのプログラミング言語には以前から名前空間の概念がありましたが、他の言語に比べて、PHP の名前空間のサポートは少し遅れています。いずれにしても、すべての新機能の導入には目的があります。他の言語と同様に、PHP は主に名前の競合の問題を解決するために名前空間を導入します。
名前空間の概念
コードをコピーします コードは次のとおりです:
文字列内で名前空間名を使用する場合は、必ずエスケープしてください
ネームスペースは引き出しのようなもので、鉛筆や定規、A4用紙などを収納できます。あなたの引き出しの下には他の人の引き出しがあり、他の人がその引き出しに同じアイテムを入れることができます。アイテムを間違えないように、引き出しにラベルを貼って、そのアイテムが誰のものであるかを明確に確認できるようにすることにしました。
以前は、コードをコードベースから独立させるために、開発者はクラス、関数、定数にアンダースコアを追加する必要がありました。これは、全員が自分の持ち物にラベルを付けて、大きな引き出しに入れるのと同じです。これはコードを整理する方法ですが、非常に非効率的です。
名前空間はこの問題を解決するために登場しました。名前の競合を引き起こすことなく、異なる名前空間で同じ関数、クラス、定数を宣言できます。本質的に、ネームスペースは PHP コードを階層的にマークする方法にすぎません。
ネームスペースの使用
注意すべき点の 1 つは、名前空間を間接的に使用していることです。 PHP 5.3 以降、ユーザー定義以外の名前空間内のすべての宣言 (クラス、関数、定数) は、デフォルトでグローバル名前空間に属します。
グローバル名前空間には、echo()、mysqli_connect()、Exception クラスなどのすべての PHP 内部定義が含まれます。グローバル名前空間には独立した識別子がないため、グローバル空間と呼ばれることがよくあります。
名前空間を定義する
名前空間の定義は、PHP ファイルの最初のステートメントである必要があります。名前空間を定義する前に許可される唯一のステートメントは、declare ステートメントです。
ネームスペースの定義は非常に簡単で、キーワード namespace を使用するだけです。ネームスペースの名前は、PHP ファイル内の他の識別子の命名規則に従う必要があります。
名前空間を定義する例を次に示します:
コードをコピーします コードは次のとおりです:
名前空間 MyNamespace{
クラステスト{
}
}
グローバル空間に属するコード ブロックを定義する場合は、次のように namespace キーワードも使用しますが、その後に名前空間の名前を追加しないでください。
コードをコピーします コードは次のとおりです:
名前空間 {
クラステスト{
}
}
次のように、1 つのファイルで複数の名前空間を定義することもできます:
コードをコピーします コードは次のとおりです:
名前空間 MyNamespace {
}
名前空間 MySecondNamespace {
}
名前空間 {
}
コードをコピーします コードは次のとおりです:
注意すべき点の 1 つは、名前空間コード ブロックを含む { はオプションであり、使用してもしなくてもよいことです。実際、ファイル内で名前空間を 1 つだけ定義することに固執する限り、{ を完全に省略できます。これにより、コードをより簡潔に見せることもできます。
サブネームスペース
名前空間は、コンピューターのファイル システムのディレクトリと同じように、特定の階層に従うことができます。サブネームスペースは、プロジェクトを構築する場合に特に役立ちます。たとえば、プロジェクトがデータベースにアクセスする必要がある場合、すべてのデータベース関連コード (データベース例外処理など) を同じサブディレクトリに配置することができます。柔軟性を維持するには、サブディレクトリにサブ名前空間を配置することが非常に賢明です。これにより、コード構造がより明確になり、PSR-0 標準に準拠したオートローダーを使用しやすくなります。
PHP は名前空間区切り文字としてバックスラッシュを使用します。興味深いことに、PHP は名前空間区切り文字としてスマイリーフェイスを使用することも検討していました:)
サブ名前空間定義の例:
コードをコピーします コードは次のとおりです:
名前空間 MyProjectDatabase
クラス接続 {
}
サブネームスペースは好きなだけ使用できます:
コードをコピーします コードは次のとおりです:
名前空間 MyProjectBlogAuthHandlerSocial;
クラスツイッター{
}
注意すべき点の 1 つは、PHP は名前空間のネストされた定義をサポートしていないということです。次のコードでは致命的なエラーが発生します: 名前空間宣言はネストできません。
コードをコピーします コードは次のとおりです:
名前空間 MyProject {
名前空間データベース {
クラス接続 { }
}
}
名前空間からコードを呼び出す
クラスをインスタンス化する場合、関数を呼び出す場合、または別の名前空間の定数を使用する場合は、バックスラッシュを使用する必要があります。それらは 3 つの観点から分析できます:
1.不完全な名前
2.限定ネーム
3. 完全修飾名
不適格な名前
これはクラス、関数、または定数の名前ですが、名前付き参照は含まれません。名前空間に慣れていない場合は、これがよく知られた角度です。
コードをコピーします コードは次のとおりです:
名前空間 MyProject;
クラス MyClass {
静的関数 static_method()
{
エコー「こんにちは、世界!」;
}
}
// 修飾されていない名前。現在いる名前空間 (MyProjectMyClass) に解決されます
MyClass:static_method();
修飾名
これがサブ名前空間の使用方法です。例は次のとおりです:
コードをコピーします コードは次のとおりです:
名前空間 MyProject;
'myproject/database/connection.php' が必要です;
// 修飾名。MyProject のサブ名前空間からクラスをインスタンス化します
$connection = new DatabaseConnection();
完全修飾名
上記の修飾名と非修飾名の使用はすべて、現在の名前空間に関連しています。上記の 2 つのメソッドは、現在の名前空間とさらに深いサブ名前空間にアクセスする場合にのみ使用できます。
前の名前空間よりも高いレベルの名前空間にアクセスしたい場合は、完全修飾名、つまり相対パスではなく絶対パスを使用する必要があります。これは、要約すると、名前空間の先頭にバックスラッシュを追加することになります。完全修飾名を使用すると、呼び出しが現在の名前空間に関連するものではなく、グローバル空間から行われていることを PHP に認識させます。例は次のとおりです:
コードをコピーします コードは次のとおりです:
名前空間 MyProjectDatabase;
'myproject/fileaccess/input.php' が必要です;
// MyProjectFileAccessInput クラスにアクセスしようとしています
// 今回は完全修飾名を使用しているため機能しますが、先頭のバックスラッシュに注意してください
$input = 新しい MyProjectFileAccessInput();
PHP の内部関数の場合、完全修飾名を使用する必要はありません。現在の名前空間に存在しない非修飾名でクラスまたは関数を呼び出すと、PHP はグローバル空間を検索します。
このルールを念頭に置くと、PHP の内部関数を次のように書き換えることができます:
コードをコピーします コードは次のとおりです:
名前空間 MyProject;
var_dump($query); // オーバーロードされました
var_dump($query); // 内部
// グローバル例外クラスにアクセスしたいです
// MyProjectDatabase 名前空間には Exception というクラスがなく、修飾されていないクラス名にはグローバル空間へのフォールバックがないため、以下は機能しません
// 新しい例外をスローします('クエリが失敗しました!');
// 代わりに、単一のバックスラッシュを使用して、グローバル空間から解決したいことを示します
新しい例外をスローします('ailed!');
関数 var_dump() {
echo 'オーバーロードされたグローバル var_dump()!
';
}
ダイナミックな通話
PHP は動的言語であり、PHP のこの機能は名前空間の呼び出しにも使用できます。これは、変数クラスをインスタンス化し、変数ファイルをインクルードすることと本質的に同じです。文字列では、PHP で使用される名前空間区切り文字 () もメタキャラクターであるため、エスケープする必要があります。
コードをコピーします コードは次のとおりです:
名前空間 OtherProject;
$project_name = 'マイプロジェクト';
$package_name = 'データベース';
$class_name = '接続';
// 変数ファイルをインクルードします
require strto lower($project_name . '/' . $package_name . '/' . $class_name) .
// 変数名前空間内の変数クラスの名前。バックスラッシュを適切に使用するためにどのようにエスケープされるかに注意してください。
$full_qualified_name = $project_name . $package_name;
$connection = new $full_qualified_name();
キーワード namespace は、名前空間を定義するために使用できるだけでなく、現在の名前空間を明示的に表すためにも使用できます。このときの機能は、クラスの self キーワードと同等です。
コードをコピーします コードは次のとおりです:
名前空間 MyProject;
関数 run()
{
echo '名前空間から実行中!';
}
// MyProjectrun に解決されます
run();
// MyProjectrun
に明示的に解決されます
名前空間実行();
self キーワードが現在のクラスの名前を表すことができないのと同様に、namespace キーワードを使用して現在の名前空間の名前を表すことはできません。 __NAMESPACE__ キーワードは、この問題を解決するために使用されます。
コードをコピーします コードは次のとおりです:
名前空間 MyProjectDatabase;
// 'MyProjectDatabase'
echo __NAMESPACE__;
このキーワードは、現在のコードが名前空間から始まるかどうかを判断するのに非常に役立ち、コードのデバッグにも使用できます。
インポートまたはエイリアス
コードをコピーします コードは次のとおりです:
[クラス、インターフェイス、または名前空間の名前] を [optional_custom_alias] として使用します
完全修飾名は非修飾のエイリアスで置き換えることができるため、完全修飾名を使用するたびに完全修飾名を使用する必要がなくなり、コードが簡素化されます。インポートは、名前空間の最上位レベルまたはグローバル空間で使用する必要があります。関数スコープ内でインポート関数を使用するのは不正な構文です。
コードをコピーします コードは次のとおりです:
名前空間 OtherProject;
// これは、Connection クラスを含む MyProjectDatabase 名前空間を保持します
'myproject/database/connection.php' が必要です;
// MyProject のデータベース接続にアクセスしたい場合は、別の名前空間にいるため、その完全修飾名を使用する必要があります
$connection = new MyProjectDatabaseConnection();
// Connection クラスをインポートします (インターフェイスでもまったく同じように機能します)
MyProjectDatabaseConnection を使用します;
// これでも機能するようになりました! Connection クラスにエイリアスが付けられる前は、PHP は OtherProjectConnection クラスを見つけられませんでした
$connection = new Connection();
//MyProjectDatabase 名前空間をインポートします
MyProjectDatabase を使用します;
$connection = new DatabaseConnection()
エイリアスを使用して上記のコードを簡素化できます:
コードをコピーします コードは次のとおりです:
名前空間 OtherProject;
'myproject/database/connection.php' が必要です;
MyProjectDatabaseConnection を MyConnection として使用します;
$connection = new MyConnection();
MyProjectDatabase を MyDatabase として使用します;
$connection = new MyDatabaseConnection();
名前空間は、定義の競合を回避し、より柔軟で組織化されたコード方法を導入するために使用されます。注意すべき点の 1 つは、名前空間を使用する義務はないということです。名前空間はオブジェクト指向と組み合わせて使用される方法です。ただし、名前空間を使用すると、コードが新しいレベルに到達し、品質が向上する可能性があります。