2016-08-03 67 views
0

我有一個對象具有一些受保護的字段以及使用它們的方法。該方法並不完全符合我需要它做的事情,但是由於我正在編寫附加組件,所以我無法更改原始代碼。 是否可以通過某種方式擴展該類並重寫該方法,以便可以在原始類的預定義對象上調用它?我想過猴子補丁,但顯然它沒有在PHP中實現。PHP:更改方法行爲

+1

這取決於...如果原始類是通過註冊自動加載器自動加載的,也許您可​​以創建自己的類和自動加載器,並強制自動加載鏈首先通過自動加載器。如果你使用的是框架,也許你應該檢查它是否允許這個本地(例如Laravel提供了很大的支持)。總體而言,這裏沒有足夠的信息來幫助。 – apokryfos

+0

我正在嘗試編寫一個模擬示例,但是項目結構與嵌套類的桶很複雜,很難確定哪些部分是相關的。 – Simoroshka

回答

1

您可以通過擴展父類,啓動新類而不是父類,並將您的方法命名爲與父方法完全相同的命名方法,即子方法將被調用,而不是父類

例子:

class Foo { 
    function sayFoo() { 
     echo "Foo"; 
    } 
} 

class Bar extends Foo { 
    function sayFoo() { 
     echo "Bar"; 
    } 
} 

$foo = new Foo(); 
$bar = new Bar(); 

$foo->sayFoo() //Outputs: Foo 
$bar->sayFoo() //Outputs: Bar 
+0

在我的情況下,發生在其他地方,不幸的是 – Simoroshka

+0

然後不,你不能改寫方法而不改變類的啓動。 – joshualawson

+0

那麼你可以使用[runkit](https://pecl.php.net/package/runkit)。但是你可能遇到一些使用你將要替換的方法的其他方法的意外行爲。 – wazelin

0

我希望下面的stategy將是作品。假設類是Foo,方法是bar()。要覆蓋bar()方法,您必須使customFoo類如下所述。

class CustomFoo extends Foo{ 
    public function bar(){ 
     parent::bar(); 
    } 
} 

我實際上不知道你需要什麼,因爲你沒有詳細解釋。儘管如此,我還是盡力了。 :)

0

嘗試創建一個擴展對象當前派生的基類或父類的子類。 用與Parent類中的方法完全相同的名稱創建一個新方法,並將邏輯放在那裏。 現在從您的新類實例化對象,您將成功重寫該特定方法,並仍然可以訪問基類的方法和屬性。

0

問題是,一旦你已經加載的類,你不能正式卸載它,你需要加載它,以擴展它。所以它很緊張。最好的辦法是要麼破解原班(不理想)或複製原來的類定義粘貼到一個新的文件:

class ParentClass { 
     //Copy paste code and modify as you need to. 
} 

後某處你的框架的引導:

spl_autoload_register(function ($class) { 
     if ($class == "ParentClass") { //Namespace is also included in the class name so adjust accordingly 
     include 'path/to/modified/ParentClass.php'; 
     } 
},true,true); 

這是完成以確保您自己的修改後的類將在原始之前加載。 這是非常冒險的,所以首先檢查你使用的框架是否具有原生支持。

+0

這也會影響所有其他可以使用這個類的東西嗎? – Simoroshka

+1

是的,但這種解決方案並不理想。只有在你確實沒有任何其他選擇時才使用它。 – apokryfos