3種策略巧妙化解PHP Trait成員屬性衝突

来源:https://www.cnblogs.com/phpphp/p/18012405
-Advertisement-
Play Games

說明 PHP語言本身可以用insteadof和as關鍵字解決多個trait同名成員方法衝突的問題,但是貌似沒有直接解決同名成員屬性衝突的方案。 雖然屬性名衝突極少發生,但是不代表不會發生。 如果是自定義trait 可以複製舊trait文件到新trait,改新文件的成員屬性名,引用新trait。 直接 ...


說明

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,既不衝突,又能同時為我所用。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 找半天沒找到相關的內容,自己搗鼓出來的,記錄一下。(比較可惜的是只能獲取靜態圖片,動態壁紙就不知道了咋弄了) uniapp的話還可以參考一下如何用NJS獲取手機桌面壁紙? - DCloud問答下麵DCloud_heavensoft 大佬的一個回答 : “Native.js很多類型沒有。用uts可以  ...
  • 前言 以前使用的都是預設的博客園主題,最近剛好有空,著手定製以下自己的博客園主題。最終效果參考當前的博客,如果看不到則需要在博客園首頁頭像處懸停關閉簡潔模式 思路是儘量保持原有結構,不進行破壞性改動,以 css 樣式為主 本主題是輕量化的,只是在原有基礎上微調樣式。如有需要更豐富功能的可以自己搜索博 ...
  • 迴首 在 零基礎入門Vue之夢開始的地方——插值語法 我記錄了v-bind、v-on、v-model的學習 在 零基礎入門Vue之To be or not to be——條件渲染 我記錄了v-if、v-else-if、v-else、v-show的學習 在 零基礎入門Vue之影分身之術——列表渲染&渲 ...
  • Rich庫的功能就像它的名字一樣,使Python編程更加豐富(rich),它幫助開發者在控制台(命令行)輸出中創建豐富、多彩和具有格式化的文本。 本篇總結瞭如何使用Rich庫讓我們的命令行工具更加美觀。 1. 安裝 通過pip安裝: pip install rich 使用下麵的命令驗證是否安裝成功。 ...
  • G 題面 定義\({{dp_i}_j}_k\)為考慮完第i個點,最左邊沒有染色的點為\(j\),最右邊沒有染色的點為\(k\)的最小數量。 考慮轉移(用自己更新別人) 如果不用\(i\),直接轉移到\({{dp_{i+1}}_j}_k\)。 如果向左噴,\(k\)為\(max({i+1,k})\), ...
  • 關註我,緊跟本系列專欄文章,咱們下篇再續! 作者簡介:魔都技術專家兼架構,多家大廠後端一線研發經驗,各大技術社區頭部專家博主,編程嚴選網創始人。具有豐富的引領團隊經驗,深厚業務架構和解決方案的積累。負責: 中央/分銷預訂系統性能優化 活動&優惠券等營銷中台建設 交易平臺及數據中台等架構和開發設計 目 ...
  • 概述 所謂介面冪等性就是:在特定場景下,同一條件的多次介面調用,保證操作只執行一次,如果介面沒有保證冪等性,在以下場景就會產生問題 前端重覆提交:用戶進行註冊、創建個人信息等操作,由於網路抖動導致頁面沒有及時響應,用戶認為沒有成功而多次點擊提交按鈕,發生重覆提交表單請求 介面超時重試:提供外部系統調 ...
  • 分享是最有效的學習方式。 博客:https://blog.ktdaddy.com/ 老貓的設計模式專欄已經偷偷發車了。不甘願做crud boy?看了好幾遍的設計模式還記不住?那就不要刻意記了,跟上老貓的步伐,在一個個有趣的職場故事中領悟設計模式的精髓吧。還等什麼?趕緊上車吧 故事 這段時間以來,小貓 ...
一周排行
    -Advertisement-
    Play Games
  • 最近做項目過程中,使用到了海康相機,官方只提供了C/C++的SDK,沒有搜尋到一個合適的封裝了的C#庫,故自己動手,簡單的封裝了一下,方便大家也方便自己使用和二次開發 ...
  • 前言 MediatR 是 .NET 下的一個實現消息傳遞的庫,輕量級、簡潔高效,用於實現進程內的消息傳遞機制。它基於中介者設計模式,支持請求/響應、命令、查詢、通知和事件等多種消息傳遞模式。通過泛型支持,MediatR 可以智能地調度不同類型的消息,非常適合用於領域事件處理。 在本文中,將通過一個簡 ...
  • 前言 今天給大家推薦一個超實用的開源項目《.NET 7 + Vue 許可權管理系統 小白快速上手》,DncZeus的願景就是做一個.NET 領域小白也能上手的簡易、通用的後臺許可權管理模板系統基礎框架。 不管你是技術小白還是技術大佬或者是不懂前端Vue 的新手,這個項目可以快速上手讓我們從0到1,搭建自 ...
  • 第1章:WPF概述 本章目標 瞭解Windows圖形演化 瞭解WPF高級API 瞭解解析度無關性概念 瞭解WPF體繫結構 瞭解WPF 4.5 WPF概述 ​ 歡迎使用 Windows Presentation Foundation (WPF) 桌面指南,這是一個與解析度無關的 UI 框架,使用基於矢 ...
  • 在日常開發中,並不是所有的功能都是用戶可見的,還在一些背後默默支持的程式,這些程式通常以服務的形式出現,統稱為輔助角色服務。今天以一個簡單的小例子,簡述基於.NET開發輔助角色服務的相關內容,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 第3章:佈局 本章目標 理解佈局的原則 理解佈局的過程 理解佈局的容器 掌握各類佈局容器的運用 理解 WPF 中的佈局 WPF 佈局原則 ​ WPF 視窗只能包含單個元素。為在WPF 視窗中放置多個元素並創建更貼近實用的用戶男面,需要在視窗上放置一個容器,然後在這個容器中添加其他元素。造成這一限制的 ...
  • 前言 在平時項目開發中,定時任務調度是一項重要的功能,廣泛應用於後臺作業、計劃任務和自動化腳本等模塊。 FreeScheduler 是一款輕量級且功能強大的定時任務調度庫,它支持臨時的延時任務和重覆迴圈任務(可持久化),能夠按秒、每天/每周/每月固定時間或自定義間隔執行(CRON 表達式)。 此外 ...
  • 目錄Blazor 組件基礎路由導航參數組件參數路由參數生命周期事件狀態更改組件事件 Blazor 組件 基礎 新建一個項目命名為 MyComponents ,項目模板的交互類型選 Auto ,其它保持預設選項: 客戶端組件 (Auto/WebAssembly): 最終解決方案裡面會有兩個項目:伺服器 ...
  • 先看一下效果吧: isChecked = false 的時候的效果 isChecked = true 的時候的效果 然後我們來實現一下這個效果吧 第一步:創建一個空的wpf項目; 第二步:在項目裡面添加一個checkbox <Grid> <CheckBox HorizontalAlignment=" ...
  • 在編寫上位機軟體時,需要經常處理命令拼接與其他設備進行通信,通常對不同的命令封裝成不同的方法,擴展稍許麻煩。 本次擬以特性方式實現,以兼顧維護性與擴展性。 思想: 一種命令對應一個類,其類中的各個屬性對應各個命令段,通過特性的方式,實現其在這包數據命令中的位置、大端或小端及其轉換為對應的目標類型; ...