PHP 名前空間について

不言
不言オリジナル
2018-05-14 15:52:263955ブラウズ

この記事では、特定の参考値を持つ PHP の名前空間を紹介します。必要な友達が参照できるようにします。

PHP 名前空間とは?

PHP マニュアル: 広義には、スペースという名前を付けます。物事をカプセル化する方法。この抽象化はさまざまな場所で見られます。たとえば、ディレクトリはオペレーティング システムで関連ファイルをグループ化するために使用され、ディレクトリ内のファイルの名前空間として機能します。

ネームスペースの役割

1. ユーザーが作成したコードと、PHP の内部クラス/関数/定数またはサードパーティのクラス/関数/定数の間で名前が競合します。
2. ソース コードの可読性を向上させるために、非常に長い識別子名 (通常は最初の種類の問題を軽減するために定義される) のエイリアス (または短い) 名を作成します。

私がこの名前空間の記事を書いたのは、友人がこれを知り、名前空間とは何なのかと尋ねたからです。それをどうやってシンプルに、分かりやすく表現するか考えました。以下では、名前空間についての私自身の理解を説明するために、いくつかの簡単な例を使用します。

1.例1
まず2つのクラスファイルを作成します
a.php

class Test{
    public function test()
    {
        echo "this is A class.";
    }
}

b.php

class Test{
    public function test()
    {
        echo "this is B class.";
    }
}

次に、上記の2つのクラスを導入するindex.phpファイルを作成し、Among theメソッドを呼び出します。
index.php

require_once("a.php");require_once("b.php");

ここでindex.phpファイルを実行すると、致命的なエラーが見つかります: Fatal error: Cannot redeclare class Test in. 。 。明らかに、Test クラスは 2 回導入されており、2 つのファイル内のクラス名が同じで競合しているため、再宣言することはできません。このとき、この問題を解決するには名前空間が必要ですが、それは簡単です。
2. 例 2
次に、2 つのクラス ファイルを少し変更します。
a.php

namespace a\test;class Test{
    public function test()
    {
        echo "this is A class.";
    }
}

b.php

namespace b\test;class Test{
    public function test()
    {
        echo "this is B class.";
    }
}

namespace キーワードは、名前空間を宣言するために使用されます。ここで、index.php を実行し、エラーがないことを確認します。 .php Test クラスを複数回インスタンス化するため、毎回完全な名前空間情報を記述するのが面倒な場合はどうすればよいでしょうか?例:
index.php

require_once("a.php");require_once("b.php");$a = new a\test\Test();$a->test();//页面输出:this is A class.

エラーは発生しませんが、毎回完全な名前空間名を記述する必要があります。ただし、エラーは発生せず、ctrl+c、ctrl+を押します。 v、あまり美しくありません(^_^)。

これを実行できます: index.php

require_once("a.php");require_once("b.php");$a = new a\test\Test();$a_a = new a\test\Test();$a_b = new a\test\Test();$a->test();$a_a->test();//页面输出:this is A class.this is A class.
use キーワードはクラスを導入するために使用され、名前空間を使用して特定のクラスの使用を示します。後で操作を直接インスタンス化できます


4.
例 5 次に、次のような別の問題が発生します:

index.php

require_once("a.php");require_once("b.php");use a\test\Test;$a = new Test();$a_a = new Test();$a_b = new Test();$a->test();$a_a->test();//页面输出:this is A class.this is A class.

明らかに、別の致命的なエラー: 致命的なエラー: btestTest をテストとして使用できません。名前はすでに で使用されています。 。 。名前空間は使用されていますが、2 つのクラスは同じ名前であり、両方とも Test であるため、プログラムは 2 番目の Test クラスが b.php の Test クラスであることを知りません。 このとき、as キーワードを使用します as:

index.php
require_once("a.php");require_once("b.php");use a\test\Test;use b\test\Test;$a = new Test();$b = new Test();$a->test();$b->test();

as キーワードは、同じクラス名との競合を効果的に防ぐことができるクラス名のエイリアスを定義します
5.
例 6 次に、別の状況を示します。最初にいくつかのコード スニペットを示します。これは Yii2 フレームワーク内にあり、フレームワークとは何の関係もありません。この例は、さまざまな場所で見ることができます。

require_once("a.php");require_once("b.php");use a\test\Test;use b\test\Test as BTest;$a = new Test();$b = new BTest();$a->test();$b->test();//页面输出:this is A class.this is B class.完美解决

ここでは明らかに Yii クラスが使用されていますが、その前にバックスラッシュ "" があるのはなぜですか? まず Yii クラスを追跡しましょう。

PHPstorm エディターを使用している場合は、それを追跡する方法を尋ねる生徒もいます。 Ctrl キーを押しながらマウスでクラス名をクリックすると、このクラス ファイルにジャンプします PHPstorm エディターの使用方法については、PhpStorm のクラック版と使用方法のチュートリアルを参照してください。以下は Yii クラス ファイルのコード スニペットです:

if (\Yii::$app->request->isPost) {
            $post = \Yii::$app->request->post();           ...
        }
You Yii クラスには名前空間がないことがわかります。このクラスをグローバル クラスと呼びます。たとえば、クラスの前にバックスラッシュ "" を追加する必要があります。 a.php と同じレベルのグローバル クラス ファイル: c.php:
/**
 * Yii bootstrap file.
 *
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */require(__DIR__ . '/BaseYii.php');class Yii extends \yii\BaseYii{
}

c.php のテスト メソッドを呼び出すには、index.php ファイルでこれを実行します

