”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 在PHP 5.4中使用特征

在PHP 5.4中使用特征

发布于2025-03-24
浏览:922

PHP 5.4 中 Traits 的使用指南

Using Traits in PHP 5.4

核心要点

  • PHP 5.4 引入的 Traits 机制允许在不同类继承层次结构的独立类之间水平复用代码,解决了单继承的局限性,减少了代码重复。
  • 单个类可以使用多个 Traits,Traits 还可以由其他 Traits 组成,从而实现灵活且模块化的代码组织方式。
  • 使用 insteadof 关键字可以解决具有相同方法名称的 Traits 之间的冲突,或者使用 as 关键字创建方法别名。
  • Traits 可以访问组合类的私有属性或方法,反之亦然,甚至可以包含组合类必须实现的抽象方法。

面向对象编程的一个重要目标是通过更好的组织和代码复用来最大限度地减少代码重复。但在 PHP 中,由于其使用的单继承模型的限制,这有时可能很困难;您可能有一些希望在多个类中使用的方法,但它们可能不太适合继承层次结构。像 C 和 Python 这样的语言允许我们从多个类继承,这在一定程度上解决了这个问题,而 Ruby 中的 mixin 允许我们在不使用继承的情况下混合一个或多个类的功能。但是多重继承存在诸如菱形问题(Diamond Problem)等问题,mixin 也是一种复杂的机制。在本文中,我将讨论 Traits,这是 PHP 5.4 中引入的一个新特性,用于克服此类问题。Traits 本身这个概念在编程中并不新鲜,在 Scala 和 Perl 等其他语言中都有使用。它们允许我们在不同类继承层次结构的独立类之间水平复用代码。

Trait 的外观

Trait 类似于不能单独实例化的抽象类(尽管更常将其与接口进行比较)。PHP 文档将 Traits 定义如下:> Traits 是一种用于单继承语言(如 PHP)中代码复用的机制。Traits 的目的是通过使开发人员能够在几个独立的类(存在于不同的类继承层次结构中)中自由地复用方法集来减少单继承的一些限制。

让我们考虑这个例子:

如果这两个类都需要一些公共功能,例如使它们都成为单例,那将是一个问题。由于 PHP 不支持多重继承,因此每个类都必须实现支持单例模式的必要代码,或者将会有一个没有意义的继承层次结构。Traits 为这类问题提供了一种解决方案。

Singleton Trait 以单例模式的直接实现方式实现,具有一个静态方法 getInstance(),该方法使用此 Trait 创建类的对象(如果尚未创建)并返回它。让我们尝试使用 getInstance() 方法创建这些类的对象。

我们可以看到 $aDbReader 的对象,$bFileReader 的对象,但两者现在都表现为单例。来自 Singleton 的方法已被水平注入到使用它的类中。Traits 不会对类强加任何额外的语义。在某种程度上,您可以将其视为一种编译器辅助的复制粘贴机制,其中 Trait 的方法被复制到组合类中。如果我们只是从具有私有 $instance 属性的父类中对 DbReader 进行子类化,则该属性不会显示在 ReflectionClass::export() 的转储中。然而,使用 Traits,它就在那里!

Class [  class FileReader ] {
  @@ /home/shameer/workplace/php54/index.php 19-22

  - Constants [0] {
  }
  - Static properties [1] {
    Property [ private static $_instance ]
  }
  - Static methods [1] {
    Method [  static public method instance ] {
      @@ /home/shameer/workplace/php54/index.php 6 - 11
    }
  }
  - Properties [0] {
  }
  - Methods [0] {
  }
}
{ @@ /home/shameer/workplace/php54/index.php 6 - 11 } } - Properties [0] { } - Methods [0] { } }

多个 Traits

sayHello() . " " . $world->sayWorld(); //Hello World
sayHello() . " " . $world->sayWorld(); //Hello World

这里我们有两个 Traits,HelloWorldHello Trait 只能说“Hello”,World Trait 可以说“World”。在 MyWorld 类中,我们应用了 HelloWorld,以便

