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 www.php.net 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.
#!/bin/bash
# phpm
# commandline php-manual interface
# Kudos to Havard Eide and Sean Coates for the original idea
#
# author: Troels Knak-Nielsen <troelskn@gmail.com>
# 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 http://www.aaronsw.com/2002/html2text/html2text.py
# symlink to ~/bin/html2text
# urlencode get from http://www.shelldorado.de/scripts/cmds/urlencode.txt
# symlink to ~/bin/urlencode
function print_usage {
echo "USAGE: phpm <function>"
echo "To clear cache: phpm --clear"
exit 0
}
# create cachedir on first run
CACHEDIR=~/.phpm
if [ ! -e $CACHEDIR ]
then
mkdir $CACHEDIR
fi
if [ $# -gt 0 ]
then
# parse a few options
if [ $1 = "--clear" ]
then
echo "clearing cache"
rm -r $CACHEDIR
exit 0
fi
if [ $1 = "--help" ]
then
print_usage
fi
if [ $1 = "-?" ]
then
print_usage
fi
URLNAME=$(echo $1 | urlencode)
CACHE_FILENAME=$CACHEDIR/$URLNAME
# check cache
if [ ! -e $CACHE_FILENAME ]
then
# fetch from HTTP
HREF=http://www.php.net/manual-lookup.php?function=$URLNAME
RESPONSE=$(wget --quiet -O - $HREF)
if [ $? != 0 ]
then
echo "HTTP error" 1>&2
exit $?
fi
# process response
# test if function has direct match
if echo $RESPONSE | grep -Eiq '<div([^>]*)class="refentry">'
then
# 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\).*\n\1/d; s/\n//; h; P' \
| sed -e '/^# \(.*\)$/ { s/^# \(.*\)/\1/p ; s/\(.\{1,1\}\)/=/g }' -e '/^## \(.*\)$/ { s/^## \(.*\)/\n\1/p ; s/\(.\{1,1\}\)/-/g }' -e '/^### \(.*\)$/ { s/^### \(.*\)/\n\1/p ; s/\(.\{1,1\}\)/~/g }' \
> $CACHE_FILENAME
# test if there are any "best" matches
elif echo $RESPONSE | grep -Eiq '<a href="\/manual\/en\/function[^>]*><b>'
then
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[^>]*>[^<]+'
then
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
fi
fi
if [ -e $CACHE_FILENAME ]
then
cat $CACHE_FILENAME
else
echo "No matches found for '$1'"
exit -1
fi
else
print_usage
fi
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.
Usage
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':
is_string
substr
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."
(interactive)
(let ((word (current-word t))
(buffername "*phpm*"))
(when (get-buffer buffername)
(kill-buffer buffername))
(save-excursion
(pop-to-buffer buffername)
(shell-command (format "phpm %s"
(shell-quote-argument word)) buffername)
(other-window 1))))
(global-set-key '[f4] 'php-manual-lookup)
Related posts:
- Interactive CLI password prompt in PHP Just a quick tip, since I spent a good hour...
- How to Use PHP Namespaces, Part 2: Importing, Aliases, and Name Resolution In the second part of Craig's PHP namespaces series, he...
- How to Use PHP Namespaces, Part 3: Keywords and Autoloading In the final part of his series explaining PHP namespaces,...
- How to Use PHP Namespaces, Part 1: The Basics In the first part of a series of articles, Craig...
- How to Install PHP on Windows In his final installation tutorial, Craig provides a step-by-step guide...







Just tried. Nice job~~
November 28th, 2007 at 3:33 am
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 :)
November 28th, 2007 at 5:49 am
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 --clearafter changing!November 28th, 2007 at 7:16 pm
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("")[1] http://schlitt.info/applications/blog/index.php/plugin/tag/vim
November 28th, 2007 at 7:27 pm
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 , http://www.php.net/manual-lookup.php?function=$wThen you should be able to type in the following to get help:
phpm substringNovember 28th, 2007 at 10:45 pm
[...] The installation instructions are available at: http://www.sitepoint.com/blogs/2007/11/28/php-manual-cli-style-20/ [...]
January 4th, 2008 at 12:40 am