【问题标题】:PHP how to detect the change of variable?PHP如何检测变量的变化?
【发布时间】:2013-07-06 18:12:20
【问题描述】:

PHP 是否存在检测变量变化的函数? 是这样的:

//called when $a is changed.
function variableChanged($value) {
    echo "value changed to " . $value;
}

$a = 1;
//attach the variable to the method.
$a.attachTo("variableChanged");
$a = 2;
$a = 3;

//expected output:
//value changed to 2
//value changed to 3

我知道如果我使用“setter”方法很容易实现。但由于我正在处理一些现有代码,我无法修改它们。有人可以告诉我如何实现我的目的吗?谢谢。

【问题讨论】:

  • 简短的回答是这是不可能的(调试器除外)。你的用例是什么,为什么需要这个?
  • PHP 执行是线性的,不是基于事件的,所以我认为你不能这样做。
  • 在大多数情况下,这是一件非常特殊的事情。
  • 这在我看来像是XY problem 的一个实例。
  • @DanFromGermany 当然,但有什么意义呢? OP 似乎需要的一个调试器。

标签: php


【解决方案1】:

知道如果我使用“setter”方法很容易实现。但由于我正在处理一些现有代码,我无法修改它们。

我假设您可以更改一些代码,但不能更改您正在使用的对象/类。如果您根本无法更改任何代码,那么这个问题将毫无用处。

您可以做的是创建自己的类,扩展您正在使用的类,并在那里添加您的设置器。出于所有目的,您不能覆盖父设置,除了您需要跟踪的任何内容的魔术设置器。跟踪更改,然后调用父函数,因此任何其他内部工作的更改都不会生效。

【讨论】:

    【解决方案2】:

    这只能通过将变量包装在一个类中并自己实现 onchange 来实现。

    即。

    class MyVarContainer {
        var $internalVar = array();
    
        function __get($name) {
            return !empty($this->internalVar[$name]) $this->internalVar[$name] ? FALSE;
        }
    
        function __set($name, $value) {
           $oldval = $this->$name;
           $this->internalVar[$name] = $value;
    
           if($oldval !== FALSE) {
              onUpdated($name, $oldval, $value);
           } else {
              onCreated($name, $value);
           }
        }
    
        function onCreated($name, $value) {
    
        }
    
        function onUpdated($name, $oldvalue, $newvalue) {
    
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可以像这样简单地修改您的代码,以产生您想要的预期输出。

      function variableChanged($value) {
          return "value changed to " . $value;
          }
      
          $a = 1;
      
          echo $a = variableChanged(2);
          echo '<br/>';
          echo $a = variablechanged(3);
      
      =================
      //output
      value changed to 2
      value changed to 3
      

      或者使用这样的类....

      class VariableHandler{
      
              private $Variable;
      
      
              function setVariable($initialValue = NULL){
                  $this->Variable = $initialValue;
                  return $initialValue;
              }
      
              function changeValue($newValue = NULL){
                  $this->Variable = $newValue;
                  return "value has change to ". $newValue;
              }
      
      
          }
      
          $var = new VariableHandler;
      
          echo $a = $var->setVariable(1);
          echo '<br/>';
          echo $var->changeValue(2);
          echo '<br/>';
          echo $var->changeValue(3);
      
       =================
          //output
          value changed to 2
          value changed to 3
      

      【讨论】:

        【解决方案4】:

        除了使用debugger:

        SplObserver 接口与 SplSubject 一起使用来实现 观察者设计模式。 http://www.php.net/manual/en/class.splobserver.php

        或者魔术方法__get()__set():将变量封装到一个类中,您可以自己实现一个事件处理程序并注册变量的更改。 你也可以像这里一样附加回调

        <?php
        header("content-type: text/plain");
        
        class WatchVar {
            private $data = array();
            private $org = array();
            private $callbacks = array();
        
            public function __set($name, $value) {
                if (!array_key_exists($name, $this->data)) {
                    $this->org[$name] = $value;
                } else {
                    //variable gets changed again!
                    $this->triggerChangedEvent($name, $value);
                }
                $this->data[$name] = $value;
            }
        
            public function &__get($name) {
                if (array_key_exists($name, $this->data)) {
                    if ($this->data[$name] != $this->org[$name]) {
                        //variable has changed, return original
                        //return $this->org[$name];
                        //or return new state:
                        return $this->data[$name];
                    } else {
                        //variable has not changed
                        return $this->data[$name];
                    }
                }
            }
        
            public function addCallback($name, $lambdaFunc) {
                $this->callbacks[$name] = $lambdaFunc;
            }
        
            protected function triggerChangedEvent($name, $value) {
                //$this->data[$name] has been changed!
                //callback call like:
                call_user_func($this->callbacks[$name], $value);
            }
        }
        
        
        $test = new WatchVar;
        $test->addCallback('xxx', function($newValue) { echo "xxx has changed to {$newValue}\n"; });
        $test->xxx = "aaa";
        
        echo $test->xxx . "\n";
        //output: aaa
        
        $test->xxx = "bbb";
        //output: xxx has changed to bbb
        
        echo $test->xxx . "\n";
        //output bbb
        
        function messyFunction(&$var) {
            $var = "test";
        }
        
        messyFunction($test->xxx);
        //output:
        

        【讨论】:

          【解决方案5】:

          下载这个文件 click to download

          我创造了这个

          将我的文件包含到您的 php 文件中

          require_once("k_dev.php");
          

          如果你使用 wordpress

          $is_wp = true;
          

          如果你不使用 wordpress

          $is_wp = false;
          

          如果你创建或设置一个变量,添加

          changed_var($VAR_NAME);
          

          在这个变量之后。

          示例:

          require_once("k_dev.php");
          
          $is_wp = false;
          
          $var1 = "test";
          changed_var($var1);
          $var1 = "test1";
          changed_var($var1);
          if(changed_var($var1) == true){
              echo "it's changed";
          }
          

          我是 Khaled 开发人员

          【讨论】:

            猜你喜欢
            • 2017-06-12
            • 1970-01-01
            • 2017-02-25
            • 1970-01-01
            • 1970-01-01
            • 2011-11-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多