【问题标题】:Find where a variable is defined in PHP (And/or SMARTY)?查找在 PHP(和/或 SMARTY)中定义变量的位置?
【发布时间】:2010-06-04 00:47:24
【问题描述】:

我目前正在处理一个非常大的项目,并且承受着很快完成它的巨大压力,而且我遇到了一个严重的问题。以一种非常奇怪的方式编写最后一个定义变量的程序员 - 配置变量并不都在同一个文件中,它们分布在整个项目的 500 多个文件和 100k+ 行代码中,我有找出某个变量的位置真是费时费力,所以我可以解决一个问题。
有没有办法追踪这个变量?我相信他正在使用 SMARTY(由于此类问题,我无法忍受),并且该变量是模板变量。我相当确定我正在寻找的变量最初被定义为 PHP 变量,然后该变量被传递给 SMARTY,所以我想追踪 PHP 变量,但是如果那不可能 - 我该如何追踪他在哪里为 SMARTY 定义了变量?

附:我在 Vista 中,并且没有 ssh 访问服务器的权限,所以 'grep' 是不可能的。

【问题讨论】:

  • +1 表示不喜欢 Smarty。虽然我自己不使用它们,但我认为 php-debugger 和 xdebug 都可以回溯外部范围内的变量/内容或至少所有现有变量。无论如何,我已经为你的 Vista 和调试情况点燃了同情的蜡烛。

标签: php variables smarty definition


【解决方案1】:

蛮力方式,因为有时 smarty 变量不是直接分配的,但它们的名称可以存储在变量中,由许多字符串连接或某些函数的结果,这使得通过简单的搜索/greping 无法在文件中找到。

首先,编写你自己的函数来打印可读的回溯,即:

function print_backtrace()
{
    $backtrace = debug_backtrace(FALSE);
    foreach($backtrace as $trace)
        echo "{$trace['file']} :: {$trace['line']}<br>";
}

打开 smarty 主文件(默认为Smarty.class.php),在第 580 行附近有一个名为 assign 的函数。修改它以查看所需的变量名称:

function assign($tpl_var, $value = null)
{
    if($tpl_var == 'FOOBAR') /* Searching for FOOBAR */
    {
        print_backtrace();
        exit;
    }

第二个函数可能需要相同的修改 - assign_by_ref。现在运行脚本后你应该有这样的输出:

D:\www\test_proj\libs\smarty\Smarty.class.php :: 584
D:\www\test_proj\classes.php :: 11
D:\www\test_proj\classes.php :: 6
D:\www\test_proj\functions.php :: 7
D:\www\test_proj\index.php :: 100

第二行指向变量第一次被赋值的地方。

【讨论】:

  • 谢谢,这是个好主意 - 我肯定会保存这段代码以备将来调试,但我最终只使用了 grep,如下所示。
  • 这可能与 SMARTY 一起工作得很好,但它似乎并没有说明文件中的特定变量最初在 PHP 中定义的位置。我认为 debug_backtrace 和/或 Reflection 可以找到,但我没有看到这里引用的方式。
【解决方案2】:

这类事情是我在所有 Windows 机器上安装 Cygwin 的第一大原因。

grep myvariablename `find project_dir -name "*.php"`

如果没有工作的grep,我无法想象编程。

【讨论】:

  • 神圣的烟雾看起来棒极了。现在到处从 CPAN 安装。
  • 嘿,我已经使用 ack 几个星期了,我喜欢它。再次感谢查尔斯!
  • @AlxVallejo 在意大利面条 PHP 中很难,但您可以尝试使用 ack '^\s*\$image\s*=' 之类的东西查找所有赋值语句
  • 嗨@Nathan,我即将在Win8 上安装Cygwin,但我不知道我必须安装哪个包才能实现此目的。你能知道哪个是一个(或多个)吗?
  • @CliffBurton 这是关于 Cygwin 的令人困惑的事情之一......但是有一个 grep 包。还要比较银牌搜索者。祝你好运。
【解决方案3】:

还有一个有趣的选项,虽然丑得要命,但如果你真的迷路了,它会很有帮助。

如果您想知道THE_NAME 的定义位置,请在您确定首先运行的地方写下这样的行:

error_reporting(E_ALL);
define('THE_NAME', 'Chuck Norris');

如果以后 PHP 会运行你正在寻找的定义,它会写一个这样的通知:

Notice: Constant THE_NAME already defined 
in /home/there/can-rip-a-page-out-of-facebook.com/SomeConfiguration.php on line 89 

那么你知道你正在寻找的定义在文件SomeConfiguration.php的第89行。

要让这个工作,你必须考虑

  • 如果框架中有 HTTP 转发到您设置的代码的途中
  • 如果还有设置PHP报错模式的命令

所以有时添加一些exit('here') 会有所帮助,以免使输出模糊。也许你必须缩小一点,或者你必须更早地设置error_reporting,但你会找到它。

【讨论】:

  • 希望它有所帮助,无论它多么丑陋:-)::)
【解决方案4】:

这不是一个完美的解决方案,但我发现agent ransack 对于搜索大型目录和文件很有用。可能会帮助您缩小范围。搜索结果将允许您阅读在结果窗格中找到匹配项的确切行。

【讨论】:

    【解决方案5】:

    如果您使用netbeans editor,只需“右键单击”->“转到定义”

    ctrl + click 变量。

    如果编辑器无法确定,您可以退回到“在文件中查找”选项。

    【讨论】:

    • Eclipse 和 PHPStorm 有类似的功能。
    【解决方案6】:

    只需使用可用的 PHP IDE 之一(如果您真的很绝望,也可以使用像 Notepad++ 这样的简单文本编辑器)并在所有源文件中搜索变量的名称(大多数 PHP IDE 还支持查找函数/变量的位置定义并允许您跳转到相关的代码段)。尽管您不知道哪段代码调用了模板似乎很奇怪(无论是 Smarty 还是其他任何东西都无关紧要)。您应该能够从 URI 开始深入研究代码(使用任何支持调试的 IDE),因为这样您一定会看到所述变量的定义位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多