5067 comments
2220 subscribers
4799 on Twitter
Subscribe! Feed reader E-mail

Emacs and PHP tutorial: php-mode

php-mode is responsible for syntax highlighting, indentation, and other major PHP-specific modifications to your editing environment. There are a number of PHP modes available for Emacs. In this project, you’ll learn how to set up the php-mode available from http://sourceforge.net/projects/php-mode/ . At the time of this writing, the current version is 1.4.0 and the maintainer is Aaron Hawley.

Download the latest php-mode.el from http://php-mode.sourceforge.net/ and save it to a directory in your load-path. I like to organize my Emacs Lisp files in a directory called ~/elisp. To add PHP support to your Emacs, add the following lines to your ~/.emacs:

 (add-to-list 'load-path "~/elisp")
 (require 'php-mode)

This configures Emacs to automatically recognize files ending in “.php”, “.phps”, “.php3″, “.php4″, “.phtml”, and “.inc” as PHP files. To associate more extensions with PHP files, add lines like this example to your ~/.emacs:

 (add-to-list 'auto-mode-alist '("\\.module$" . php-mode))
 (add-to-list 'auto-mode-alist '("\\.inc$" . php-mode))
 (add-to-list 'auto-mode-alist '("\\.install$" . php-mode))
 (add-to-list 'auto-mode-alist '("\\.engine$" . php-mode))

This associates php-mode with the extensions used by Drupal, a PHP framework. When you open a file with the specified extension, it should be highlighted according to PHP syntax.

Here are some useful commands:

TAB c-indent-command Indent the current line
M-; comment-dwim Add a line comment, comments or uncomments the currently-selected region, or does other smart comment-related actions
C-c C-f php-search-documentation Search the online PHP manual for the current word
C-c RET php-browse-manual View the online PHP manual
C-c . c-set-style Change coding style
C-M-a, C-M-e c-beginning-of-defun, c-end-of-defun Go to the beginning or end of the current function
C-M-h c-mark-function Select the current function
M-a, M-e c-beginning-of-statement, c-end-of-statement Go to the beginning or end of the current statement

Here are some variables you may wish to customize:

indent-tabs-mode Set this to nil if you want to insert spaces instead of tabs
case-fold-search Set this to t if you want case-insensitive search.
c-basic-offset Set your tab size or number of spaces used as a basis for indentation

You can either customize these variables globally with M-x customize or set them for php-mode. Here’s an example that sets up a buffer with the coding style recommended for Drupal:

 (defun wicked/php-mode-init ()
   "Set some buffer-local variables."
   (setq case-fold-search t)
   (setq indent-tabs-mode nil)
   (setq fill-column 78)
   (setq c-basic-offset 2)
   (c-set-offset 'arglist-cont 0)
   (c-set-offset 'arglist-intro '+)
   (c-set-offset 'case-label 2)
   (c-set-offset 'arglist-close 0))
 (add-hook 'php-mode-hook 'wicked/php-mode-init)

You can further customize the indentation by moving the point to where the indentation needs improvement and typing C-c C-o (c-set-offset).

To try automatic indentation, press C-j (newline-and-indent). If you like that behavior, you can make it the default in php-mode by adding the following line in ~/.emacs:

(define-key php-mode-map (kbd “RET”) ‘newline-and-indent)

You may also be interested in M-x show-paren-mode, which shows the matching parenthesis, bracket or brace for the character at point. You can enable it automatically by adding the following line to your ~/.emacs:

   (setq show-paren-mode t)

It’s a good idea to separate PHP and HTML code. This is not only better coding practice, but it also makes developing in Emacs much easier. php-mode focuses on PHP-specific behavior and does not have special support for HTML. Emacs has a number of packages that allow you to work with multiple modes like php-mode and html-helper-mode in a single buffer, but they don’t always work, and indentation can be confusing. If you must work with large segments of both PHP and HTML in the same file, check out MultipleModes (http://www.emacswiki.org/cgi-bin/wiki/MultipleModes) for tips.

Short URL: http://sachachua.com/blog/p/5014

20 Responses to “Emacs and PHP tutorial: php-mode”

  1. php-mode is decent, but it has plenty of issues.

    C-M-h, for example, doesn’t understand OOP code. If you use it to mark a method in a class, it marks the entire class. Same goes for any of the other commands for dealing with functions, like beginning-of-defun & friends.

    I have a few custom functions and bindings:
    (defun terminate-line ()
    “Terminate the line with a semicolon, and prepare to start typing on the next line. A second semicolon will not be inserted if one is already present.
    If the line begins with `case,’ a colon will be inserted insead.”
    (interactive)

    (back-to-indentation)
    (if (looking-at “case”)
    (setq eol-char “:”)
    (setq eol-char “;”))

    (end-of-line)
    (if (not (looking-back eol-char))
    (insert eol-char))
    (reindent-then-newline-and-indent))

    (defun open-line-indent (n)
    “Insert a newline and leave point before it.
    If there is a fill prefix and/or a `left-margin’, insert them
    on the new line if the line would have been blank.
    Indent following line afterwards.
    With arg n, insert n newlines.”
    (interactive “*p”)
    (save-excursion
    (open-line n)
    (next-line n)
    (indent-according-to-mode)))

    (define-key php-mode-map “\r” ‘reindent-then-newline-and-indent)
    (define-key php-mode-map “\C-c\C-c” ‘comment-or-uncomment-region-or-line)
    (define-key php-mode-map “\M-;” ‘terminate-line)
    (define-key php-mode-map “\C-o” ‘open-line-indent)

    I turn php-mode-force-pear on, since I contribute to PEAR and follow their CS in all my code.

  2. I’ve added your terminate-line to my config. Thanks! =)

    For open-line-indent – open-line doesn’t seem to do things like add the * prefix for block comments. When do you tend to use it?

    In other news, I so have to figure out how to turn off smart quotes in WordPress…

  3. Hello.
    I have problem with install php mode for my emacs editor.
    I can`t find the directory .emacs, and i don`t now were I can put th php-mode.el.
    Could You help me to do that. I need the php mode, and emacs is my est editor.

  4. Hello, Andreu! Here’s what I’d suggest:

    1. Create a directory named elisp in your home directory (mkdir ~/elisp on Linux).
    2. Save php-mode.el to that directory, so you’ll have ~/elisp/php-mode.el.
    3. Create an ~/.emacs file if you don’t have one already. In the file, add
      (add-to-list 'load-path "~/elisp")
      (require 'php-mode)
      

    That should take care of most of it. Good luck and have fun!

  5. Hey Sacha,

    Is there any chance you could give instructions on how to setup php-mode on a windows install of emacs? :) emacs is my favorite editor, but i just don’t have a good linux box to program on right now, and i haven’t been able to figure out how to get this working in windows yet :(

    thanks!

  6. hey sacha,

    any chance you could give instructions on how to setup php-mode on a windows emacs install? it’s my favorite editor, but just don’t have access to a linux box right now, and haven’t been able to figure out how to get this to work in windows :(

    thanks!

  7. Step 1: Install VMware. Step 2: Install Ubuntu in a VM image… ;)

  8. @greg
    I found the answer to most my questions in this document. Chapter 3, “Installing Emacs” in particular. I used the register method and it worked fine.It makes it easy to emulate Unix behavior. Note that you need a newer version of Emacs (I tried 21.3 at first and that didn’t work) installed.

  9. I get the following error when I try to open emacs with the php-mode enabled:

    An error has occurred while loading `c:/.emacs’:

    Symbol’s function definition is void: c-lang-const

    It appears to be coming from lines 297-303 in the php-mode.el file:

    (defconst php-class-key
    (concat
    “\\(” (regexp-opt php-class-decl-kwds) “\\)\\s-+”
    (c-lang-const c-symbol-key c) ;; Class name.
    “\\(\\s-+extends\\s-+” (c-lang-const c-symbol-key c) “\\)?” ;; Name of superclass.
    “\\(\\s-+implements\\s-+[^{]+{\\)?”)) ;; List of any adopted protocols.

    Is there a dependency I’m missing?

  10. @martin:

    PHP mode depends on cc-mode; the error you report comes from using too old a version of cc-mode. It happened to me and I upgraded my cc-mode in a 21.2 emacs installation; cc-mode loaded fine, but then I got a different error when loading a php file. The quick fix was to just install a more recent emacs (22.3) and then add php mode to the new install.

  11. [...] Emacs está configurado para reconocer ciertas extensiones de archivo y abrir el modo correspondiente. Pero ¿cómo hacemos para indicarle que abra cierto tipo de archivo en cierto modo? Este artículo nos indica como. A pesar de que está hecho para PHP, es fácil adaptarlo para cualquier otro lenguaje. Emacs and PHP tutorial: php-mode [...]

  12. [...] See the article here: Emacs and PHP tutorial: php-mode » sacha chua :: enterprise 2.0 … [...]

  13. I don’t have a .emacs file.

    You mentioned to Andreu to create one, but I still don’t know where it needs to be created?

    My directory to php-mode is here
    C:\emacs-22.3\lisp\php-mode-1.5.0

    So where do i put the .emacs file?

  14. Hello,
    You have to put .emacs file i your home directory. When emacs start, he is searching for configuration file, first step is for looking in the home directory.

  15. I ‘ve copied ‘php-mode.el’ to ‘~/.emacs.d/site-lisp/php-mode.el’ (not ‘~/emacs.d’, I think so). And followed your suggestion, but when I start emacs, it shows this error:

    Warning (initialization): An error occurred while loading `/root/.emacs’:

    error: `c-lang-defconst’ must be used in a file

    To ensure normal operation, you should investigate and remove the
    cause of the error in your initialization file. Start Emacs with
    the `–debug-init’ option to view a complete error backtrace.

    So, I start Emacs with the ‘–debug-init’ (by gnome-terminal). It says:

    Debugger entered–Lisp error: (error “`c-lang-defconst’ must be used in a file”)
    signal(error (“`c-lang-defconst’ must be used in a file”))
    error(“`c-lang-defconst’ must be used in a file”)
    c-define-lang-constant(c-mode-menu ((t cons ["Comment Out Region" comment-region ...] (cons ["Uncomment Region" ... ...] …))))
    require(cc-langs)
    eval-buffer(#<buffer *load*> nil “/root/.emacs.d/site-lisp/php-mode.el” nil t) ; Reading at buffer position 4158
    load-with-code-conversion(“/root/.emacs.d/site-lisp/php-mode.el” “/root/.emacs.d/site-lisp/php-mode.el” nil t)
    require(php-mode)
    eval-buffer(# nil “/root/.emacs” nil t) ; Reading at buffer position 624
    load-with-code-conversion(“/root/.emacs” “/root/.emacs” t t)
    load(“~/.emacs” t t)
    #[nil “^H\205\264^@ . . . etc (I cannot fully paste this line)
    command-line()
    normal-top-level()

    I use Ubuntu 10.10.
    Could you help me with this bug

  16. Hi,
    As php-mode seems no longer maintained, I have forked it http://git.piprime.fr/?p=emacs/pi-php-mode.git;a=summary

  17. Hi Sacha,

    I tried with your steps, but was getting error.
    So I tried by removing (require ‘php-mode)

    And…… it worked……

  18. tanmay: Do you have php-model.el in a directory in your load-path?

  19. yup….
    may be that is why its working….

  20. Using php-mode.el, I encounter strange indenting.

    It seems that within an “if” block, delimited by curly brackets, each statement will normally be indented by one stop. But if within that block there is a foreach statement, that statement will be outdented by one stop, and the block it contains will be indented relative to the outdented foreach statement, so that it lines up with the contents of the “if” block. This makes the code hard to read (for me), and I wonder if the behavior is intentional, or if this is a bug.

    I know that “foreach” lines are delimited by colons, just like “case” statements in C, which are similarly outdented, by c-mode. Is this the reason? Am I the only one who finds that it obscures the logical flow?

    Perhaps more to the point, is there a way I can tweak this behavior?

    (I tried pasting in code (with “code” and “/code” tags), but judging by the preview, *all* the indents are removed.)

Comment, share a thought, ask a question...

Please comment as you, not your organization.





 

On This Day...

  • 2011: Mornings at our house — Neko and Leia have taken to meowing us awake in the morning. When I stumble out of bed and pour [...]
  • 2010: Finding opportunities in a big company — DEADLINE: 2010-07-30 Fri 08:00 The Extreme Blue interns are wrapping up and starting their job searches, so Cate [...]
  • 2008: Emacs and PHP: There’s more than one way to do it, of course — The PhpMode page on EmacsWiki lists five options for developing PHP in Emacs. I’m currently using the php-mode maintained by [...]
  • 2007: If I don’t go and do something, I’ll go mad — My thesis draft has been sent to my committee members. I’ve also revised my CASCON paper and outlined my presentation. And [...]
  • 2007: Postponing driver’s ed — Driving is a useful skill, and I will definitely look into it. However, I will postpone driving lessons right now because [...]
  • 2007: I heart the Toronto Public Library — Did you know that the Toronto Public Library is the largest in North Americ in terms of circulation, with 19 [...]
  • 2006: A weekend with a friend — My good deed for the weekend was spending time with Alice. Saturday, I attended the birthday party for her 2-year-old daughter [...]
  • 2004: Said goodbye to Fr. Nebres — Told him about the JapanTraining program and my plans for FurtherStudies. Got hugged twice! I’m so going to miss this school…
  • 2004: del.icio.us — I’m getting addicted to http://del.icio.us . I think of it as the high-tech equivalent of browsing library cards to see who [...]
  • 2003: http://rinkworks.com/stupid — Tech support horror stories