具有动态属性支持的通用空类:stdClass

2023-10-12 13:12

本文主要是介绍具有动态属性支持的通用空类:stdClass,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 参考
  • 环境
  • stdClass
  • 容器
      • 数组转化为对象
      • 解析 JSON 数据
  • 动态属性
      • 概念
      • \_\_set()
          • \_\_set() 的默认行为
          • 还原 __set() 的默认行为
      • PHP8.2
          • 弃用
          • #[\AllowDynamicProperties] 注解
      • 天然的动态属性支持者 stdClass
          • stdClass 派生类

参考

项目描述
搜索引擎BingGoogle
AI 大模型文心一言通义千问讯飞星火认知大模型ChatGPT
PHP 官方PHP Manual
PHP 官方class.stdclass.php
PHP 官方class.allowdynamicproperties.php
PHP 官方language.oop5.magic.php

环境

项目描述
PHP5.5.05.6.87.0.07.2.57.4.98.0.08.2.9
PHP 编辑器PhpStorm 2023.1.1(专业版)

stdClass

stdClass 是 PHP 提供的一个 基础类,用于创建一个 没有预定义结构的空对象(stdClass 中没有定义任何成员)stdClass 的结构大致如此:

class stdClass {}

stdClass 提供了一种方式,允许开发者 在运行时动态地创建和管理对象属性,而不必预先定义一个完整的类。对此,请参考如下示例:

<?php// stdClass 属于 PHP 的基础类,
// 是 PHP 的一部分,可以直接进行使用。
$myClass = new stdClass();// 在 PHP 运行过程中动态的对属性进行创建与管理
$myClass -> name = "RedHeart";
$myClass -> nation = "BinaryMoon";
$myClass -> nation = "China";print_r($myClass);

执行效果

stdClass Object
([name] => RedHeart[nation] => China
)

容器

在 PHP 内部,stdClass 常作为一个 容器,用于存储 键值对(键值对是一种数据结构,通常用于将一个值与一个唯一标识符或键相关联。在对象中,键可以理解为属性,值可以理解为属性值)。当 PHP 需要为一些操作创建一个对象,但又 不需要特定的类结构时,就会使用 stdClass。

数组转化为对象

在 PHP 中,(object) 是一种 类型转换操作符,它用于 将一个值转换为对象,而转换后的结果对象便是 stdClass 类的实例。对此,请参考如下示例:

<?php# 创建一个关联数组
$arr = ["name" => "RedHeart", "nation" => "China"];# 通过 (object) 类型转化操作符将数组转化为对象
$obj = (object)$arr;print_r($obj);

执行效果

stdClass Object
([name] => RedHeart[nation] => China
)

解析 JSON 数据

当您使用 json_decode 函数尝试将 JSON 格式的字符串解析为对象时,解析成功的结果将为一个 stdClass 类的实例对象。对此,请参考如下示例:

<?php# 定义一个 JSON 格式的字符串
$json_string = '{"name": "RedHeart", "nation": "China"}';# 通过 json_decode 函数解析 JSON 字符串
$obj = json_decode($json_string);print_r($obj);

执行效果

stdClass Object
([name] => RedHeart[nation] => China
)

动态属性

概念

在 PHP 中,动态属性是一种 允许您在运行时向对象添加属性的特性。通常,对象的属性在定义类时就被预先声明,但 PHP 也提供了 动态属性机制,使你能够在不预先定义属性的情况下将它们添加到对象中。

__set()

__set() 是 PHP 中提供的一个 魔术方法(在特定场景中由 PHP 自动调用),用于处理对象的属性赋值。__set() 允许您在尝试访问或设置一个对象的 不存在或不可见属性(即没有直接访问权限的属性)时执行自定义的操作

当您尝试设置一个对象的不存在或不可见属性的属性值时,__set() 方法将会被自动调用。您可以在该方法中定义逻辑来规定如何执行。您必须为 __set() 魔术方法指定两个形参,其中第一个形参将用于接收尝试访问当前对象的不存在或不可见属性的 属性名称,第二个形参将用于接收尝试为该属性设置的 属性值

举个栗子

<?php# 创建一个没有任何成员属性的对象
class MyClass {# 定义 __get() 魔术方法,规定部分属性的访问逻辑function __set($name, $value) {print('Failed to set property value "' . $value . '" for property "' . $name . '".');}
};$myClass = new MyClass();# 尝试对 $myClass 对象中的属性设置属性值
$myClass -> nation = 'China';

执行效果

Failed to set property value "China" for property "nation".
__set() 的默认行为

当你没有明确规定 __set() 的执行逻辑(即没有在类中定义这个方法)并尝试为不存在或不可访问的属性设置属性值时,__set() 魔术方法的默认行为是为当前对象添加该属性并为其设置属性值。对此,请参考如下示例:

<?php$myClass = new stdClass();# 尝试为一个空对象设置属性值
$myClass -> name = "RedHeart";
$myClass -> nation = "China";print_r($myClass);

执行效果

stdClass Object
([name] => RedHeart[nation] => China
)
还原 __set() 的默认行为

