PHP 提供 9 個魔術常量,在編譯時根據上下文解析為特定值,無運行開銷。本文通過測試代碼展示各常量輸出,並說明實際開發中的典型應用場景(日誌、調試、路徑構建、異常上下文)。
<?php
namespace App\Demo;
class MagicConstDemo {
public function test() {
echo "=== 類內部 ===" . PHP_EOL;
echo '__CLASS__ : ' . __CLASS__ . PHP_EOL; // App\Demo\MagicConstDemo
echo '__METHOD__ : ' . __METHOD__ . PHP_EOL; // App\Demo\MagicConstDemo::test
echo '__FUNCTION__ : ' . __FUNCTION__ . PHP_EOL; // test
echo '__LINE__ : ' . __LINE__ . PHP_EOL; // 當前行號
echo '__FILE__ : ' . __FILE__ . PHP_EOL; // 完絕對路徑
echo '__DIR__ : ' . __DIR__ . PHP_EOL; // 所在目錄
echo '__NAMESPACE__: ' . __NAMESPACE__ . PHP_EOL; // App\Demo
echo '__TRAIT__ : ' . __TRAIT__ . PHP_EOL; // 若在 Trait 中
}
}
echo "=== 全域/函數內部 ===" . PHP_EOL;
echo '__LINE__ : ' . __LINE__ . PHP_EOL;
echo '__FILE__ : ' . __FILE__ . PHP_EOL;
echo '__DIR__ : ' . __DIR__ . PHP_EOL;
echo '__FUNCTION__ : ' . __FUNCTION__ . PHP_EOL; // 空字串(非函數內)
echo '__NAMESPACE__: ' . __NAMESPACE__ . PHP_EOL; // 空字串(全域)
$demo = new MagicConstDemo();
$demo->test();
// PHP 8.0+ 新增
echo 'PHP_VERSION_ID: ' . PHP_VERSION_ID . PHP_EOL; // 80100
?>
=== 全域/函數內部 === __LINE__ : 25 __FILE__ : /var/www/app/Demo/MagicConstDemo.php __DIR__ : /var/www/app/Demo __FUNCTION__ : __NAMESPACE__: === 類內部 === __CLASS__ : App\Demo\MagicConstDemo __METHOD__ : App\Demo\MagicConstDemo::test __FUNCTION__ : test __LINE__ : 10 __FILE__ : /var/www/app/Demo/MagicConstDemo.php __DIR__ : /var/www/app/Demo __NAMESPACE__: App\Demo __TRAIT__ :
| 常量 | 返回值 | 典型用途 |
|---|---|---|
| __LINE__ | 當前行號 (int) | 日誌、異常上下文、調試輸出 |
| __FILE__ | 完整絕對路徑 (string),已解析符號鏈接 | require 相對路徑、配置文件定位 |
| __DIR__ | 所在目錄絕對路徑 (string),等同 dirname(__FILE__) | 項目根目錄 BASE_PATH = __DIR__ . '/../' |
| __FUNCTION__ | 函數名 (string),區分大小寫;閉包為 {closure} | 動態調用、埋點監控 |
| __CLASS__ | 類名含命名空間 (string),self::class 同義 | 工廠模式、註解掃描、實體類名 |
| __TRAIT__ | Trait 名含命名空間 (string) | Trait 內部邏輯區分來源 |
| __METHOD__ | 類名::方法名 (string) | 精確日誌、緩存鍵前綴、路由映射 |
| __NAMESPACE__ | 當前命名空間 (string) | 動態導入、模組自動發現 |
| ClassName::class | 類全限定名 (string),編譯時解析,非魔術常量但極常用 | 替代字串硬編碼,IDE 重構安全 |
function log_info(string $msg, array $ctx = []): void {
$ctx += [
'file' => __FILE__,
'line' => __LINE__,
'func' => __FUNCTION__,
'time' => microtime(true),
];
error_log(json_encode($ctx, JSON_UNESCAPED_UNICODE) . ' ' . $msg);
}
// 調用
log_info("用戶登錄成功"); // 自動攜帶調用位置
// config/bootstrap.php
define('APP_ROOT', __DIR__ . '/../');
require APP_ROOT . 'vendor/autoload.php';
$config = require APP_ROOT . 'config/app.php';
class AppException extends Exception {
public function __construct(string $msg = '', int $code = 0, Throwable $prev = null) {
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1] ?? [];
$ctx = " at {$trace['file']}:{$trace['line']} in {$trace['function']}";
parent::__construct($msg . $ctx, $code, $prev);
}
}
// ❌ 易拼寫錯、重構失效
$factory->create('App\\Service\\UserService');
// ✅ 編譯期檢查、IDE 智能提示
$factory->create(UserService::class);