魔术方法 #

一、属性重载 #

1.1 __get和__set #

php
<?php
class DynamicProperties
{
    private array $data = [];
    
    public function __get(string $name): mixed
    {
        return $this->data[$name] ?? null;
    }
    
    public function __set(string $name, mixed $value): void
    {
        $this->data[$name] = $value;
    }
    
    public function __isset(string $name): bool
    {
        return isset($this->data[$name]);
    }
    
    public function __unset(string $name): void
    {
        unset($this->data[$name]);
    }
}

$obj = new DynamicProperties();
$obj->name = "John";
echo $obj->name;

二、方法重载 #

2.1 __call和__callStatic #

php
<?php
class DynamicMethods
{
    public function __call(string $name, array $arguments): mixed
    {
        echo "Calling $name with: " . implode(', ', $arguments);
        return null;
    }
    
    public static function __callStatic(string $name, array $arguments): mixed
    {
        echo "Static calling $name";
        return null;
    }
}

$obj = new DynamicMethods();
$obj->doSomething('a', 'b');
DynamicMethods::staticMethod();

三、对象转换 #

3.1 __toString #

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

$user = new User("John");
echo "Hello, $user";

3.2 __invoke #

php
<?php
class Multiplier
{
    public function __invoke(int $a, int $b): int
    {
        return $a * $b;
    }
}

$multiply = new Multiplier();
echo $multiply(3, 4);

四、对象克隆 #

4.1 __clone #

php
<?php
class User
{
    public function __construct(
        public string $name,
        public DateTime $createdAt
    ) {}
    
    public function __clone(): void
    {
        $this->createdAt = clone $this->createdAt;
    }
}

$user1 = new User("John", new DateTime());
$user2 = clone $user1;

五、序列化 #

5.1 __sleep和__wakeup #

php
<?php
class User
{
    public function __construct(
        public string $name,
        private string $password
    ) {}
    
    public function __sleep(): array
    {
        return ['name'];
    }
    
    public function __wakeup(): void
    {
        $this->password = '';
    }
}

六、总结 #

本章学习了:

  • __get、__set属性重载
  • __call、__callStatic方法重载
  • __toString对象转换
  • __invoke可调用对象
  • __clone对象克隆
  • __sleep、__wakeup序列化

下一章将学习命名空间。

最后更新:2026-03-26