4

是否有可能在 Emacs 的 PHP 文件中识别未使用的变量?

对于其他语言,这可以通过使用Flymake等工具来实现。

我已经启用 Flymake 来动态显示我的 PHP 文件语法错误,但仍然令人沮丧的是,PHP 逻辑错误有时是由于以下情况引起的:

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

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

在Pascal 和 viam0Zah的提示之后,我在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
(require '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

3 回答 3

5

这并不是您问题的真正答案,因为它在 Emacs 中不起作用,但是当您尝试从未初始化的变量中读取时,PHP 会引起注意。

有关更多信息,请参阅:


例如,将 error_reporting 设置为报告 E_NOTICE(和其他),以下代码部分:
$aa = 'glop';
echo strlen($a);

发出此通知:

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

我承认,这并不像在你的编辑器中那样简单——但它仍然有助于找出为什么某些东西不起作用;-)

于 2010-03-28T19:27:37.673 回答
2

由于 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的函数而不是原来的函数。所以它起作用了:


(来源:flickr.com

于 2010-03-29T09:24:25.430 回答
-4

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

这应该会大大减少您拼错变量名的次数。它还允许您的变量名称比$foo


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

于 2010-03-28T19:26:39.987 回答