识别PHP未使用的变量(在Emacs中)?

时间:2010-03-28 19:23:49

标签: php emacs flymake

以某种方式可以在Emacs中的PHP文件中识别未使用的变量吗?

使用其他语言,可以使用 flymake 等工具。 我已经启用了Flymake来显示我的PHP文件动态的语法错误,但仍然令人沮丧的是,PHP逻辑错误有时是由于以下情况造成的:

<?php
$foo = whatever();
$bar = something($fo);
...

请注意$ foo上的拼写错误,这会导致开发人员的头痛和过度使用咖啡。

更新

在Pascal和Gabor的提示之后,我设置了我的php.ini:

error_reporting = E_ALL | E_STRICT

当我从命令行运行php时,我现在能够看到有关未定义变量的通知(带或不带-l选项):

> php -r '$foo = 3; echo $fo;'
PHP Notice:  Undefined variable: fo in Command line code on line 1
> php -r '$foo = 3; echo $fo;' -l
PHP Notice:  Undefined variable: fo in Command line code on line 1

这就是我目前在.emacs中使用的内容。它可以很好地处理解析错误,但我仍然无法在通知上匹配,但是:(

;; FlyMake for Php (需要'flymake)

(defun flymake-php-init ()
  "Use php to check the syntax of the current file."
  (let* ((temp (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace))
     (local (file-relative-name temp (file-name-directory buffer-file-name))))
    (list "php" (list "-f" local "-l"))))

(add-to-list 'flymake-err-line-patterns
             '("\\(Parse\\|Fatal\\) error: +\\(.*?\\) in \\(.*?\\) on line \\([0-9]+\\)$" 3 4 nil 2))

(add-to-list 'flymake-err-line-patterns
               '("Notice: \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)" 2 3 nil 1))

(add-to-list 'flymake-allowed-file-name-masks '("\\.php$" flymake-php-init))

我也尝试过Gabor的配置。结果相同。很好的错误,通知不好。

请注意,从命令行,解析错误如下所示:

> php -r '$fo o = 3; echo $fo;' -l
PHP Parse error:  syntax error, unexpected T_STRING in Command line code on line 1

我不明白为什么通知不匹配。我已经单独尝试了正则表达式,它似乎正确匹配:

(search-forward-regexp "Notice: \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)")

PHP Notice:  Undefined variable: fo in Command line code on line 1

C-x C-e将跳到行尾。)

最后,我暂时禁用了XDebug,因为这些通知最初报告为:

PHP Notice:  Undefined variable: fo in Command line code on line 1
PHP Stack trace:
PHP   1. {main}() Command line code:0

所以,我想我应该稍微更改正则表达式以匹配多行错误。有关于此的任何暗示吗?

4 个答案:

答案 0 :(得分:5)

这不是你问题的答案,因为它不适用于emacs,但当你试图从一个尚未初始化的变量中读取时,PHP可以引发通知。

有关更多信息,请参阅:


例如,将error_reporting设置为报告E_NOTICE(和其他),代码的以下部分:

$aa = 'glop';
echo strlen($a);

提出此通知:

Notice: Undefined variable: a in /.../temp/temp.php on line 5

这并不像进入你的编辑那么简单,我承认 - 但仍然有助于找出原因不起作用的原因; - )

答案 1 :(得分:3)

由于Flymake使用php二进制语法检查选项(-l)来突出显示解析错误,因此没有明显的方法可以在不运行或词法解析代码的情况下捕获通知和其他错误。如果不仅仅是lint而且执行你的脚本不是问题,那么你可以执行以下操作。

不幸的是,flymake-php将错误行模式定义为常量(至少在Emacs Starter Kit附带的包中),甚至flymake命令也是硬编码的。有几种方法可以实现我们的目标,每种方法都是痛苦的。可能是基于原始函数定义我们的flymake-php-init函数的快速且不那么脏的解决方案。

(defun my-flymake-php-init ()
  ;; add a new error pattern to catch notices
  (add-to-list 'flymake-err-line-patterns
               '("\\(Notice\\): \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)"
                 3 4 nil 2))
  (let* ((temp-file (flymake-init-create-temp-buffer-copy
                     'flymake-create-temp-inplace))
         (local-file  (file-relative-name
                       temp-file
                       (file-name-directory buffer-file-name))))
    ;; here we removed the "-l" switch
    (list "php" (list "-f" local-file))))

然后自定义flymake-allowed-php-file-name-masks以使用my-flymake-php-init函数初始化flymake-php而不是原始的。它起作用了:

答案 2 :(得分:1)

有点迟到的答案,但我已经详细介绍了如何将Emacs Flymake与PHP_CodeSniffer以及PHP_CodeSniffer-VariableAnalysis插件连接起来,该插件在此博客中添加了未使用的变量警告(以及未定义的变量警告):

http://www.illusori.co.uk/perl/2011/07/25/perl_php_static_analysis_with_emacs_flymake.html

作为将各种各样的东西粘合在一起的各种各样的作者意味着我有点偏向于认为它运作良好,但我经常使用它来工作并且它可以解决问题。

此方法通过静态分析源而不是运行程序来工作,如果您想避免意外的副作用,这非常有用......

答案 3 :(得分:-4)

当您通过Intellisense输入时,体面IDE将为您提供当前范围内变量的名称。

这应该会严重削减拼写变量名称的次数。它还允许您的变量名称比$foo

更具描述性

此外,您应该始终注意未定义的变量警告,因为它们会在您拼写错误时立即告诉您。