class Test{
    public function test()
    {
        echo "this is C class.";
    }
}

注: 名前空間などのキーワードの使用、use、as、およびグローバル クラスの使用。 PHP 名前空間とは何ですか?

PHP マニュアル: 大まかに言えば、名前空間は物事をカプセル化する方法です。この抽象的な概念はさまざまな場所で見られます。たとえば、ディレクトリはオペレーティング システムで関連ファイルをグループ化するために使用され、ディレクトリ内のファイルの名前空間として機能します。


ネームスペースの役割

1. ユーザーが作成したコードと、PHP の内部クラス/関数/定数またはサードパーティのクラス/関数/定数の間で名前が競合します。

2. ソース コードの可読性を向上させるために、非常に長い識別子名 (通常は最初のタイプの問題を軽減するために定義される) のエイリアス (または短い) 名を作成します。

示例

写这个命名空间的文章是因为一个朋友刚学这个来问我命名空间到底是个什么东西。我在想怎么简单的描述出来并且很容易理解。下面我就以几个简单的小例子来说明一下我自己对命名空间的理解。

1. 例一
首先我们先建立两个类文件
a.php

class Test{
    public function test()
    {
        echo "this is A class.";
    }
}

b.php

class Test{
    public function test()
    {
        echo "this is B class.";
    }
}

再建立一个index.php文件,来引入以上两个类并调用其中的方法。
index.php

require_once("a.php");require_once("b.php");

现在运行index.php文件,你会发现有一个致命错误: Fatal error: Cannot redeclare class Test in。。。很显然,无法重新声明Test类,因为你引入了两次,而且两个文件中的类名称相同,冲突了。这个时候就需要命名空间来解决这个问题,并且很容易。
2. 例二
我们现在把两个类文件稍作修改。
a.php

namespace a\test;class Test{
    public function test()
    {
        echo "this is A class.";
    }
}

b.php

namespace b\test;class Test{
    public function test()
    {
        echo "this is B class.";
    }
}

namespace关键字是用来声明命名空间的。现在运行index.php发现没有错误,修改index.php进行方法调用测试
index.php

require_once("a.php");require_once("b.php");$a = new a\test\Test();$a->test();//页面输出:this is A class.

3. 例三
现在有另外一种情况,比如我需要实例化a.php中的Test类多次,那么每次我们都需要命名空间信息完整写的话比较麻烦怎么办呢?比如:
index.php

require_once("a.php");
require_once("b.php");
$a = new a\test\Test();
$a_a = new a\test\Test();
$a_b = new a\test\Test();
$a->test();
$a_a->test();
//页面输出:
this is A class.this is A class.

虽然也没有错误,但是你会发现比较麻烦,每次都需要全写命名空间名称,虽然不报错并且可以ctrl+c,ctrl+v,但是不太美观(^_^)。
你可以这样做:
index.php

require_once("a.php");
require_once("b.php");
use a\test\Test;
$a = new Test();
$a_a = new Test();
$a_b = new Test();
$a->test();
$a_a->test();
//页面输出:
this is A class.this is A class.

use关键字是用来引入类,用命名空间的方式表示使用了某个类。后面就可以直接实例化操作
4. 例五
接下来另一个问题又来了,如下:
index.php

require_once("a.php");require_once("b.php");use a\test\Test;use b\test\Test;$a = new Test();$b = new Test();$a->test();$b->test();

很明显,又一个致命错误:Fatal error: Cannot use b\test\Test as Test because the name is already in use in 。。。因为虽然使用了命名空间,但是两个类名称相同,都是Test,程序不知道第二个Test类是b.php中的Test类,这时候你就用到了as关键字
如:
index.php

require_once("a.php");
require_once("b.php");
use a\test\Test;
use b\test\Test as BTest;
$a = new Test();
$b = new BTest();
$a->test();$b->test();
//页面输出:
this is A class.this is B class.完美解决

as关键字是对类名称定义别名,可以有效防止类名称相同冲突
5. 例六
下面是另一种情况,我先给出几个代码片段,是Yii2框架中的,和框架无关,只是为了演示使用,很多地方都能见到此例。

if (\Yii::$app->request->isPost) {
            $post = \Yii::$app->request->post();           ...
        }

很显然这里使用了一个Yii类,但是为什么前面又一个反斜杠”\”,我们先追踪一下Yii类,有的同学会问怎么追踪呢,如果你使用的是PHPstorm编辑器,直接按住Ctrl,鼠标点击类名就会跳到此类类文件中,关于怎么使用PHPstorm编辑器,请查看:PhpStorm破解版及使用教程
下面是Yii类文件代码段:

/**
 * Yii bootstrap file.
 *
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */require(__DIR__ . '/BaseYii.php');class Yii extends \yii\BaseYii{
}

你会发现该Yii类并没有命名空间,我们将这种类叫做全局类,如果要使用需要类前面加入反斜杠”\”
比如我们在a.php同级再建立一个全局类文件:c.php:

class Test{
    public function test()
    {
        echo "this is C class.";
    }
}

在index.php文件中这样做即可调用c.php中的test方法

require_once("a.php");
require_once("b.php");
require_once("c.php");
use a\test\Test;
use b\test\Test as BTest;
$a = new Test();
$b = new BTest();
$c = new \Test();
$a->test();
$b->test();
$c->test();
//页面输出:
this is C class.this is A class.this is B class.this is C class.

注意:namespace,use,as等关键字用法以及全局类的使用。

以上がPHP 名前空間についての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。