”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > PHP 的 `__get` 和 `__set` 魔术方法什么时候被实际调用?

PHP 的 `__get` 和 `__set` 魔术方法什么时候被实际调用?

发布于2024-11-19
浏览:806

When are PHP's `__get` and `__set` magic methods actually invoked?

PHP 魔术方法:为属性重载揭开 __get 和 __set 的面纱

在 PHP 中,__get 和 __set 魔术方法提供了另一种处理方法超越传统 getter 和 setter 的属性访问和修改。这些方法使开发人员能够在未显式定义所请求的属性时拦截和自定义属性访问的行为。

但是,一个常见的误解是 __get 和 __set 方法用于重载 get 和 set 关键字。这并不完全准确。

属性重载和魔术方法

虽然 __get 和 __set 方法可用于某种形式的属性重载,但它们与典型的重载不同其他语言中的方法。 PHP 通过公共、受保护和私有属性声明显式处理属性访问。如果未在给定范围内声明属性,PHP 将生成错误。

当 PHP 尝试访问未显式声明的属性时,魔法方法就会发挥作用。在本例中,__get 和 __set 方法提供了一种动态处理属性访问的方法。

使用 __get 和 __set

来说明 __get 和 __set 方法的用法,考虑以下示例:

class foo {
    public $bar;  // Public property
    public function __get($name) {
        echo "Get:$name";
        return $this->$name;  // Custom behavior for accessing inaccessible properties
    }
    public function __set($name, $value) {
        echo "Set:$name to $value";
        $this->$name = $value;  // Custom behavior for setting inaccessible properties
    }
}

在此场景中,__get 和 __set 方法旨在在访问或修改 $bar 属性时提供自定义行为。例如,调用 echo $foo->bar;会触发 __get 方法,而 $foo->bar = 'test';将涉及 __set 方法。

调试和常见陷阱

但是,如原始问题中所述,如果该属性已经公开声明(如本例所示) ,PHP 运行时将直接访问该属性。因此,__get 和 __set 方法不会被调用。

这种行为在 PHP 手册的属性重载部分中得到了确认,其中指出 __set 和 __get 方法仅在向不可访问的属性写入或读取数据时才会被调用,不是公共属性。

一般来说,魔术方法不应被视为正确的 getter 和 setter 函数或直接方法调用的替代品。它们的主要目的是处理无效的属性访问并在这种情况下提供替代行为。此外,值得注意的是,与直接属性访问相比,魔术方法可能会导致性能损失。

为了解决原始问题中遇到的问题,可以定义显式的 getter 和 setter 方法,这将直接处理属性访问和修改。这种方法更有效,并且可以更好地控制属性访问语义。

