【问题标题】:Is it possible to restrict how a method can be called in PHP?是否可以限制如何在 PHP 中调用方法?
【发布时间】:2010-06-16 14:50:14
【问题描述】:

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

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

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

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

是否可以保证函数a只能被函数b调用

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

【问题讨论】:

  • 否(不包括丑陋的黑客)。你为什么要那样做呢?你想完成什么?
  • 好的,我会采取另一条路线,因为普遍的共识是这个想法很糟糕......
  • 如果c() 不应该调用a() 不要在c() 中调用它

标签: php scope methods


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您应该首先查看类可见性修饰符,就像 Mark Ba​​ker 所建议的那样。这可能就是您要寻找的。​​p>

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

    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();
        }
    }
    

    【讨论】:

      【解决方案3】:

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

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

      将方法设置为 privateprotected 将阻止从类外部调用它,但不会限制类内的哪些方法可以访问它。在某种程度上,您需要相信您的代码会遵守 API 的使用规则。

      类通常是信任的单元封装,如果您将方法设为私有,不让外部使用,并记录它,您应该能够相信它在类内被正确使用。如果没有,可能这个类已经太大了,是时候重构了。

      正如@Sjoerd 提到的,您还可以检查调用堆栈,但同意@Mark Ba​​ker 的观点,即这几乎没有价值;这类似于滥用语言并使您的代码也变得一团糟。

      【讨论】:

        【解决方案4】:

        不是真的。

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

        【讨论】:

          【解决方案5】:

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

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

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

          【讨论】:

            【解决方案6】:

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

            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 实例的引用。但它确实使流程更加严格,您的文档可以说明为什么它会以这种方式工作。

            也许这会有用,它似乎适用于我非常擅长的类似问题。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-12-28
              • 2012-09-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多