本文目录导读:

我来详细讲解一下 PHP 中的魔术方法(Magic Methods),这些方法以双下划线 开头,在特定时机被自动调用。
🔮 核心魔术方法
__construct() - 构造函数
class User {
public function __construct($name) {
$this->name = $name;
echo "对象创建成功";
}
}
$user = new User("小明"); // 输出: 对象创建成功
__destruct() - 析构函数
class File {
public function __destruct() {
echo "对象销毁,连接已关闭";
}
}
$file = new File();
unset($file); // 触发析构
__get() - 访问私有属性
class Person {
private $data = ['age' => 25];
public function __get($name) {
echo "试图访问不存在的属性: $name";
return isset($this->data[$name]) ? $this->data[$name] : null;
}
}
$person = new Person();
echo $person->age; // 输出: 试图访问不存在的属性: age 25
__set() - 设置私有属性
class Config {
private $settings = [];
public function __set($name, $value) {
echo "设置动态属性: $name = $value";
$this->settings[$name] = $value;
}
}
$config = new Config();
$config->debug = true; // 输出: 设置动态属性: debug = 1
__call() - 调用不存在的方法
class Calculator {
public function __call($method, $arguments) {
if ($method === 'add') {
return array_sum($arguments);
}
throw new Exception("方法 $method 不存在");
}
}
$calc = new Calculator();
echo $calc->add(1, 2, 3); // 输出: 6
__callStatic() - 调用不存在的静态方法
class MathHelper {
public static function __callStatic($method, $arguments) {
echo "调用静态方法: $method";
return count($arguments);
}
}
echo MathHelper::sum(1, 2, 3); // 输出: 调用静态方法: sum 3
__toString() - 对象转字符串
class Product {
public function __construct($name, $price) {
$this->name = $name;
$this->price = $price;
}
public function __toString() {
return "$this->name: ¥$this->price";
}
}
$product = new Product("手机", 3999);
echo $product; // 输出: 手机: ¥3999
🎯 高级魔术方法
__isset() 和 __unset()
class Data {
private $items = ['name' => '张三', 'email' => 'test@example.com'];
public function __isset($name) {
echo "检查 isset($name)";
return isset($this->items[$name]);
}
public function __unset($name) {
echo "删除 $name";
unset($this->items[$name]);
}
}
$data = new Data();
isset($data->name); // 触发 __isset
unset($data->email); // 触发 __unset
__sleep() 和 __wakeup() - 序列化控制
class Connection {
private $db;
private $data = '重要数据';
public function __sleep() {
echo "序列化前保存数据";
return ['data']; // 只序列化 data 属性
}
public function __wakeup() {
echo "反序列化后重新连接数据库";
$this->db = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
}
}
$conn = new Connection();
$serialized = serialize($conn); // 触发 __sleep
$restored = unserialize($serialized); // 触发 __wakeup
__clone() - 克隆对象时
class Database {
public $connection;
public function __construct() {
$this->connection = "数据库连接";
}
public function __clone() {
echo "克隆后重置连接";
$this->connection = "新数据库连接";
}
}
$db1 = new Database();
$db2 = clone $db1; // 触发 __clone
🚀 实用示例:API 请求类
class ApiClient {
private $config = [];
private $headers = [];
public function __construct(array $config = []) {
$this->config = $config;
echo "API 客户端初始化完成\n";
}
// 动态方法调用
public function __call($method, $args) {
if (strpos($method, 'get') === 0) {
$endpoint = strtolower(substr($method, 3));
return $this->request('GET', $endpoint, $args[0] ?? []);
}
throw new BadMethodCallException("方法 $method 不存在");
}
// 动态属性设置
public function __set($key, $value) {
if ($key === 'token' || $key === 'timeout') {
$this->config[$key] = $value;
return;
}
throw new InvalidArgumentException("无效配置项: $key");
}
// 动态属性获取
public function __get($key) {
return $this->config[$key] ?? null;
}
private function request($method, $endpoint, $params = []) {
echo "请求: $method /$endpoint\n";
echo "参数: " . json_encode($params) . "\n";
return "模拟响应";
}
public function __toString() {
return "API 配置: " . json_encode($this->config);
}
public function __debugInfo() {
return ['config' => $this->config, 'headers' => $this->headers];
}
}
// 使用示例
$api = new ApiClient(['base_url' => 'https://api.example.com']);
$api->timeout = 30;
echo $api->timeout . "\n"; // 30
$result = $api->getUsers(['page' => 1]);
echo $api; // 输出配置
📋 注意事项
- 不要混用:魔术方法不能和同名普通方法共存
- 触发条件:只有在对象上下文中才会触发
- 性能考虑:过度使用会影响性能,建议适当使用
- 版本兼容:
__serialize()和__unserialize()是 PHP 7.4+ 新增的
魔术方法提供了强大的钩子机制,可以实现:
- 属性的动态访问控制
- 方法的动态扩展
- 对象序列化控制
- 错误处理和兼容性
合理使用可以极大提升代码的灵活性和可维护性,但要注意不要过度使用,保持代码清晰。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播