我们可以通过定义 __set()复现该函数的默认逻辑,即通过定义 __set() 来实现该函数所提供的 默认功能 —— 为对象提供动态属性支持。对此,请参考如下示例:

<?phpclass MyClass
{# 尝试通过定义 __set() 来支持对象的动他属性功能function __set($name, $value) {# 在对象中,$this 变量指代当前对象$this -> $name = $value;}
}$myClass = new MyClass();$myClass -> name = "RedHeart";
$myClass -> nation = "China";print_r($myClass);

执行效果

MyClass Object
([name] => RedHeart[nation] => China
)

PHP8.2

弃用

自 PHP8.2 开始,PHP 不再支持动态属性功能,即使你通过规定 __set() 来实现动态属性功能,PHP 也将抛出 弃用提示信息。对此,请参考如下示例:

<?phpclass MyClass
{# 尝试通过定义 __set() 来支持对象的动他属性功能function __set($name, $value) {# 在对象中,$this 变量指代当前对象$this -> $name = $value;}
}$myClass = new MyClass();$myClass -> name = "RedHeart";
$myClass -> nation = "China";print_r($myClass);

执行效果

PHP8.2.9 中执行上述代码将得到如下内容:

PHP Deprecated:  Creation of dynamic property MyClass::$name is deprecated in C:\upload.php on line 9
PHP Deprecated:  Creation of dynamic property MyClass::$nation is deprecated in C:\upload.php on line 9
MyClass Object
([name] => RedHeart[nation] => China
)
#[\AllowDynamicProperties] 注解

PHP8.2.0 废弃动态属性机制的同时,PHP 提供了 #[\AllowDynamicProperties] 注解。通过将 #[\AllowDynamicProperties] 注解添加到 类定义之前,将 使得 PHP 支持该类使用动态属性并避免可能产生的 PHP 弃用提示信息的输出。对此,请参考如下示例:

<?php# 添加注解以使得 PHP 为该类提供动态属性机制
#[\AllowDynamicProperties]
class MyClass
{function __set($name, $value) {$this -> $name = $value;}
}$myClass = new MyClass();$myClass -> name = "RedHeart";
$myClass -> nation = "China";print_r($myClass);

执行效果

PHP8.2.9 中执行上述代码将得到如下内容:

MyClass Object
([nation] => China
)

天然的动态属性支持者 stdClass

在 PHP8.2.0 废弃动态属性后,stdClass 类仍旧支持动态属性机制,您并不需要尝试为 stdClass 添加 #[\AllowDynamicProperties] 注解。对此,请参考如下示例:

<?php$myClass = new stdClass();$myClass -> name = "RedHeart";
$myClass -> nation = "China";print_r($myClass);

执行效果

PHP8.2.9 中执行上述代码将得到如下内容:

stdClass Object
([name] => RedHeart[nation] => China
)
stdClass 派生类

通过 将新创建类继承自 stdClass 类,新创建的类也将获得动态属性支持,而无需使用 #[\AllowDynamicProperties] 注解。对此,请参考如下示例:

<?php# 创建一个继承自 stdClass 类的空类
class MyClass extends stdClass {};$myClass = new MyClass;$myClass -> name = "RedHeart";
$myClass -> nation = "China";print_r($myClass);

执行效果

PHP8.2.9 中执行上述代码将得到如下内容:

MyClass Object
([name] => RedHeart[nation] => China
)

这篇关于具有动态属性支持的通用空类:stdClass的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/196077

相关文章

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

Python如何调用另一个类的方法和属性

《Python如何调用另一个类的方法和属性》在Python面向对象编程中,类与类之间的交互是非常常见的场景,本文将详细介绍在Python中一个类如何调用另一个类的方法和属性,大家可以根据需要进行选择... 目录一、前言二、基本调用方式通过实例化调用通过类继承调用三、高级调用方式通过组合方式调用通过类方法/静

go动态限制并发数量的实现示例

《go动态限制并发数量的实现示例》本文主要介绍了Go并发控制方法,通过带缓冲通道和第三方库实现并发数量限制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录带有缓冲大小的通道使用第三方库其他控制并发的方法因为go从语言层面支持并发,所以面试百分百会问到

spring中的@MapperScan注解属性解析

《spring中的@MapperScan注解属性解析》@MapperScan是Spring集成MyBatis时自动扫描Mapper接口的注解,简化配置并支持多数据源,通过属性控制扫描路径和过滤条件,利... 目录一、核心功能与作用二、注解属性解析三、底层实现原理四、使用场景与最佳实践五、注意事项与常见问题六

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

python删除xml中的w:ascii属性的步骤

《python删除xml中的w:ascii属性的步骤》使用xml.etree.ElementTree删除WordXML中w:ascii属性,需注册命名空间并定位rFonts元素,通过del操作删除属... 可以使用python的XML.etree.ElementTree模块通过以下步骤删除XML中的w:as

springboot如何通过http动态操作xxl-job任务

《springboot如何通过http动态操作xxl-job任务》:本文主要介绍springboot如何通过http动态操作xxl-job任务的问题,具有很好的参考价值,希望对大家有所帮助,如有错... 目录springboot通过http动态操作xxl-job任务一、maven依赖二、配置文件三、xxl-