首页 > 编程语言 >3种策略巧妙化解PHP Trait成员属性冲突

3种策略巧妙化解PHP Trait成员属性冲突

时间:2024-02-09 12:11:23浏览次数:23  
标签:echo Trait 巧妙 prop 冲突 trait PHP public 属性

说明

PHP语言本身可以用insteadof和as关键字解决多个trait同名成员方法冲突的问题,但是貌似没有直接解决同名成员属性冲突的方案。
虽然属性名冲突极少发生,但是不代表不会发生。

如果是自定义trait

  1. 可以复制旧trait文件到新trait,改新文件的成员属性名,引用新trait。
  2. 直接更改原trait成员属性名,可能会影响项目。

如果就不动原trait,仅通过类怎么解决?(例如某些trait在vendor下,极少的情况下需要同时引用多个trait,他们的属性冲突了)

示例

如下:C类想用A Trait和B Trait的方法,但是属性名冲突,报错。
Fatal error: A and B define the same property ($prop) in the composition of C. However, the definition differs and is considered incompatible. Class was composed。

trait A {
    public $prop = 'trait_a';
    public function speakEnglish() {
        echo 'English';
    }
}

trait B {
    public $prop = 'trait_b';
    public function speakChinese() {
        echo '中文';
    }
}

class C {
    use A,B;
}

$c = new C();
echo $c->prop;

错误的解决方案

PHP语言本身可以用insteadof和as关键字解决多个trait同名成员方法冲突的问题,但是这无法修饰成员属性。
报错:Fatal error: A precedence rule was defined for A::prop but this method does not exist.

class C {
    use A,B {
        A::prop insteadof B;
        B::prop as B_prop;
    }
}

$c = new C();
echo $c->prop;

正确的解决方案

  1. 需要一个父类参与,相当于一个中间人为冲突双方做调解。
  2. 并在父类中引入任意一个trait,相当于告诉这个trait停止冲突。
  3. 子类继承父类并引入另一个trait,并重新声明属性并赋初始值,相当于告诉另一个trait也停止冲突,而且支持你。
  4. 此时子类继承了家业又化解了冲突。
  5. 需要注意:C类中的public $prop = 'trait_b'不能少,且必须等于B trait中的值,否则会报致命错误。
trait A {
    public $prop = 'trait_a';
    public function speakEnglish() {
        echo 'English';
    }
}

trait B {
    public $prop = 'trait_b';
    public function speakChinese() {
        echo '中文';
    }
}

class P {
    use A;
}

class C  extends P {
    use B;
    public $prop = 'trait_b';
	//构造方法为非必填项
    public function __construct() {
        $this->prop = 'new value';
    }
}

$c = new C();
echo $c->prop;
$c->speakEnglish();
$c->speakChinese();

至此,使用父类可巧妙化解PHP Trait成员属性冲突的问题,让不能更改的两个trait,既不冲突,又能同时为我所用。

标签:echo,Trait,巧妙,prop,冲突,trait,PHP,public,属性
From: https://www.cnblogs.com/phpphp/p/18012405

相关文章

  • php,用touch 修改文件时间
     touch($path,$fc_time,$fc_time);echo"\n$path已经被建立,并且重置了修改时间和访问时间\n";echo"\n如果是windows系统,将会执行以下命令重置该文件的建立时间\n";if(PHP_OS==='WINNT'){$path=str_replace('/','\\......
  • Apache配置不同目录绑定不同版本的PHP
    Apache配置不同目录绑定不同版本的PHPhttps://aka.ms/vs/17/release/vc_redist.x64.exehttps://www.apachelounge.com/download/VS17/binaries/httpd-2.4.58-310124-win64-VS17.ziphttps://www.apachelounge.com/download/VS17/modules/mod_fcgid-2.3.10-win64-VS17.zipDefine......
  • Ubuntu安装PHP8.2 编译安装 oci8 pdo_oci扩展
    PHP8.2是PHP语言的最新版本。新特性包括,只读类,允许布尔值作为独立类型等。从mysqli中删除libmysql的支持等。时至今天,主流的HTTP服务器已不是Apache,我们推荐使用Nginx作为HTTP服务器,Nginx相对于Apache来说简单且性能更好。本教程将向您展示如何在Ubuntu20.04安装PHP8.2并将其......
  • Version 1.23.0 of PhpSpreadsheet breaks PHP 7.3+ support
    Version1.23.0ofPhpSpreadsheetbreaksPHP7.3+supporthttps://github.com/PHPOffice/PhpSpreadsheet/issues/2779当你升级composerupdate时候,项目跑不通的时候,请检查相关依赖的版本;欢迎关注公-众-号【TaonyDaily】、留言、评论,一起学习。Don’treinventthewh......
  • ThinkPHP 6.0 SQL注入漏洞修复
    公司买的官网被政府网安检测出SQL注入漏洞:隐患描述SQL漏洞证明语句: python3sqlmap.py-u"http://xxxx?keywords=1"-pkeywords--level=5--risk=3--tamper=space2comment.py,between.py--current-db--random-agent--time-sec=10--batch--dbms="MySQL"漏洞回显:权......
  • 靶场搭建----phpstudy2018安装及注意问题
    安装官网下载:https://www.xp.cn/download.html新人推荐2018版本phpstudy介绍系统服务------开机自启非服务模式------开机不自启搭建好环境,此时服务器与客户端同时存在服务器:phpstudy所在的目录客户端:除phpstudy所在目录外的都是客户端调整phpstud......
  • 第22天:安全开发-PHP应用&留言板功能&超全局变量&数据库操作&第三方插件引用
    #数据库操作-mysqli函数&增删改查PHP函数:连接,选择,执行,结果,关闭等参考:https://www.runoob.com/php/php-ref-mysqli.html常用:mysqli_connect()打开一个到MySQL的新的连接。mysqli_select_db()更改连接的默认数据库。mysqli_query()执行某个针对数据库的查询。mysqli_fetch......
  • php下载远程图片保存到本地
    /***下载远程图片保存到本地*@param$url文件url*@param$save_dir保存文件目录*@param$filename保存文件名称*@param$type使用的下载方式*@returnbool*/functiondownloadImage($url,$save_dir='',$filename=''){if(trim($url)==......
  • PHP导出Excel,从xlswriter到golang的进化是2分缩减到5秒
    先看图 一、介绍xlswriter是一个高效处理excel文件的PHP扩展,底层以C语言实现;处理速度是PHPExcel几十倍甚至几百倍的效率。官方链接:https://gitee.com/viest/php-ext-xlswriter缺点:更深入的功能(例如读取excel图片)健全;导出excel样式不够丰富导出excel文件,xlswriter绝对是效......
  • php clone和=区别
    如果有一个实例化的对象:Object1$Object2=$Object1$Object2=clone$Object1有什么区别呢?$Object2=$Object1是引用;$Object2=clone$Object1是克隆;引用就是:当改变$Object1对象时,$Object2也做相同的变化。克隆就是:克隆的对象$Object1与原来的对象没有任何关系,它......