MyWorld

对象将具有来自这两个 Traits 的方法,并且能够说“Hello World”。

由 Traits 组成的 Traits

sayHello() . " " . $world->sayWorld(); //Hello World
sayHello() . " " . $world->sayWorld(); //Hello World

在这里,我们创建了 HelloWorld Trait,使用了 HelloWorld Traits,并在 MyWorld 中包含了它。由于

HelloWorld

Trait 具有来自其他两个 Traits 的方法,因此它与我们在类中自己包含这两个 Traits 完全相同。

(以下内容因篇幅限制,将简略概括,保留核心信息)

优先级顺序:

Trait 方法优先级高于父类方法,类方法优先级高于 Trait 方法。 冲突解决和别名: 使用 insteadof 选择使用哪个 Trait 方法,使用

as

创建方法别名以避免冲突。 反射: ReflectionClass 提供了获取类中 Traits 信息的方法,例如 getTraits()getTraitNames()isTrait()

getTraitAliases()

其他特性:

Traits 可以访问组合类的私有属性和方法,反之亦然;Traits 可以包含抽象方法,要求组合类实现这些方法;Traits 不能有构造函数,但可以有公共初始化方法。

总结:

Traits 是 PHP 5.4 中引入的最强大的特性之一,本文几乎讨论了它的所有特性。它们允许程序员在多个类之间水平复用代码片段,而这些类不必位于相同的继承层次结构中。它们提供了一种轻量级的代码复用机制,而不是复杂的语义。尽管 Traits 有一些缺点,但它们肯定可以帮助改进应用程序的设计,消除代码重复,并使其更 DRY。

(FAQs 部分因篇幅过长,在此省略。核心信息已在上述内容中涵盖。)

