5

我试图找出某个对象的某个属性在哪里被修改。由于 PHP 的高度动态性($o->$prop = $val等等),这实际上是不可能通过简单的代码分析来完成的。有没有办法启动调试会话并在属性被修改的行中断?__set(通过对类的条件调用添加一个魔法xdebug_break()可能在简单的情况下会有所帮助,但如果该类或其祖先之一已经有一个魔法设置器,它可能会变得非常复杂,所以这也不是一个好的解决方案。)

4

2 回答 2

11

根据 xdebug 文档,似乎应该有一种方法可以中断变量更改。 http://xdebug.org/docs-dbgp.php#breakpoints

watch:在写入由表达式参数定义的变量或地址时中断

但源代码表明文档领先于其实际功能: https ://github.com/xdebug/xdebug/blob/master/xdebug_handler_dbgp.c#L875

if (strcmp(CMD_OPTION('t'), "watch") == 0) {
        RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_BREAKPOINT_TYPE_NOT_SUPPORTED);
    }

我实际上无法在 repo 的其他任何地方找到字符串“watch”,所以我的假设是它目前不受支持。

Xdebug 的错误跟踪器中似乎存在错误:

http://bugs.xdebug.org/view.php?id=514

于 2014-04-01T06:05:11.187 回答
7

将您尝试调试的属性声明为private,并创建一个__set方法。在其中,您将能够找到答案。

class subject extends something {
    private $field;

    public function __set($key, $value) {
        if ($key == 'field') {
            debug_print_backtrace(); exit;
        }

        if (method_exists(get_parent_class($this), '__set')) {
            return parent::__set($key, $value);
        }

        return $this->$key = $value;
    }
}

编辑:这是 getter 和 setter 的另一个惊人原因:)

于 2013-02-15T18:19:30.093 回答