是否可以限制在PHP中调用方法的方式?

时间:2010-06-16 14:50:15

标签: php scope methods

鉴于我的班级看起来像这样:

class Methods{
    function a(){
        return 'a';
    }

    function b(){  
        $this->a();   
    }

    function c(){ 
        $this->a();
    }  
}

是否有可能确保函数a 只能从函数b中调用

在上面的示例中,函数c应该失败。我可以将它包含在函数b中,但将来我可能希望让一些新函数调用a()(例如d()或e ()

6 个答案:

答案 0 :(得分:8)

首先要了解public, private and protected方法之间的区别......在想要做一些非常复杂的事情之前,至少要掌握一些OOP基础知识是有用的。 是的,可以使用debug_backtrace()来识别对方法的调用的位置;但这是一个非常大的开销....我认为实际设置这样的限制没有任何价值。

答案 1 :(得分:2)

您应首先查看类可见性修饰符,例如Mark Ba​​ker建议的那样。这可能就是你要找的东西。

但是,如果不是,则以下代码适合您:

class Methods
{
    private function a()
    {
        $bt = debug_backtrace();
        if(!isset($bt[1]) || $bt[1]['function'] != 'b' || $bt[1]['class'] != get_class($this))
        {
            //Call not allowed
            return NULL;
        }
    }
    function b()
    {
        //allowed
        $this->a();
    }
    function c()
    {
        //not allowed
        $this->a();
    }
}

答案 2 :(得分:1)

与您要求的最接近的是 要限制的方法。在它们定义的方法之外无法访问闭包。这些闭包通常用于定义回调并传递给其他方法,但您可以直接调用它。

class Methods{
  function b(){
    $a = function() {
      return 'a';
    }; // don't forget the trailing ';'

    $a();   
  }

  function c(){ 
    $this->a(); // fails
  }  
}

使方法私有受保护将阻止从类外部调用它,但不会限制类中的哪些方法可以访问它。在某种程度上,您需要信任您的代码,以遵循API的使用规则。

类通常是信任的单元封装,如果您从外部使用私有方法并将其记录下来,那么您应该能够相信它在类中正确使用。如果没有,也许那个班级太大了,是时候重构了。

正如@Sjoerd所提到的那样,你也可以检查一下调用堆栈,但是同意@Mark Ba​​ker的观点,认为它几乎没有价值;它类似于滥用语言并使你的代码变得混乱。

答案 3 :(得分:0)

不是真的。

  • 您可以通过查看debug_backtrace()
  • 的结果来查看来电者
  • 您可以将其设为私有,以避免从课外调用,然后将c()移到课堂外。

答案 4 :(得分:0)

我认为限制同一类内的方法调用其他方法没有意义。

也许你的模型是错的,你必须创建两个类?一个类应该是一个逻辑单元(不知何故)。

如果您使用单独的类,则可以使用方法a上的private keyword,并且无法再从类外部调用它。

答案 5 :(得分:0)

以下内容可能适用于您的问题。

class First {
    public function a() {
        $second = new Second();

        // Works in this context!
        $second->b($this);
    }
}

class Second {
    public function b($context) {
        if (!$context instanceof First)
            throw new Exception('Can only be called from context of "First".');
        echo 'b';
    }
}

class Third {
    public function c() {
        $second = new Second();

        // Doesn't work out of context.
        $second->b($this);
    }
}

警告这不会阻止Third调用该方法,因为它可以提供对Second实例的引用。但它确实使这个过程更加严格,你的文档可以用这种方式表明它的工作原理。

也许这会有用,它似乎适用于我很好的类似问题。