By Troels Knak-Nielsen

PHP Manual CLI style 2.0

By Troels Knak-Nielsen

Harry mentioned the handy little phpm some three years ago. And Sean Coates was kind enough to point out how it could be replaced with a shell one-liner. Doesn’t that just make one love bash?

One thing, I missed with either of the two, was the ability to see the entire manual entry. It’s quite often, that the manual actually holds useful information (Who’d known that!), so I find myself using a lot. Or I did, until I decided to do something about it. Now, shell-scripting isn’t what I spent most of my time on, so it’s not with out a bit of pride, that I present to you phpm two-oh.

# phpm
# commandline php-manual interface
# Kudos to Havard Eide and Sean Coates for the original idea
# author: Troels Knak-Nielsen <>
# version: 2007-11-27
# dependencies:
#   wget        sudo apt-get install wget
#   sed         sudo apt-get install sed
#   tidy        sudo apt-get install tidy
#   xmlstarlet  sudo apt-get install xmlstarlet
#   konwert     sudo apt-get install konwert
#   html2text   get from
#               symlink to ~/bin/html2text
#   urlencode   get from
#               symlink to ~/bin/urlencode

function print_usage {
  echo "USAGE: phpm <function>"
  echo "To clear cache: phpm --clear"
  exit 0

# create cachedir on first run
if [ ! -e $CACHEDIR ]
  mkdir $CACHEDIR

if [ $# -gt 0 ]
  # parse a few options
  if [ $1 = "--clear" ]
    echo "clearing cache"
    rm -r $CACHEDIR
    exit 0
  if [ $1 = "--help" ]
  if [ $1 = "-?" ]

  URLNAME=$(echo $1 | urlencode)
  # check cache
  if [ ! -e $CACHE_FILENAME ]
    # fetch from HTTP
    RESPONSE=$(wget --quiet -O - $HREF)
    if [ $? != 0 ]
      echo "HTTP error" 1>&2
      exit $?

    # process response
    # test if function has direct match
    if echo $RESPONSE | grep -Eiq '<div([^>]*)class="refentry">'
      # grap and format output
      # the first sed collapses blank lines, the second formats headers
      echo $RESPONSE 
        | tidy -latin1 -asxhtml --input-encoding utf8 --output-xml true --numeric-entities true 2>/dev/null 
        | xmlstarlet select --net --html -t -c "//*[@class='refentry']" 2>/dev/null 
        | tidy -latin1 --input-encoding utf8 -asxhtml 2>/dev/null 
        | konwert utf8-ascii 
        | html2text 2>&1 
        | sed -n 'G; s/n/&&/; /^([ -~]*n).*n1/d; s/n//; h; P' 
        | sed -e '/^# (.*)$/ { s/^# (.*)/1/p ; s/(.{1,1})/=/g }' -e '/^## (.*)$/ { s/^## (.*)/n1/p ; s/(.{1,1})/-/g }' -e '/^### (.*)$/ { s/^### (.*)/n1/p ; s/(.{1,1})/~/g }' 
    # test if there are any "best" matches
    elif echo $RESPONSE | grep -Eiq '<a href="/manual/en/function[^>]*><b>'
      echo "Best matches for '$1':" > $CACHE_FILENAME
      echo $RESPONSE 
        | tidy -latin1 -asxhtml --input-encoding utf8 --output-xml true --numeric-entities true --wrap 0 2>/dev/null 
        | sed -n 's/.*<a href="/manual/en/function[^>]*><b>([^<]{1,})<.*/1/p' 
        >> $CACHE_FILENAME
    # test if there are any "weak" matches
    elif echo $RESPONSE | grep -Eiq '<a href="/manual/en/function[^>]*>[^<]+'
      echo "Possible matches for '$1':" > $CACHE_FILENAME
      echo $RESPONSE 
        | tidy -latin1 -asxhtml --input-encoding utf8 --output-xml true --numeric-entities true --wrap 0 2>/dev/null 
        | sed -n 's/.*<a href="/manual/en/function[^>]*>[^<]{1,}([^<]{1,})<.*/1/p' 
        >> $CACHE_FILENAME

  if [ -e $CACHE_FILENAME ]
    echo "No matches found for '$1'"
    exit -1

Installing it

You obviously need a bash environment to run it (I suppose cygwin will do). Apart from that, you need a host of cli tools and utilities. If you’re on a debian based system, the following should get you running:

sudo apt-get install wget sed tidy xmlstarlet konwert

Then get the following two scripts:

Save them (Without file-extension) in ~/bin and make them executable:

chmod +x ~/bin/html2text
chmod +x ~/bin/urlencode

(Or you can put them somewhere, such as in ~/scripts and then symlink them)

Finally, save the above script as ~/bin/phpm and chmod it, like the other two scripts.


You should now be able to look up a function in the PHP manual as simple as:

phpm substr

As a bonus, you’ll get a list of suggestions for mismatches. For example:

$ phpm substring
Best matches for 'substring':

Very handy, when you only remember part of the function name.

The script queries the php website for the documentation, so it’s always up-to-date. To improve performance, results are cached in ~/.phpm. You can always clear the cache by calling phpm like:

phpm --clear

Emacs bonus

As a final little bonus for the Emacs-users about, here’s a snippet for binding F4 to phpm for the current word:

(defun php-manual-lookup ()
  "Shows short documentation for the word at the point."
  (let ((word (current-word t))
        (buffername "*phpm*"))
    (when (get-buffer buffername)
      (kill-buffer buffername))
      (pop-to-buffer buffername)
      (shell-command (format "phpm %s"
                             (shell-quote-argument word)) buffername)
      (other-window 1))))
(global-set-key '[f4] 'php-manual-lookup)
  • deminy

    Just tried. Nice job~~

  • phpimpact

    This is the shell-script of the year, and if you are a LAMP developer, the script of the century! Well done Troels, great use of sed :)

  • thkoch2001

    Somewhere my wget is configured to send an Accept-Language header for german. First the german umlauts were not displayed correctly on my ISO-8859-1 terminal, second I don’t rely on the translated manual pages as there are sometimes outdated. So I changed line 57 to explicitly ask for english pages:

    RESPONSE=$(wget --header='Accept-Language: en' --quiet -O - $HREF)

    Make sure to run phpm --clear after changing!

  • thkoch2001

    Include it in VIM, using Tobias Schlitt’s config[1]:

    " Map -H to search phpm for the function name currently under the cursor (insert mode only)
    inoremap :!phpm =expand("")


  • Ramin

    Nice script.

    If you are a Windows user who has Microsoft Desktop Search installed, an alternative way to access php help would be to create a shortcut by typing the following in the Desktop Search box:
    @phpm ,$w

    Then you should be able to type in the following to get help:
    phpm substring

  • Pingback: PHP help at your command line | VT's Tech Blog()

Get the latest in Front-end, once a week, for free.