常用魔术方法详解
__construct(),类的构造函数
php中构造方法是对象创建完成后第一个被对象自动调用的方法。在每个类中都有一个构造方法,如果没有显示地声明它,那么类中都会默认存在一个没有参数且内容为空的构造方法

<?php
class Player {
public $name;
public $hp;
// 当你 new Player(...) 的时候,这里会自动运行
public function __construct($name, $hp = 100) {
$this->name = $name;
$this->hp = $hp;
echo "角色【{$this->name}】已创建,初始血量:{$this->hp}<br>";
}
}
// 创建对象的同时传参
$p1 = new Player("大猛男");
$p2 = new Player("小脆皮", 50);
构造方法的作用
通常构造方法被用来执行一些有用的初始化任务,如对成员属性在创建对象时赋予初始值
在类中声明构造方法需要注意的事项
1、在同一个类中只能声明一个构造方法,原因是,PHP不支持构造函数重载。
2、构造方法名称是以两个下画线开始的__construct()
__destruct(),类的析构函数
析构方法允许在销毁一个类之前执行的一些操作或完成一些功能,比如说关闭文件、释放结果集等
析构方法是PHP5才引进的新内容
析造方法的声明格式与构造方法 __construct() 比较类似,也是以两个下划线开始的方法 __destruct() ,这种析构方法名称也是固定的。
function __destruct()
{
//方法体
}

<?php
class Demo {
public function __construct() {
echo "1. 对象诞生了(构造函数)<br>";
}
public function sayHello() {
echo "2. 正在工作中...<br>";
}
public function __destruct() {
echo "3. 对象被销毁了(析构函数)<br>";
}
}
$test = new Demo();
$test->sayHello();
// 当代码运行到这里结束时,__destruct 会自动触发
析构函数不能带有任何参数
一般来说,析构方法在PHP中并不是很常用
它属类中可选择的一部分,通常用来完成一些在对象销毁前的清理任务
__call(),在对象中调用一个不可访问方法时调用
该方法有两个参数,第一个参数 function_name 会自动接收不存在的方法名,第二个 arguments 则以数组的方式接收不存在方法的多个参数
__call() 方法的格式:
function __call(string $function_name, array $arguments)
{
// 方法体
}

class Robot {
public function __call($name, $args) {
echo "你尝试调用了方法:{$name} <br>";
echo "你传入的参数是:" . implode(', ', $args) . "<br>";
}
}
$myRobot = new Robot();
// 类里没有 hello() 方法,会触发 __call
$myRobot->hello("小明", "今天天气不错");
__call() 方法的作用
为了避免当调用的方法不存在时产生错误,而意外的导致程序中止,可以使用 __call() 方法来避免。
该方法在调用的方法不存在时会自动调用,程序仍会继续执行下去。
__callStatic(),用静态方式中调用一个不可访问方法时调用
此方法与上面所说的 __call() 功能除了 __callStatic() 是未静态方法准备的之外,其它都是一样的。
__get(),获得一个类的成员变量时调用
在 php 面向对象编程中,类的成员属性被设定为 private 后,如果我们试图在外面调用它则会出现"不能访问某个私有属性"的错误。那么为了解决这个问题,我们可以使用魔术方法 __get()。
魔术方法__get()的作用
在程序运行过程中,通过它可以在对象的外部获取私有成员属性的值。
public function __get(string $name)
{
// 方法体
}
$name: 你想要访问的那个属性的名字
基础拦截
<?php
class Simple {
public function __get($name) {
return "抱歉,属性【{$name}】不存在或不可访问。";
}
}
$obj = new Simple();
echo $obj->age; // 类里没有 age 属性,触发 __get
只读访问
<?php
class User {
private string $name = "张三";
private int $score = 99;
public function __get($name) {
// 如果访问的是 score,我们加个后缀
if ($name === 'score') {
return $this->score . " 分";
}
// 返回原始属性值
return $this->$name;
}
}
$user = new User();
echo $user->name; // 输出:张三
echo $user->score; // 输出:99 分
动态数据映射
有时候数据存储在一个数组里,但你想用"点语法"像访问属性一样去用它
<?php
class Config {
private array $settings = [
'db_host' => 'localhost',
'db_user' => 'root'
];
public function __get($key) {
return $this->settings[$key] ?? "配置项不存在";
}
}
$conf = new Config();
echo $conf->db_host; // 触发 __get,返回 'localhost'