【问题标题】:PHP: is current function running inside an object?PHP:当前函数是否在对象内运行?
【发布时间】:2017-11-03 15:28:52
【问题描述】:

PHP 中有什么方法可以判断一个函数是从特定对象类的内部还是外部运行的?

function getToDaChoppa() {
    if( "we're inside the Choppa object" ) {
        $foo = "We're inside";
    } else {
        $foo = "We're outside";
    }
    echo $foo;
}

class Choppa() {
    public function getStatus() {
        getToDaChoppa();
    }
}

跑步:

getToDaChoppa();
( new Choppa )->getStatus();

应该回显:

我们在外面

我们在里面

【问题讨论】:

  • __CLASS__ 将在后一种情况下设置。
  • get_class($this) 返回什么?
  • 等等,我撒了谎。 __CLASS__ 只为在类内部定义的函数设置。你是从班级内部调用全局变量吗?
  • 我认为这是一个完全有效的问题。听到解决方案同样有趣,因为在我多年的编码工作中,我从来没有做过这样的事情:)
  • 从一个类中调用一个全局函数不会传递任何关于调用它的类的信息——你需要使用debug_backtrace或类似的方法来找出函数被调用的位置。或者,将实例作为$context 变量传递给函数。

标签: php object scope


【解决方案1】:

它自己的函数不知道它是否是从一个类中调用的,这是有充分理由的。如果函数的行为不同,那将导致代码非常难以维护和调试困难等。

如果你需要调用函数并且可能会问,如果这个函数属于一个类/获取实例,唯一的方法是debug_backtrace。但总的来说,你真的只应该这样做,用于调试代码(顾名思义)。

通常情况下,您只需为每种情况设置两个函数,或者传递一个参数,该参数存储所需的信息。

【讨论】:

    【解决方案2】:

    您始终可以在默认值之上传递该类的实例,然后在返回 get_class() 时进行评估。

    function getToDaChoppa($that = false) {
        $class = $that ? get_class($that) : '';
        if($class == "Choppa") {
            $foo = "We're inside";
        } else {
            $foo = "We're outside";
        }
        echo $foo;
    }
    
    class Choppa {
        public function getStatus() {
            getToDaChoppa($this);
        }
    }
    
    
    getToDaChoppa(); // Would return "We're outside" 
    ( new Choppa )->getStatus(); // Would return "We're inside"
    

    有关工作示例,请参阅 https://ideone.com/WWg1Hl

    【讨论】:

      【解决方案3】:

      您可以使用debug_backtrace(),返回一跳,然后检查它是否是在类中生成的。我不确定我是否会在生产中这样做......

      function getToDaChoppa() {
          $bt = debug_backtrace();
          if (isset($bt[1]) && array_key_exists('class', $bt[1])) {
              echo "called from class\n";
          } else {
              echo "called directly\n";
          }
      }
      

      澄清:如果您希望它仅针对一个特定类触发:

      function getToDaChoppa() {
          $bt = debug_backtrace();
          if (
              isset($bt[1]) &&
              array_key_exists('class', $bt[1]) &&
              $bt[1]['class'] === 'Choppa'
          ) {
              echo "called from class Choppa\n";
          } else {
              echo "called otherwise\n";
          }
      }
      

      【讨论】:

      • 如果它是从与Choppa 不同的类中调用的,这不会也返回"called from class" 吗?
      • 它将触发任何类。如果您希望它仅针对一个特定类触发,只需检查 $bt[1]['class'] 的值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-27
      相关资源
      最近更新 更多