文章目录
参考
项目 | 描述 |
---|---|
搜索引擎 | Bing、Google |
AI 大模型 | 文心一言、通义千问、讯飞星火认知大模型、ChatGPT |
PHP 官方 | PHP Manual |
PHP 官方 | class.stdclass.php |
PHP 官方 | class.allowdynamicproperties.php |
PHP 官方 | language.oop5.magic.php |
环境
项目 | 描述 |
---|---|
PHP | 5.5.0 、5.6.8 、7.0.0 、7.2.5 、7.4.9 、8.0.0 、8.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() 来实现该函数所提供的 默认功能 —— 为对象提供动态属性支持
。对此,请参考如下示例:
<?php
class 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 也将抛出 弃用提示信息
。对此,请参考如下示例:
<?php
class 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
)