从0开始学PHP面向对象内容之(常用魔术方法续一)

在这里插入图片描述

常用魔术方法(续)

上期我们讲到几个常用的魔术方法,但是由于篇幅过程且全是文字性质地东西,就没写完,篇幅太长也会丧失阅读兴趣,我尽量控制一篇文章在5000字左右

一、__isset()&&__unset()

1、在开发中,类通常有一些不想暴露或让外部检查的私有或受保护的属性,比如密码、敏感配置等。通过 __isset(),可以控制这些属性是否能够被 isset() 或 empty() 检查到。

2、__isset() 的主要用途:是控制对象中是否可以检测到某个属性,通常用于保护敏感数据和实现延迟加载。
__unset() 的主要用途:是定义对象在使用 unset() 时的行为,通常用于控制哪些属性可以被删除或在删除时执行附加逻辑。

1、数据隐藏与控制访问

1、__isset() 和 __unset() 常用于对象中属性的访问控制,尤其是当类有一些私有属性时,这些方法可以决定哪些属性可以被检查或销毁。

2、__isset() 可以用:来控制 isset() 和 empty() 是否能正确判断属性的存在性。
__unset() 可以用:来决定是否允许 unset() 删除某个属性。

示例
class User {private $data = ['username' => 'john_doe','email' => 'john.doe@example.com','password' => 'hashed_password' // 敏感信息];public function __isset($name) {// 阻止 `password` 属性被 `isset()` 检查if ($name === 'password') {return false;}return isset($this->data[$name]);}
}$user = new User();
var_dump(isset($user->username)); // 输出 true
var_dump(isset($user->password)); // 输出 false,即使 `password` 实际上存在
应用场景

1、保护敏感数据,防止它们在调试或其他场景中暴露。
2、控制哪些属性能够被检查是否存在,提升代码安全性。

2、动态属性管理

在很多应用程序中,类的属性是动态存储的,例如配置类、缓存类、或从数据库获取的数据对象。使用 __isset() 和 __unset(),可以灵活地管理这些动态属性。

示例
class Config {private $settings = [];public function __set($name, $value) {$this->settings[$name] = $value;}public function __get($name) {return $this->settings[$name] ?? null;}public function __isset($name) {// 检查动态属性是否已设置return array_key_exists($name, $this->settings);}public function __unset($name) {// 删除动态属性unset($this->settings[$name]);}
}$config = new Config();
$config->app_name = 'MyApp';// 检查属性是否存在
var_dump(isset($config->app_name)); // 输出 true// 删除属性
unset($config->app_name);
var_dump(isset($config->app_name)); // 输出 false
应用场景

1、用于配置类或设置类,动态管理属性,确保灵活性和可扩展性。
2、控制对象中存储的临时或动态数据的访问和修改。

3、延迟加载与内存优化

在大型系统中,延迟加载(Lazy Loading)是一种重要的设计模式,它允许在需要时才加载对象的某些部分。通过 __isset() 可以实现对属性是否存在的延迟检测,这样只有在实际访问时才执行昂贵的计算或数据加载。

示例
class DataLoader {private $data;public function __get($name) {// 延迟加载数据if ($name === 'largeData' && $this->data === null) {$this->data = $this->loadData();}return $this->data;}public function __isset($name) {// 检查是否需要加载数据if ($name === 'largeData') {return $this->data !== null;}return false;}private function loadData() {// 模拟数据加载return "Loaded Data";}
}$loader = new DataLoader();// 检查属性,延迟加载还未触发
var_dump(isset($loader->largeData)); // 输出 false// 访问属性,触发延迟加载
echo $loader->largeData; // 输出 "Loaded Data"// 再次检查属性
var_dump(isset($loader->largeData)); // 输出 true
应用场景

1、在访问大数据对象时确保仅在必要时加载,避免不必要的内存占用。
2、结合 __get(),实现对象中某些复杂数据的惰性初始化。

4、复杂对象结构的可控销毁

通过 __unset(),可以确保某些重要数据不会被外部轻易删除,或在删除时执行一些清理操作。

示例
class Cache {private $cache = ['item1' => 'data1','item2' => 'data2',];public function __unset($name) {// 防止 `item1` 被删除if ($name === 'item1') {echo "item1 不允许被删除。\n";return;}unset($this->cache[$name]);}
}$cache = new Cache();
unset($cache->item2); // 正常删除
unset($cache->item1); // 输出 "item1 不允许被删除。"
应用场景

1、防止关键属性被无意中删除。
2、在删除对象属性时需要执行额外的清理或日志记录操作

二、__clone()

1、__clone() 是 PHP 中的一个魔术方法,用于控制对象被克隆时的行为。
2、__clone() 方法允许你自定义克隆对象的行为,以实现更复杂的对象复制逻辑。
3、__clone() 方法在使用 clone 关键字克隆对象时自动调用。它可以用于调整新克隆对象的状态,比如复制引用类型的属性、重置一些属性值、或处理特定逻辑。

1、实现深拷贝

当一个对象的属性中包含其他对象时,PHP 默认的 clone 关键字会创建一个浅拷贝,这意味着属性中引用的对象不会被克隆,仍会指向原对象。通过 __clone() 方法,可以确保深拷贝,从而避免原始对象和克隆对象共享引用。

示例
class Node {public $data;public $child;public function __clone() {if ($this->child !== null) {$this->child = clone $this->child; // 确保子对象也被克隆}}
}$node1 = new Node();
$node1->data = "Parent";
$node1->child = new Node();
$node1->child->data = "Child";$node2 = clone $node1; // 深拷贝,`child` 属性被单独克隆
$node2->child->data = "Modified Child";echo $node1->child->data; // 输出 "Child"
echo $node2->child->data; // 输出 "Modified Child"
应用场景

1、处理复杂数据结构,如树形结构或图结构。
2、需要在克隆后修改子对象,以避免意外共享引用。

2、防止共享状态

当一个对象的某些属性指向外部资源或缓存时,克隆时共享这些引用可能导致冲突或意外行为。通过 __clone(),可以确保克隆对象有独立的副本。

示例:
class Cache {public $data;public function __construct($data) {$this->data = $data;}public function __clone() {$this->data = clone $this->data; // 确保 `data` 独立拷贝}
}
应用场景:

在克隆时创建独立的数据缓存副本。
避免克隆对象与原对象共享同一连接、文件句柄或其他资源。

3、对象重置和初始化

在一些情况下,克隆后的对象需要进行特定的重置或重新初始化。通过 >__clone(),可以修改属性、生成新的唯一 ID 或重置状态。

示例:
class Session {public $id;public $createdAt;public function __construct() {$this->id = uniqid();$this->createdAt = time();}public function __clone() {// 在克隆时重新生成唯一 ID 和时间戳$this->id = uniqid();$this->createdAt = time();}
}$session1 = new Session();
$session2 = clone $session1; // 克隆并生成新的 ID 和时间戳echo "Original Session ID: " . $session1->id . "\n";
echo "Cloned Session ID: " . $session2->id . "\n";
应用场景

克隆对象时生成新 ID,确保唯一性。
在克隆后重置时间戳、状态标志等。

4、预防克隆操作

在某些情况下,你可能希望防止对象被克隆。通过在 __clone() 中抛出异常,可以实现这一点。

示例
class Singleton {private static $instance;private function __construct() {// 私有构造函数,防止外部实例化}public static function getInstance() {if (self::$instance === null) {self::$instance = new self();}return self::$instance;}public function __clone() {throw new \Exception("Cloning of this object is not allowed.");}
}$instance = Singleton::getInstance();try {$clone = clone $instance;
} catch (\Exception $e) {echo $e->getMessage(); // 输出 "Cloning of this object is not allowed."
}
应用场景:

单例模式,确保对象实例是唯一的。
防止意外克隆,保护对象状态。

5、复制复杂对象中的引用属性

在包含其他对象的复杂对象中,使用 __clone() 可以确保这些引用类型的属性被正确地复制,以防止在修改克隆对象时影响原始对象。

示例:
class Car {public $engine;public function __construct($engine) {$this->engine = $engine;}public function __clone() {$this->engine = clone $this->engine; // 确保引擎属性被克隆}
}class Engine {public $type;public function __construct($type) {$this->type = $type;}
}$engine1 = new Engine("V8");
$car1 = new Car($engine1);$car2 = clone $car1;
$car2->engine->type = "V6";echo $car1->engine->type; // 输出 "V8"
echo $car2->engine->type; // 输出 "V6"
应用场景:

克隆包含依赖关系的对象。
在克隆时将部分属性复制为新的实例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/469874.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】数据库知识突破:数据类型全解析与详解

前言:本节内容讲述MySQL的数据类型, 我们在学习之前的建表的时候已经用过各种各样的数据类型。 比如int、varchar、char类型等等。其中它们是对表的结构的操作, 并没有对数据的内容进行操作,所以它叫做DDL。另外,还有…

windows 11编译安装ffmpeg(包含ffplay)

一、源码及安装包下载 1.1,ffmpeg源码包下载 下载地址:Download FFmpeg 1.2,mysys下载 下载地址:MSYS2 1.3,libx264源码包下载 下载地址:x264, the best H.264/AVC encoder - VideoLAN 二、软件安装 2.1&…

从0开始深度学习(28)——序列模型

序列模型是指一类特别设计来处理序列数据的神经网络模型。序列数据指的是数据中的每个元素都有先后顺序,比如时间序列数据(股票价格、天气变化等)、自然语言文本(句子中的单词顺序)、语音信号等。 1 统计工具 前面介绍…

【考研数学:高数2】数列极限

目录 前言 一、数列极限的概念 1.常见前n项和 2.等差、等比数列 3.数列的性质 (1)单调性 (2)有界性 二、数列极限的定义 三、收敛数列的性质 1.概念 2.例题 四、极限的四则运算 五、海涅定理(归结原则&…

计算机网络分析题

网络的布置 根据具体需求布置网络 第二小题、网络的划分 根据路由表作出路由器拓扑图 ARP跨网络寻址 TCP报文段格式概念 网桥的转发表与动作 网络嗅探报文 十六进制化作十进制 嗅探以太网帧首部 除MAC帧以外,其他各层协议数据单元都是源地址在前,目…

PHP爬虫快速获取京东商品详情(代码示例)

在当今互联网时代,数据的重要性不言而喻。对于电商领域来说,获取商品信息是数据分析、市场研究和价格监控的基础。本文将介绍如何使用PHP编写一个简单的爬虫,以快速获取京东商品的详情信息。 1. 概述 京东是中国领先的电商平台之一&#xff…

快速学习Serde包实现rust对象序列化

在处理HTTP请求时,我们总是需要在数据结构对象(可以是enum、struct等)和序列化数据格式(例如JSON,用与存储或传输,并可以反序列化的格式)之间来回转换。 Serde是一个库(crate&#x…

OLED 显示画面的变换操作——上下、左右翻转

OLED 画面旋转 OLED 写入函数定义 OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常 OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常OLED 显示界面转换函数如下 void OLED_DisplayTurn(u8 i) {if(i0…

由播客转向个人定制的音频频道(1)平台搭建

项目的背景 最近开始听喜马拉雅播客的内容,但是发现许多不方便的地方。 休息的时候收听喜马拉雅,但是还需要不断地选择喜马拉雅的内容,比较麻烦,而且黑灯操作反而伤眼睛。 喜马拉雅为代表的播客平台都是VOD 形式的&#xff0…

luckfox-pico-max学习记录

0.文件编译及烧录 SDK包在文件夹/home/tao/linux/luckfox/luckfox-pico-spi应用程序样例在文件夹/home/tao/linux/luckfox-pico-spi/demo编译:sudo ./build.sh生成的镜像文件在./luckfox-pico-spi/output/image中,将所有文件复制到windows电脑文件夹I:\…

一文了解珈和科技在农业遥感领域的服务内容和能力

2020年,农业农村部、中央网信办联合印发了《数字农业农村发展规划(2019-2025年)》,对数字农业农村建设作出了具体部署。其中,农业遥感作为推进数字农业农村的重要力量贯穿《规划》始终。 今年10月,农业农村…

羊城杯2020Easyphp

审题 看到url,可以想到伪协议读取 尝试过后可以发现,题目绕过了read后面的编码 我们可以尝试双重urlencode进行绕过 ?filephp://filter/read%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%…

【时间之外】IT人求职和创业应知【34】-人和机器人,机器人更可靠

目录 新闻一:人形机器人产业持续高速增长,2026年中国市场规模将突破200亿元 新闻二:AI技术驱动设备厂商格局变化,部分厂商市占率快速提升 新闻三:华为与江淮汽车携手打造超高端品牌“尊界”,计划于明年春…

Linux——基础指令2 + 权限

目录 1.zip/unzip 2.tar 3.bc 4.uname –r 5.重要的几个热键 6.扩展命令 7.shell命令以及运行原理 8.Linux权限的理解 关于权限的三个问题: 1.目录权限 2.缺省权限 3.粘滞位 1.zip/unzip 打包、压缩:使用特定的算法,文件进行合…

pgsql和mysql的自增主键差异

1. 当有历史数据存在时, mysql的自增主键是默认从最大值自增。 pgsql的自增主键取初始值开始逐个尝试,所以存在可能与历史数据的主键重复的情况。 pgsql解决上述问题的方式:重设自增值。 SELECT SETVAL(t_db_filed_id_seq, (SELECT MAX(&q…

【Linux】基础IO及文件描述符相关内容详细梳理

0. C语言文件I/O 在C语言中,我们学习了相关函数来读写文件,例如:fopen,fwrite,fread,fprintf等, 在C语言中文件的打开方式: r Open text file for reading. …

大语言模型在序列推荐中的应用

一、简介 序列推荐技术通过分析用户的过往交互历史,能够有效挖掘出用户可能感兴趣的项目,对于提升各类应用的服务质量具有重要作用。近期,大语言模型(LLMs)的发展在应对复杂的推荐问题上展现出了显著的优势。不过&…

JavaScript——函数、事件与BOM对象

一、系统函数(JS中预置的函数) JS的预置函数在遇到非数字字符时会停止解析 parseInt 转整型 parseFloat 转浮点型 isNaN !isNaN("10") 检测是否纯数字 eval 把字符串转成算式并计算 1.parseInt(string, radix); 语法: string&#x…

Python酷库之旅-第三方库Pandas(208)

目录 一、用法精讲 971、pandas.MultiIndex.set_levels方法 971-1、语法 971-2、参数 971-3、功能 971-4、返回值 971-5、说明 971-6、用法 971-6-1、数据准备 971-6-2、代码示例 971-6-3、结果输出 972、pandas.MultiIndex.from_arrays类方法 972-1、语法 972-2…

相亲小程序(源码+文档+部署+讲解)

最近我在挖掘一些优秀的开源项目时,无意间发现了一个相当给力的系统——相亲小程序管理系统。这个系统不仅功能实用,而且代码结构清晰,易于二次开发。作为一名技术爱好者,我觉得有必要把这个好东西推荐给我的读者们。接下来&#…