2013-02-15 82 views
2

我正試圖找出某個對象的某個屬性被修改的位置。由於PHP的高度動態性($o->$prop = $val等),通過簡單的代碼分析實際上不可能做到這一點。有沒有辦法啓動一個調試會話,並在屬性被修改的那一行中斷? (增加一個魔術__set和一個有條件的xdebug_break()對這個類的調用可能有助於簡單的情況,但是如果這個類或它的祖先已經有一個魔法設置器,它可能會變得非常複雜,所以這也不是一個好的解決方案。)Xdebug中的屬性更改打破

回答

6

按照Xdebug的文檔另一個驚人的原因,好像有應該是打破對變量變化的一種方式。 http://xdebug.org/docs-dbgp.php#breakpoints

手錶:由 表達式參數

但源代碼中定義的變量或地址的寫入斷點指示該文件是超前的實際功能: 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的的bug跟蹤系統的bug:

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

+0

已解決鏈接的xdebug問題,解決方案「無法解決」。我在https://bugs.php.net/bug.php?id=75659&thanks=4創建了新的錯誤報告 – gadelat 2017-12-09 17:22:44

6

聲明您試圖調試的屬性爲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 :)

+0

正如我在這個問題的最後說,這是很辛苦,如果對象已經具有複雜了自己的二傳手邏輯。 (當然,'非常努力'仍然比'不可能'更好。) – Tgr 2013-02-15 18:30:27

+0

不明白爲什麼這很難?如果你的對象已經有一個'__set'方法,爲什麼你不能檢查哪個變量是'__set'並打破它是你想要的?不管那裏有什麼?也許如果你展示了你的魔法'__set'方法,我們可以提供幫助。附註:你在你的問題中提到了魔術吸氣劑,而不是魔術吸氣劑。 – 2013-02-15 18:31:38

+0

這是一個錯字(現在修復,謝謝)。問題在於對象的setter本身可能會將對'$ o-> foo'的訪問轉換爲對'$ o :: _ foo'的訪問(或者做比這更復雜的事情)。通常我會遇到這個問題,使用框架對象(在這個特殊情況下是'Zend_Navigation_Page'),它經常有非常複雜的初始化邏輯。 – Tgr 2013-02-15 18:36:27