php反序列化(复习)(第二章)

常用魔术方法详解

__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'
相关推荐
疯狂打码的少年4 小时前
编译程序与解释程序的区别
java·开发语言·笔记
caimouse7 小时前
reactos编码规范
c语言·开发语言
xieliyu.11 小时前
Java算法精讲:双指针(三)
java·开发语言·算法
数智工坊12 小时前
机器人运动控制:采样、优化与学习三大流派深度对比与实战
android·学习·机器人
CryptoPP12 小时前
快速对接东京证券交易所API数据:实战指南与代码示例
开发语言·人工智能·windows·python·信息可视化·区块链
ZC跨境爬虫12 小时前
跟着 MDN 学JavaScript day_7:数学运算与逻辑判断实战测试
开发语言·前端·javascript·学习·ecmascript
阳区欠13 小时前
【LangChain】LLM基础介绍
开发语言·python·langchain
Jinkxs13 小时前
Java 跨域14-Java 与区块链(Hyperledger)集成
java·开发语言·区块链
故渊at13 小时前
第二板块:Android 四大组件标准化学理 | 第八篇:Service 后台执行实体与优先级
android·gitee·service·前台服务·后台服务
会Tk矩阵群控的小木13 小时前
安卓群控系统对于游戏工作室实战教程
android·运维·游戏·adb·开源软件·个人开发