2024 年日本 PHP 研討會

使用命名空間:函式和常數回退到全域空間

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

在命名空間內,當 PHP 在類別名稱、函式或常數上下文中遇到未限定的名稱時,它會以不同的優先順序解析這些名稱。類別名稱一律解析為目前的命名空間名稱。因此,要存取內部或非命名空間的使用者類別,必須使用它們的完整限定名稱來引用它們,如下所示

範例 #1 在命名空間內存取全域類別

<?php
namespace A\B\C;
class
Exception extends \Exception {}

$a = new Exception('hi'); // $a 是 A\B\C\Exception 類別的物件
$b = new \Exception('hi'); // $b 是 Exception 類別的物件

$c = new ArrayObject; // 致命錯誤,找不到 A\B\C\ArrayObject 類別
?>

對於函式和常數,如果命名空間中的函式或常數不存在,PHP 會退回到全域函式或常數。

範例 #2:命名空間內全域函式/常數的退回機制

<?php
namespace A\B\C;

const
E_ERROR = 45;
function
strlen($str)
{
return
\strlen($str) - 1;
}

echo
E_ERROR, "\n"; // 輸出 "45"
echo INI_ALL, "\n"; // 輸出 "7" - 退回到全域 INI_ALL

echo strlen('hi'), "\n"; // 輸出 "1"
if (is_array('hi')) { // 輸出 "不是陣列"
echo "是陣列\n";
} else {
echo
"不是陣列\n";
}
?>

新增註釋

使用者貢獻的註釋 1 則註釋

36
markus at malkusch dot de
10 年前
您可以使用退回策略來為內建函式(例如 time())提供模擬物件 (mock)。因此,您必須以非限定名稱的方式呼叫這些函式。

<?php
namespace foo;

function
time() {
return
1234;
}

assert (1234 == time());
?>

然而,有一個限制是您必須在測試類別方法中第一次使用模擬函式之前定義它。這在錯誤 #68541 中有記錄。

您可以在 GitHub 上找到 php-mock 模擬函式庫。
To Top