PHP 魔术变量 详解

PHP 提供了一系列预定义的常量,这些常量被称为魔术变量。它们的值会随着在代码中的位置变化而改变,为开发者提供了有用的上下文信息。这些特殊的常量不区分大小写。

__LINE__ - 文件中的当前行号

返回该常量所在行在文件中的行号,常用于调试和错误报告。

实例:

<?php
echo '这是第 \" '  . __LINE__ . ' \" 行';
echo "\n";
echo '这是第 \" '  . __LINE__ . ' \" 行';
?>

输出结果:

这是第 " 2 " 行
这是第 " 3 " 行

__FILE__ - 文件的完整路径和文件名

返回当前文件的绝对路径。如果用在被包含文件中,则返回被包含的文件名。

实例:

<?php
echo '该文件位于:'  . __FILE__;
?>

输出结果:

该文件位于:/var/www/html/test/index.php

__DIR__ - 文件所在的目录

返回文件所在的目录路径,相当于 dirname(__FILE__)

实例:

<?php
echo '文件目录:' . __DIR__;
?>

输出结果:

文件目录:/var/www/html/test

__FUNCTION__ - 函数名称

返回当前函数的名称,在函数内部使用。

实例:

<?php
function testFunction() {
    echo '当前函数名:' . __FUNCTION__;
}

function anotherFunction() {
    echo '在另一个函数中:' . __FUNCTION__;
}

testFunction();
echo "\n";
anotherFunction();
?>

输出结果:

当前函数名:testFunction
在另一个函数中:anotherFunction

__CLASS__ - 类的名称

返回当前类的名称,在类的方法内部使用。

实例:

<?php
class MyClass {
    public function showClass() {
        echo '当前类名:' . __CLASS__;
    }

    public function showMethod() {
        echo '当前方法:' . __METHOD__;
    }
}

class AnotherClass {
    public function display() {
        echo '类名:' . __CLASS__;
    }
}

$obj = new MyClass();
$obj->showClass();
echo "\n";
$obj->showMethod();
echo "\n";

$obj2 = new AnotherClass();
$obj2->display();
?>

输出结果:

当前类名:MyClass
当前方法:MyClass::showMethod
类名:AnotherClass

__TRAIT__ - Trait 的名称

返回当前 trait 的名称,在 trait 的方法内部使用。

实例:

<?php
trait LogTrait {
    public function log($message) {
        echo '[' . __TRAIT__ . '] ' . $message . "\n";
    }
}

trait ValidationTrait {
    public function validate($data) {
        echo '[' . __TRAIT__ . '] 验证数据:' . $data . "\n";
    }
}

class User {
    use LogTrait, ValidationTrait;

    public function create($userData) {
        $this->log('开始创建用户');
        $this->validate($userData);
        echo "用户创建成功\n";
    }
}

$user = new User();
$user->create('John Doe');
?>

输出结果:

[LogTrait] 开始创建用户
[ValidationTrait] 验证数据:John Doe
用户创建成功

__METHOD__ - 类的方法名

返回当前方法的名称,包括类名和方法名。

实例:

<?php
class Calculator {
    public function add($a, $b) {
        echo '正在执行方法:' . __METHOD__ . "\n";
        return $a + $b;
    }

    public function multiply($a, $b) {
        echo '方法:' . __METHOD__ . "\n";
        return $a * $b;
    }
}

$calc = new Calculator();
echo "结果:" . $calc->add(5, 3) . "\n";
echo "结果:" . $calc->multiply(4, 6) . "\n";
?>

输出结果:

正在执行方法:Calculator::add
结果:8
方法:Calculator::multiply
结果:24

__NAMESPACE__ - 当前命名空间

返回当前命名空间的名称。

实例:

<?php
namespace MyProject\Utils;

class StringHelper {
    public static function showNamespace() {
        echo '当前命名空间:' . __NAMESPACE__ . "\n";
    }
}

echo '根命名空间:"' . __NAMESPACE__ . '"' . "\n";
StringHelper::showNamespace();

namespace AnotherProject;

echo '新命名空间:' . __NAMESPACE__ . "\n";
?>

输出结果:

根命名空间:"MyProject\Utils"
当前命名空间:MyProject\Utils
新命名空间:AnotherProject

魔术变量总结

魔术变量 描述 PHP版本
__LINE__ 文件中的当前行号 PHP 4+
__FILE__ 文件的完整路径和文件名 PHP 4+
__DIR__ 文件所在的目录 PHP 5.3+
__FUNCTION__ 函数名称 PHP 4.3+
__CLASS__ 类的名称 PHP 4.3+
__TRAIT__ Trait 的名称 PHP 5.4+
__METHOD__ 类的方法名 PHP 5.0+
__NAMESPACE__ 当前命名空间的名称 PHP 5.3+

实际应用场景

魔术变量在以下场景中特别有用:

  • 调试和日志记录:在日志中记录文件名和行号
  • 错误处理:在异常信息中包含详细的上下文信息
  • 自动加载:根据命名空间自动加载类文件
  • 代码分析:动态获取代码结构信息

综合实例:

<?php
namespace App\Services;

class Logger {
    public static function log($message, $level = 'INFO') {
        $timestamp = date('Y-m-d H:i:s');
        $logEntry = sprintf(
            "[%s] %s: %s (%s:%d)\n",
            $timestamp,
            $level,
            $message,
            __FILE__,
            __LINE__
        );

        file_put_contents('app.log', $logEntry, FILE_APPEND);
    }
}

class UserService {
    use ValidationTrait;

    public function createUser($data) {
        Logger::log('开始创建用户 - ' . __METHOD__);

        $this->validate($data);

        Logger::log('用户创建成功');
        return true;
    }
}

// 使用示例
$userService = new UserService();
$userService->createUser(['name' => 'John', 'email' => 'john@example.com']);
?>