主题
  • 默认模式
  • 浅蓝色模式
  • 淡绿色模式
  • 深夜模式

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");
    }
}


评论区 0
发表评论