關於PHP的命名空間

不言
發布: 2023-03-24 06:54:01
原創
3866 人瀏覽過

這篇文章介紹的內容是關於PHP的命名空間 ,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

什麼是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手冊:廣義來說,命名空間是一種封裝事物的方法。在很多地方都可以看到這種抽象概念。例如,在作業系統中目錄用來將相關檔案分組,而對於目錄中的檔案來說,它就扮演了命名空間的角色。

命名空間的作用

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中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!