Menu
CoddyTech

__toString 和 __debugInfo

本课属于 Coddy PHP 学习旅程的“面向对象编程”单元。第 45 课,共 91 课。

__toString() 方法可以让你定义对象以字符串形式表示的方式。当你在字符串上下文中使用对象时,例如使用 echo 或进行字符串拼接时,会自动调用这个方法。

<?php
class User {
    public function __construct(
        private string $name,
        private string $email
    ) {}
    
    public function __toString(): string {
        return $this->name . " (" . $this->email . ")";
    }
}

$user = new User("Alice", "alice@example.com");
echo $user;

输出:

Alice (alice@example.com)

__debugInfo() 方法控制你对对象使用 var_dump() 时显示哪些信息。这在调试时隐藏敏感数据或显示计算出的值很有用:

<?php
class BankAccount {
    public function __construct(
        private string $accountNumber,
        private float $balance,
        private string $pin
    ) {}
    
    public function __debugInfo(): array {
        return [
            'accountNumber' => '****' . substr($this->accountNumber, -4),
            'balance' => $this->balance,
            'pin' => '[HIDDEN]'
        ];
    }
}

$account = new BankAccount("1234567890", 1500.00, "9876");
var_dump($account);

输出:

object(BankAccount)#1 (3) {
  ["accountNumber"]=>
  string(8) "****7890"
  ["balance"]=>
  float(1500)
  ["pin"]=>
  string(8) "[HIDDEN]"
}

注意,__debugInfo() 会返回键值对数组,用来替代默认的属性转储。敏感的 PIN 已隐藏,账号也经过部分遮蔽,非常适合安全调试。

challenge icon

挑战

简单

我们来构建一个凭据管理系统,演示 __toString() 和 __debugInfo() 这两个魔术方法。你将创建一个类,在打印时显示易于用户理解的信息,同时在调试时保护敏感数据。

你将把代码分放在两个文件中:

  • Credential.php:创建一个 Credential 类,安全地存储登录信息。使用构造函数属性提升来定义私有属性:$username(字符串)、$password(字符串)和 $lastLogin(字符串)。实现两个魔术方法:
    • __toString():返回一段便于用户理解的字符串:"User: [username] (Last login: [lastLogin])"。注意,密码绝不会出现在字符串表示中。
    • __debugInfo():返回一个供 var_dump() 使用的数组,其中用户名按原样显示,密码则只显示 "[PROTECTED]" 以隐藏其内容,最后登录日期正常显示。
  • main.php:引入 Credential 文件。你将收到 3 个输入:用户名、密码和最后登录日期。使用这些值创建一个 Credential 实例。首先,直接输出凭据对象(这会触发 __toString())。然后换行,对该对象使用 var_dump(),查看受保护的调试输出。

__toString() 方法提供了一种简洁、安全的方式来显示凭据,而不会泄露密码。__debugInfo() 方法则确保即使在调试时,敏感信息也会保持隐藏:这是处理身份验证数据时至关重要的实践。

亲手试试

<?php

require_once 'Credential.php';

// 读取输入
$username = trim(fgets(STDIN));
$password = trim(fgets(STDIN));
$lastLogin = trim(fgets(STDIN));

// TODO:用输入值创建一个 Credential 实例

// TODO:输出 Credential 对象(会触发 __toString())

// TODO:对对象使用 var_dump(),查看受保护的调试输出

?>
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: PHP 在线编译器