2011-03-25 52 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