最新教程 更多>
  • 如何高效检索 Go 字符串的最后一个字符?
    如何高效检索 Go 字符串的最后一个字符?
    检索 Go 字符串的最后一个字符在 Go 中,处理字符串时会出现一个常见的需求:从 Go 字符串中检索最后 X 个字符给定的字符串。虽然 string 包没有为此任务提供特定函数,但有一些有效的方法可以使用切片表达式来完成此任务。要获取字符串的最后 N 个字符,请使用以下切片表达式语法:string...
    编程 发布于2024-11-19
  • Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta:列偏移的删除和恢复Bootstrap 4 在其 Beta 1 版本中引入了重大更改柱子偏移了。然而,随着 Beta 2 的后续发布,这些变化已经逆转。从 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    编程 发布于2024-11-19
  • FastAPI:如何使用 Pydantic 声明查询参数
    FastAPI:如何使用 Pydantic 声明查询参数
    它大约三周前发布,是 FastAPI 最受期待的功能之一。至少当我们谈论 Pydantic Models FastAPI 时。 是的,我说的是使用 Pydantic 模型来映射查询参数的能力。 所以在这篇文章中,我将尽力向您展示一切?可以和?无法解决这个问题?: ?映射查询参数 要开...
    编程 发布于2024-11-19
  • 测试自动化工具:综合指南
    测试自动化工具:综合指南
    测试自动化工具简介 测试自动化工具已成为现代软件开发的重要组成部分,使团队能够简化测试流程并确保高质量的发布。在当今快节奏的开发环境中,手动测试已经跟不上持续集成和交付的速度。测试自动化工具允许团队自动执行重复任务,减少人为错误并腾出时间进行更复杂的测试工作。 为什么使用测试自动化工具? 自动化工...
    编程 发布于2024-11-19
  • 为什么在 AngularJS 中使用“controller as”语法?
    为什么在 AngularJS 中使用“controller as”语法?
    理解AngularJS的“controller as”语法简介AngularJS引入了一种定义控制器的新语法“controller as”,这引起了一些关注关于其目的的问题。本文旨在阐明此语法背后的基本原理及其优点。Controller as 语法“controller as”语法允许您实例化控制器...
    编程 发布于2024-11-19
  • 如何为单个 Go 项目定义 GOPATH?
    如何为单个 Go 项目定义 GOPATH?
    自动为各个项目定义GOPATH简介:在Go中管理依赖项和项目需要设置GOPATH 环境变量,但使用单个 GOPATH 的默认方法可能会导致冲突和冗余。本讨论探讨了在每个项目的基础上定义 GOPATH 的潜在解决方案。为每个项目定义 GOPATH:传统方法需要使用导出 GOPATH= 为每个项目手动设...
    编程 发布于2024-11-19
  • 如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 识别今天生日的用户使用 MySQL 确定今天是否是用户的生日涉及查找生日匹配的所有行今天的日期。这可以通过一个简单的 MySQL 查询来实现,该查询将存储为 UNIX 时间戳的生日与今天的日期进行比较。以下 SQL 查询将获取今天有生日的所有用户: FROM USERS ...
    编程 发布于2024-11-19
  • Google 财经小工具 API 弃用后如何检索股票行情?
    Google 财经小工具 API 弃用后如何检索股票行情?
    使用 Google Finance API 检索股票报价正如您所提到的,Google Finance Gadget API 不再可用。因此,通过这种方法访问股票报价不再可行。但是,还有其他资源提供类似的功能。一种替代方案是 Google Cloud Platform 的财务数据 API。此 API ...
    编程 发布于2024-11-19
  • 如何使用CSS在显示图像时有效隐藏文本?
    如何使用CSS在显示图像时有效隐藏文本?
    使用 CSS 隐藏文本使用 CSS 隐藏文本元素可用于各种设计目的。一种常见的情况是用图像替换文本作为徽标。本文解决了一个具体问题:如何在显示图像时有效地去除原始文本。隐藏文本的解决方案有多种方法可以使文本在显示图像时不可见保留图像放置的元素尺寸。方法 1:文本缩进一种技术涉及使用文本缩进将文本推出...
    编程 发布于2024-11-19
  • 如何在 Go 中为派生标量类型实现自定义 JSON 解组?
    如何在 Go 中为派生标量类型实现自定义 JSON 解组?
    在 Go 中导出用于 JSON 解组的自定义类型在 Go 中使用自定义类型时,通常需要实现 UnmarshalJSON 函数来启用自动从 JSON 转换为所需类型。然而,当类型源自标量值时,就会出现挑战。本文探讨了解决此问题的解决方案。考虑 PersonID 类型的示例,该类型表示用于标识个人的子类...
    编程 发布于2024-11-19
  • 为什么在 PHP PDO 中的错误处理中,try {} catch {} 优于 if {} else {}?
    为什么在 PHP PDO 中的错误处理中,try {} catch {} 优于 if {} else {}?
    在错误处理方面,try {} catch {} 相对于 if {} else {} 的优点从普通 MySQL 迁移到 PHP PDO 时开发人员经常观察到使用 try {} catch {} 块而不是 if {} else {} 组合进行错误处理的转变。这种偏好源于以下几个优点:全面的错误处理try...
    编程 发布于2024-11-19
  • 如何计算两个 Joda-Time 日期时间之间的时差(以分钟为单位)?
    如何计算两个 Joda-Time 日期时间之间的时差(以分钟为单位)?
    计算两个 Joda-Time DateTimes 之间的时间差(以分钟为单位)在确定两个 Joda-Time DateTime 对象之间的时间差的过程中,让我们深入研究提供的解决方案:答案建议使用 Duration 类,它是时间量的抽象表示。通过将 Duration 对象初始化为 Durationu...
    编程 发布于2024-11-19
  • os.FileMode 在设置标志之前如何转换权限?
    os.FileMode 在设置标志之前如何转换权限?
    设置Flags之前os.FileMode如何转换权限最初关注使用时使用八进制或十进制数的 os.FileMode 函数,生成的文件权限似乎并不总是与预期行为匹配。具体来说,传递十进制数(不带前导零)会导致与传递八进制等效值不同的文件属性。转换逻辑os.FileMode 接受整数作为输入并在内部将其表...
    编程 发布于2024-11-19
  • 如何根据用户指定的数量动态创建输入表单元素?
    如何根据用户指定的数量动态创建输入表单元素?
    为用户指定的数字创建动态输入表单元素了解手头的任务,用户打算基于动态生成输入表单元素基于用户提供的整数。我们的目标是提供一个简单的解决方案,而不会使过程过于复杂。利用 JavaScript,我们可以通过以下步骤来应对这一挑战:检索用户输入:利用“填写详细信息”链接的 onclick 事件处理程序来检...
    编程 发布于2024-11-19
  • 如何使用 Golang 处理 AWS Lambda 中的多个触发器?
    如何使用 Golang 处理 AWS Lambda 中的多个触发器?
    在 Golang 中支持 AWS Lambda 的多个触发器简介AWS Lambda 支持来自各种来源的触发函数,包括 S3 事件和 SQS 消息。但是,当您需要 Lambda 函数响应多个触发器时,就会出现困境。建议的解决方案您尝试了两种方法:第一种方法:func main() { lam...
    编程 发布于2024-11-19

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3