Emacs and PHP: On-the-fly syntax checking with Flymake
Posted: - Modified: | emacsThe dreaded white screen of nothingness usually means that I’ve misplaced a quotation mark or brace somewhere in my PHP code. On-the-fly syntax checking in Eclipse helped me find those errors quickly because I could scan the right scrollbar for areas marked with red. I knew that shifting to Emacs wouldn’t automatically cure me of the propensity to mismatch my parentheses. If I could get on-the-fly syntax checking working in Emacs, I’d save myself a lot of time.
It took me a while to sort out various configuration problems. Most were due to the fact that PHP didn’t report parse errors with my original configuration, even though I had uncommented the line after “Show only errors”. As it turned out, the error_reporting option in php.ini needs to include E_PARSE in order for php to report parsing error details. Here’s the value I’m currently using in /etc/php.ini:
error_reporting = E_ERROR|E_COMPILE_ERROR|E_CORE_ERROR|E_PARSE
Flymake is the package responsible for on-the-fly syntax checking in Emacs. Out of the box, it supports C, C++, XML, XHTML, Perl, Java, TeX, and IDL. To load Flymake and add support for PHP, add the following to your ~/.emacs:
(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-allowed-file-name-masks '("\\.php$" flymake-php-init)) ;; Drupal-type extensions (add-to-list 'flymake-allowed-file-name-masks '("\\.module$" flymake-php-init)) (add-to-list 'flymake-allowed-file-name-masks '("\\.install$" flymake-php-init)) (add-to-list 'flymake-allowed-file-name-masks '("\\.inc$" flymake-php-init)) (add-to-list 'flymake-allowed-file-name-masks '("\\.engine$" flymake-php-init)) (add-hook 'php-mode-hook (lambda () (flymake-mode 1))) (define-key php-mode-map '[M-S-up] 'flymake-goto-prev-error) (define-key php-mode-map '[M-S-down] 'flymake-goto-next-error)
Evaluate that code, open one of your PHP files, and intentionally break it. The syntax error should be highlighted. To change the highlighting, move your point to the error and type M-x customize-face. Accept the default (flymake-errline), then customize it as desired. Don’t forget to save your customizations for future sessions.
If your syntax errors are not highlighted and you get a message like this:
Configuration error occured while running (php -f test_flymake.php -l). flymake will be switched OFF
double-check your /etc/php.ini to make sure that E_PARSE is included as one of the options for error_reporting. You can check the output by running php -f yourfile.php -l. You should see the line number of the parse error. Make sure that this matches the regular expression added to flymake-err-line-patterns in your ~/.emacs. If your PHP returns a slightly different message, modify your flymake-err-line-patterns accordingly.
Flymake can save you a lot of programmer frustration for the cost of a little CPU time. Use it to check for errors before you save files or commit them to your source code control repository, and you and other developers will be much happier.
(UPDATE: Fixed typo in flymake-php-init)
4 comments
Jake
2010-04-08T22:17:06ZEmacs 23's flymake now includes support for php. You should be able to get the proper effect with:
(require 'flymake)
(add-hook 'php-mode-hook (lambda() (flymake-mode 1)))
(define-key php-mode-map '[M-S-up] 'flymake-goto-prev-error)
(define-key php-mode-map '[M-S-down] 'flymake-goto-next-error)
Jason Murray
2010-11-22T07:04:04ZNice post, this was one of the missing features that prevented me from moving from Eclipse PDT to Emacs full time for development.
Dave Cohen
2011-06-13T21:24:34ZSacha,
Thanks for sharing. While the comments are correct that flymake-php-init is already defined in my version of emacs. I still copied your Drupal-type file extensions and that's what I needed to get it working for my drupal files.
Now on my wish list is to run Drupal's coder module in emacs' compile mode. Is there an elisp expert out there who can tackle that?
-Dave
slink
2011-06-14T11:08:54Z@Dave: how do you invoke the Coder module? Do you run it via drush? Typing `M-x compile` allows you to specify the compile command to run that can be any drush command as well.