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'
相关推荐
学运维的Kysan3 分钟前
暑假运维学习打卡第二十五天8.16
学习
进制树19 分钟前
【飞控开发实战·⑲】ROS2无人机开发环境搭建:Jazzy安装、工作空间与hello_drone节点实战
开发语言·安全·无人机·课程设计
键盘飞行员35 分钟前
Flutter App 全套实战学习计划:从零搭建到 APK 部署
学习·flutter
牛马也想出海42 分钟前
亚马逊爬虫代理IP:IP类型选择与配置指南
开发语言·php
菜冻鱼1 小时前
Python-pytorch-高级技巧
开发语言·人工智能·pytorch·python·深度学习·神经网络·聚类
lpfasd1231 小时前
python webview打包版卡死、开发版正常
开发语言·python
weixin_461408581 小时前
npm npx yarn
开发语言·前端·javascript
菜冻鱼1 小时前
Python-pytorch-模型保存与加载
开发语言·人工智能·pytorch·python·深度学习·机器学习
骇客野人1 小时前
Java SSO 统一认证方案
java·开发语言
萝卜er2 小时前
BroadcastReceiver 静态注册与动态注册-《Android深水区(七)》
android