最新教程 更多>
  • 如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
    如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
    在Visual Studio 2012 尽管已安装了MySQL Connector v.6.5.4,但无法将MySQL数据库添加到实体框架的“ DataSource对话框”中。为了解决这一问题,至关重要的是要了解MySQL连接器v.6.5.5及以后的6.6.x版本将提供MySQL的官方Visual...
    编程 发布于2025-05-05
  • 如何在JavaScript对象中动态设置键?
    如何在JavaScript对象中动态设置键?
    在尝试为JavaScript对象创建动态键时,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正确的方法采用方括号: jsobj ['key''i] ='example'1; 在JavaScript中,数组是一...
    编程 发布于2025-05-05
  • 如何使用PHP从XML文件中有效地检索属性值?
    如何使用PHP从XML文件中有效地检索属性值?
    从php $xml = simplexml_load_file($file); foreach ($xml->Var[0]->attributes() as $attributeName => $attributeValue) { echo $attributeName,...
    编程 发布于2025-05-05
  • Python中嵌套函数与闭包的区别是什么
    Python中嵌套函数与闭包的区别是什么
    嵌套函数与python 在python中的嵌套函数不被考虑闭合,因为它们不符合以下要求:不访问局部范围scliables to incling scliables在封装范围外执行范围的局部范围。 make_printer(msg): DEF打印机(): 打印(味精) ...
    编程 发布于2025-05-05
  • 解决Spring Security 4.1及以上版本CORS问题指南
    解决Spring Security 4.1及以上版本CORS问题指南
    弹簧安全性cors filter:故障排除常见问题 在将Spring Security集成到现有项目中时,您可能会遇到与CORS相关的错误,如果像“访问Control-allo-allow-Origin”之类的标头,则无法设置在响应中。为了解决此问题,您可以实现自定义过滤器,例如代码段中的MyFi...
    编程 发布于2025-05-05
  • 在程序退出之前,我需要在C ++中明确删除堆的堆分配吗?
    在程序退出之前,我需要在C ++中明确删除堆的堆分配吗?
    在C中的显式删除 在C中的动态内存分配时,开发人员通常会想知道是否需要手动调用“ delete”操作员在heap-exprogal exit exit上。本文深入研究了这个主题。 在C主函数中,使用了动态分配变量(HEAP内存)的指针。当应用程序退出时,此内存是否会自动发布?通常,是。但是,即使在这...
    编程 发布于2025-05-05
  • Python中何时用"try"而非"if"检测变量值?
    Python中何时用"try"而非"if"检测变量值?
    使用“ try“ vs.” if”来测试python 在python中的变量值,在某些情况下,您可能需要在处理之前检查变量是否具有值。在使用“如果”或“ try”构建体之间决定。“ if” constructs result = function() 如果结果: 对于结果: ...
    编程 发布于2025-05-05
  • 同实例无需转储复制MySQL数据库方法
    同实例无需转储复制MySQL数据库方法
    在同一实例上复制一个MySQL数据库而无需转储在同一mySQL实例上复制数据库,而无需创建InterMediate sqql script。以下方法为传统的转储和IMPORT过程提供了更简单的替代方法。 直接管道数据 MySQL手动概述了一种允许将mysqldump直接输出到MySQL clie...
    编程 发布于2025-05-05
  • CSS强类型语言解析
    CSS强类型语言解析
    您可以通过其强度或弱输入的方式对编程语言进行分类的方式之一。在这里,“键入”意味着是否在编译时已知变量。一个例子是一个场景,将整数(1)添加到包含整数(“ 1”)的字符串: result = 1 "1";包含整数的字符串可能是由带有许多运动部件的复杂逻辑套件无意间生成的。它也可以是故意从单个真理...
    编程 发布于2025-05-05
  • 为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    网格超过身体,用100%grid-template-columns 为什么在grid-template-colms中具有100%的显示器,当位置设置为设置的位置时,grid-template-colly修复了?问题: 考虑以下CSS和html: class =“ snippet-code”> g...
    编程 发布于2025-05-05
  • Java开发者如何保护数据库凭证免受反编译?
    Java开发者如何保护数据库凭证免受反编译?
    在java 在单独的配置文件保护数据库凭证的最有效方法中存储凭据是将它们存储在单独的配置文件中。该文件可以在运行时加载,从而使登录数据从编译的二进制文件中远离。使用prevereness class import java.util.prefs.preferences; 公共类示例{ 首选项...
    编程 发布于2025-05-05
  • 如何使用Python的请求和假用户代理绕过网站块?
    如何使用Python的请求和假用户代理绕过网站块?
    如何使用Python的请求模拟浏览器行为,以及伪造的用户代理提供了一个用户 - 代理标头一个有效方法是提供有效的用户式header,以提供有效的用户 - 设置,该标题可以通过browser和Acterner Systems the equestersystermery和操作系统。通过模仿像Chro...
    编程 发布于2025-05-05
  • 反射动态实现Go接口用于RPC方法探索
    反射动态实现Go接口用于RPC方法探索
    在GO 使用反射来实现定义RPC式方法的界面。例如,考虑一个接口,例如:键入myService接口{ 登录(用户名,密码字符串)(sessionId int,错误错误) helloworld(sessionid int)(hi String,错误错误) } 替代方案而不是依靠反射...
    编程 发布于2025-05-05
  • 解决MySQL错误1153:数据包超出'max_allowed_packet'限制
    解决MySQL错误1153:数据包超出'max_allowed_packet'限制
    mysql错误1153:故障排除比“ max_allowed_pa​​cket” bytes 更大的数据包,用于面对阴谋mysql错误1153,同时导入数据capase doft a Database dust?让我们深入研究罪魁祸首并探索解决方案以纠正此问题。理解错误此错误表明在导入过程中接...
    编程 发布于2025-05-05
  • 如何有效地转换PHP中的时区?
    如何有效地转换PHP中的时区?
    在PHP 利用dateTime对象和functions DateTime对象及其相应的功能别名为时区转换提供方便的方法。例如: //定义用户的时区 date_default_timezone_set('欧洲/伦敦'); //创建DateTime对象 $ dateTime = ne...
    编程 发布于2025-05-05

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

Copyright© 2022 湘ICP备2022001581号-3