2011-03-25 111 views
1

不能讓我的頭在這個,有沒有什麼辦法來檢查一個方法是否被內部調用?通過這個我的意思是回溯來檢查它是否被$ this調用,而不是指向實例的指針。有點像私人功能的概念,但只有功能是公共的?PHP,區分內部和外部類的方法調用

<?php 

class Foo { 
    public function check() { 
     /* 
     if invoked by $this (internally) 
      return true 
     else 
      return false 
     */ 
    } 

    public function callCheck() { 
     /* returns true because its called by $this */ 
     return $this->check(); 
    } 
} 

$bar = new Foo; 
// this should return false because we are calling it from an instance 
$bar->check(); 
// where as this will return true 
$bar->callCheck(); 

?> 

也許這是可以撤消的,但我真的需要它在我的大學項目?任何人都會遇到一個解決方案,或知道如何識別解決方案。

謝謝。

+4

看起來像你應該更換你的接口。函數不應該根據*如何調用而作出不同的反應。如果您正在尋找'public' /'private'行爲,爲什麼不使用它? – deceze 2011-03-25 03:42:42

+4

你爲什麼想知道其中的差異?您似乎可能會嘗試用錯誤的解決方案來解決問題。 – Jonah 2011-03-25 03:43:18

+0

@deceze @Jonah我試圖將對象合併在一起,但保持分開。所以我可以通過編程擴展對象,而不是在界面中定義它。所以如果一個對象有一個受保護的函數,那麼合併它的對象可以調用受保護的函數,但顯然受保護意味着你可以從一個實例調用它。你懂我的意思嗎??? – 2011-03-25 04:10:01

回答

1

下面的解決方案不起作用。


您可以使用debug_backtrace但它會很慢。我真的建議你找到一種不同的方法來解決你正在努力克服的問題。

<?php 
public function check() { 
    $trace = debug_backtrace(); 
    if ($trace[1]['class'] == 'MyClassName') { 
     return true; 
    } 
    return false; 
} 
+0

回溯工作的問題是$ bar class_name等於$ this class_name,那麼該方法如何知道誰在調用它時這些課程是平等的。 – 2011-03-25 04:06:21

+0

你說得對。我曾以爲課堂會叫課堂,而不是被叫課堂。現在我覺得有意義,但我想。 – MitMaro 2011-03-25 04:13:44

+0

實例和類與您所看到的相同,該類不會繼承或擴展接口 – 2011-03-25 04:18:24

0

如果你有一個電話$ bar-> callCheck();控制從函數check()退出;

首先它去 callCheck(),然後後往那裏去檢查(),並從那裏返回

+1

不確定您的工作內容,您可以舉例嗎? – 2011-03-25 04:07:04

0

debug_backtrace();應該管用。放置debug_backtrace();在check()方法中。

做到這一點:

$ T = debug_backtrace(); var_dump($ t);

從這裏你應該檢查$ t ['function']和$ t ['class'],結合那些2,你應該找出是一個呼叫,外部還是內部。

這裏是從我的機器出來,PHP版本是5.2.14。

array(1) { 
    [0]=> 
    array(7) { 
    ["file"]=> 
    string(15) "C:\php\test.php" 
    ["line"]=> 
    int(24) 
    ["function"]=> 
    string(5) "check" 
    ["class"]=> 
    string(3) "Foo" 
    ["object"]=> 
    object(Foo)#1 (0) { 
    } 
    ["type"]=> 
    string(2) "->" 
    ["args"]=> 
    array(0) { 
    } 
    } 
} 
array(2) { 
    [0]=> 
    array(7) { 
    ["file"]=> 
    string(15) "C:\php\test.php" 
    ["line"]=> 
    int(18) 
    ["function"]=> 
    string(5) "check" 
    ["class"]=> 
    string(3) "Foo" 
    ["object"]=> 
    object(Foo)#1 (0) { 
    } 
    ["type"]=> 
    string(2) "->" 
    ["args"]=> 
    array(0) { 
    } 
    } 
    [1]=> 
    array(7) { 
    ["file"]=> 
    string(15) "C:\php\test.php" 
    ["line"]=> 
    int(26) 
    ["function"]=> 
    string(9) "callCheck" 
    ["class"]=> 
    string(3) "Foo" 
    ["object"]=> 
    object(Foo)#1 (0) { 
    } 
    ["type"]=> 
    string(2) "->" 
    ["args"]=> 
    array(0) { 
    } 
    } 
} 
+0

我已經嘗試過這個,但它一直保持真實?也許你可以幫助我在選擇算法?我想在回溯中只返回1個堆棧而不是2個。我想說的是,誰叫check();不是誰叫callCheck();然後調用check();我找不到一個可靠的方法來做到這一點,我正在研究runkit擴展,也許我會玩這個,看看我是否可以用不同的方法實現相同的目標。乾杯! – 2011-03-25 12:32:06

+0

在數組(1)中,只有一個元素,表示「check()」是由其自身調用的,即外部調用。在數組(2)中,裏面有2個子數組,而check()是最上面的數組,這表明「check()」被其他函數調用,檢查函數我們發現函數來自同一個類, check()「屬於,所以這意味着,」check()「被稱爲內部 – anru 2011-03-26 10:15:48

+0

所以算法是:如果數組中有一個元素,它是一個外部調用。如果不止一個,檢查下一個元素,如果下一個元素與「check()」具有相同的類,則是內部調用,如果類diff,external call。 – anru 2011-03-26 10:24:16