PHP 魔术常量
魔术常量是PHP中预定义的常量,它们的值会根据它们在代码中的位置而改变。这些常量以双下划线(__
)开头和结尾。
魔术常量不区分大小写(但建议使用大写形式),它们的值由编译器在运行时确定,不同于普通常量,它们不需要用define()定义。
以下是 PHP 中主要的八个魔术常量:
__LINE__
__LINE__
是 PHP 的一个魔术常量,它返回当前代码行在文件中的行号。
实际应用场景
✅ 基本调试:
echo "当前行号是: " . __LINE__; // 输出当前行号
✅ 错误报告:
if ($error) {
die("错误发生在文件 " . __FILE__ . " 的第 " . __LINE__ . " 行");
}
✅ 日志记录:
function logMessage($message) {
file_put_contents('log.txt', date('Y-m-d H:i:s') . " [Line " . __LINE__ . "] " . $message . "\n", FILE_APPEND);
}
✅ 与异常结合使用:
try {
// 某些可能出错的代码
} catch (Exception $e) {
throw new Exception("错误发生在第 " . __LINE__ . " 行: " . $e->getMessage());
}
__FILE__
__FILE__
是 PHP 的一个重要魔术常量,它返回当前执行脚本的完整路径和文件名。
实际应用场景
✅ 获取当前文件信息:
echo "正在执行: " . __FILE__; // 输出类似: /var/www/project/index.php
✅ 与__DIR__
配合使用:
require __DIR__ . '/config.php'; // 更安全的包含文件方式
✅ 调试和日志记录:
function logError($message) {
$log = "[" . date('Y-m-d H:i:s') . "] " . __FILE__ . ": " . $message . "\n";
file_put_contents('error.log', $log, FILE_APPEND);
}
✅ 获取当前文件名(不含路径):
$current_file = basename(__FILE__);
echo "当前文件名: " . $current_file;
✅ 在类中使用:
class MyClass {
public function showFile() {
return "类定义在: " . __FILE__;
}
}
__DIR__
__DIR__
是 PHP 5.3.0 引入的一个实用的魔术常量,它返回当前执行脚本所在的目录的绝对路径(不包括末尾的斜杠)。
实际应用场景
✅ 安全地包含文件:
require __DIR__ . '/config/database.php';
✅ 设置项目根目录:
define('PROJECT_ROOT', __DIR__);
require PROJECT_ROOT . '/vendor/autoload.php';
✅ 文件操作:
$cache_dir = __DIR__ . '/cache';
if (!file_exists($cache_dir)) {
mkdir($cache_dir, 0755, true);
}
✅ 自动加载类:
spl_autoload_register(function ($class) {
$file = __DIR__ . '/src/' . str_replace('\\', '/', $class) . '.php';
if (file_exists($file)) {
require $file;
}
});
✅ 获取相对路径:
// 从当前目录到项目根目录的相对路径
$relative_path = substr(__DIR__, strlen('/var/www/html/'));
__FUNCTION__
__FUNCTION__
是 PHP 的一个魔术常量,用于返回当前函数的名称(字符串形式)。它在函数内部使用时会返回该函数的名称,在函数外部使用则返回空字符串。
实际应用场景
✅ 安全地包含文件:
function processData($data) {
if (empty($data)) {
error_log("[" . __FUNCTION__ . "] 错误: 空数据");
return false;
}
// 处理数据...
}
✅ 回调函数识别:
$callback = function() {
echo "回调函数: " . (__FUNCTION__ ?: '匿名函数');
};
$callback(); // 输出: 回调函数: 匿名函数
✅ 与异常处理结合:
function divide($a, $b) {
if ($b == 0) {
throw new Exception(__FUNCTION__ . ": 除数不能为零");
}
return $a / $b;
}
✅ 方法链式调用调试:
class Calculator {
public function add($num) {
// ...操作...
$this->log(__FUNCTION__);
return $this;
}
private function log($action) {
file_put_contents('calc.log', "$action 被调用\n", FILE_APPEND);
}
}
__CLASS__
__CLASS__
是 PHP 中一个重要的魔术常量,它返回当前的类名(包括命名空间,如果有的话)。这个常量在类定义内部使用时会返回当前类的名称,在类外部使用则返回空字符串。
实际应用场景
✅ 日志记录:
class Logger {
public function log($message) {
$logEntry = "[" . date('Y-m-d H:i:s') . "] " . __CLASS__ . ": " . $message;
file_put_contents('app.log', $logEntry . PHP_EOL, FILE_APPEND);
}
}
✅ 工厂方法:
class Product {
public static function create() {
return new __CLASS__;
}
}
✅ 异常处理:
class DatabaseException extends Exception {
public function __construct($message) {
parent::__construct(__CLASS__ . ": " . $message);
}
}
✅ 单例模式:
class Singleton {
private static $instance;
public static function getInstance() {
if (!isset(self::$instance)) {
self::$instance = new __CLASS__;
}
return self::$instance;
}
private function __construct() {}
}
__TRAIT__
__TRAIT__
是 PHP 5.4.0 引入的一个魔术常量,用于返回当前 trait 的名称(包括命名空间)。这个常量在 trait 定义内部使用时会返回该 trait 的完全限定名称。
实际应用场景
✅ 调试和日志记录:
trait Loggable {
public function log($message) {
$logEntry = "[" . date('Y-m-d H:i:s') . "] " . __TRAIT__ . ": " . $message;
file_put_contents('trait.log', $logEntry . PHP_EOL, FILE_APPEND);
}
}
✅ Trait 自引用:
trait SingletonTrait {
private static $instance;
public static function getInstance() {
if (!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
echo "Initializing " . __TRAIT__;
}
}
✅ 冲突解决:
trait A {
public function smallTalk() {
echo __TRAIT__ . " says 'a'";
}
}
trait B {
public function smallTalk() {
echo __TRAIT__ . " says 'b'";
}
}
class Talker {
use A, B {
B::smallTalk insteadof A;
}
}
__METHOD__
__METHOD__
是 PHP 中一个非常有用的魔术常量,它返回当前方法名(包括类名)。这个常量在方法内部使用时会返回"类名::方法名"格式的字符串。
实际应用场景
✅ 调试和日志记录:
class Database {
public function query($sql) {
error_log("[" . __METHOD__ . "] 执行查询: " . $sql);
// 执行数据库查询...
}
}
✅ 异常处理:
class Calculator {
public function divide($a, $b) {
if ($b == 0) {
throw new InvalidArgumentException(__METHOD__ . ": 除数不能为零");
}
return $a / $b;
}
}
✅ 性能分析:
class Profiler {
private $timers = [];
public function startTimer() {
$this->timers[__METHOD__] = microtime(true);
}
public function endTimer() {
$time = microtime(true) - $this->timers[__METHOD__];
echo __METHOD__ . " 执行时间: " . $time . "秒";
}
}
✅ 接口实现检查:
interface LoggerInterface {
public function log($message);
}
class FileLogger implements LoggerInterface {
public function log($message) {
file_put_contents('log.txt', __METHOD__ . ": " . $message, FILE_APPEND);
}
}
__NAMESPACE__
__NAMESPACE__
是 PHP 5.3.0 引入的一个魔术常量,用于获取当前命名空间的名称(字符串形式)。当在全局空间(非命名空间代码)中使用时,它返回空字符串。
实际应用场景
✅ 动态类加载:
namespace My\App;
class Autoloader {
public static function load($className) {
if (strpos($className, __NAMESPACE__) {
$file = str_replace('\\', '/', $className) . '.php';
require $file;
}
}
}
✅ 日志记录:
namespace Company\Service;
class Logger {
public function log($message) {
$logEntry = "[" . date('Y-m-d H:i:s') . "] " . __NAMESPACE__ . ": " . $message;
file_put_contents('app.log', $logEntry . PHP_EOL, FILE_APPEND);
}
}
✅ 异常处理:
namespace My\Exceptions;
class DatabaseException extends \Exception {
public function __construct($message) {
parent::__construct(__NAMESPACE__ . " error: " . $message);
}
}
✅ 工厂模式:
namespace My\Factory;
class ObjectFactory {
public static function create($type) {
$className = __NAMESPACE__ . '\\' . $type;
if (class_exists($className)) {
return new $className();
}
throw new \Exception("Class $className not found");
}
}
反馈提交成功
感谢您的反馈,我们将尽快处理您的反馈