iEFdev

Code, Computers & Random Junk

Setup a Local PHP Manual

How to setup a local verison of the PHP manual, and keep it up to date. The PHP manual is essential to use and get quick access to. Keeping a local version of it, is for me really great. My internet speed isn’t very good, so the online pages are kind of slow at times. Also, when living on the countryside, it happens that the internet will be gone sometimes - like after a big storm.

PHP Documentation

One way is to download and setup/use the documention files. They’re great, but I find them hard to use some times.

PEAR “pman”

There is also the (exellent) pman, which is a terminal based version of the manuals. I really like them - simple to install, and to use.

You install pman with PEAR.

pear install doc.php.net/pman
pear upgrade doc.php.net/pman

And use it with:

pman strlen

The only (real) disappointment when I installed it was that the pman-file had a date in its filename: “2014-01-01”. I hope it gets updated soon, since that is quite old now.

A note on the pear installation… Bump up the ‘memory_limit’ in php.ini before you run it.

Virtualhost

Then you can setup a local mirror of the PHP manuals.


There are 2 pages on php.net that explains that really good.


First you need to setup your environment, where to download the files - where your virtualhost for this will sit. I keep my local sites in: /srv/www/foo.dev/public_html/. I’m going to call the “site”: pman.dev. An example set of folders…

mkdir /srv/www/pman.dev/{backups,cgi-bin,logs,misc_files,public_html,tmp}

Now, this (my setup) will differ a litte bit from the setup at php.net, because the example for the virtualhost is based on the Apache 2.2 syntax, and I use Apache 2.4 - without the access_compat_module. Then I also use PHP as FastCGI/FPM.

Download

To download the files - rsync is the program to use for that. If you look at the examples (at php.net), you’ll see a few different --delete..., --include... and --exclude.... This will be an example, where we only download the english version of the manual without downlads etc… Focus is to get the manual.

You could run the rsync command manually, but since we will automate the updates, I suggest you create a script and then run the script with cron for the updates.

Here’s mine. I have saved it as php-local in one of my php folders: /usr/local/php56/sbin/php-local.

php-local
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env bash
#
# /usr/local/php56/sbin/php-local
#
# Description: Script to run with cron (or launchctl in OSX)
# to update local mirror of PHP manuals/docs
#
# Cron examples: 5min, 15min
#   */5 * * * * /usr/local/php56/sbin/php-local
#   */15 * * * * /usr/local/php56/sbin/php-local
#
# Read more:
#   http://php.net/mirroring.php
#   http://doc.php.net/tutorial/local-setup.php
#

rsync -avzC --timeout=600 --delete --delete-after \
--include='manual/en/' --include='manual/en/**' \
--exclude='manual/**' --exclude='distributions/**' \
--exclude='extra/**' --exclude='backend/notes/**' \
--exclude='bin/**' \
europe.rsync.php.net::phpweb /srv/www/pman.dev/public_html/

# OS X say...
[ $(uname) == 'Darwin' ] && say -v Samantha "php manuals r synced"

Replace europe.rsync.php.net with the region that match your location:

  • americas.rsync.php.net (North + South America)
  • europe.rsync.php.net (Europe + Russia and Africa)
  • asia.rsync.php.net (Asia + Australia)

The example on the site suggest you later on update every 5min (max 15min), but this is not an official mirror site, and in my case with my bad internet speed, I really don’t want it to update that often. I’ve set mine to once a week.

Give it permission to execute:

sudo chmod +x /usr/local/php56/sbin/php-local

And then run the script. It’ll take a while at first run, but not that bad - not even with my speed.

Virtualhost

Now to setup the site.

In /etc/hosts, add:

127.0.0.1   pman.dev

Then your virtualhost file… I’m just going to paste in my content here. Some of it will probably be useless to you, but you get the picture.

pman.dev.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#===============================================
#   pman.dev
#===============================================
<VirtualHost *:80>
    Define vhost_srv pman.dev
    #Define vhost_adm admin@foobar.dev

    ServerName ${vhost_srv}
    ServerAlias www.${vhost_srv}
    ServerAdmin admin@${vhost_srv}
    UseCanonicalName On

    DocumentRoot /srv/www/${vhost_srv}/public_html

    ErrorLog /srv/www/${vhost_srv}/logs/error_log
    CustomLog /srv/www/${vhost_srv}/logs/access_log combined

    <IfModule alias_module>
        ScriptAlias /cgi-bin/ "/srv/www/${vhost_srv}/cgi-bin/"
    </IfModule>

    # Handle errors with local error handler script
    ErrorDocument 401 /error.php
    ErrorDocument 403 /error.php
    ErrorDocument 404 /error.php

    # Add types not specified by Apache by default
    AddType application/octet-stream .chm .bz2 .tgz .msi
    AddType application/x-pilot .prc .pdb

    # Set mirror's preferred language here
    SetEnv MIRROR_LANGUAGE "en"

    # The next two lines are only necessary if generating
    # stats (see below), otherwise you should comment them out
    #Alias /stats/ /path/to/local/stats/
    #SetEnv MIRROR_STATS 1

    # Apache2 has 'AddHandler type-map var' enabled by default.
    # Remove the comment sign on the line below if you have it enabled.
    # RemoveHandler var

    # Turn spelling support off (which would break URL shortcuts)
    <IfModule speling_module>
        CheckSpelling Off
    </IfModule>

    <Directory "/srv/www/${vhost_srv}/public_html">
        Options -Indexes -FollowSymLinks +SymLinksIfOwnerMatch
        Require host localhost
        Require ip 127
        Require ip ::1

        Use NoExt php
    </Directory>

    # Choose PHP Version
    # ==================
    Use FastPHP ${vhost_srv}
    #Use ModPHP
</VirtualHost>

To explain that a little… The “Use” and “Define” parts are functions in Apache 2.4. Depending on what you use, you’ll need to remove or change those parts to match your setup.

Inside the <Directory ... for the public folder, you want to add the content of the .htaccess with the Apache 2.4 syntax, like:

<FilesMatch "\.(inc|sql)$">
    Require all denied
</FilesMatch>

…instead of “Allow,Deny” etc.

Then setup your pool for FPM, if you’re use that.

Now restart Apache &/or PHP-FPM and give it a try.

Updating

The examples on php.net to setup cron is great, but adjust the time to what you need. For me that is once a week.

In OS X you can setup a LaunchDaemon instead. It’s like the OS X version of cron.

Here’s an example file.

net.php.php-local.plist
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>net.php.php-local</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/usr/local/php56/sbin/php-local</string>
    </array>
    <key>StandardErrorPath</key>
    <string>/var/php56/log/php-local.log</string>
    <key>StartCalendarInterval</key>
    <dict>
      <key>Hour</key>
      <integer>3</integer>
      <key>Minute</key>
      <integer>15</integer>
      <key>Weekday</key>
      <integer>6</integer>
    </dict>
</dict>
</plist>

Save it as: /System/Library/LaunchDaemons/net.php.php-local.plist. Adjust the paths to the log directory and where you put the script.

The last part: “StartCalendarInterval” is set to update at Saturdays at 3:15 AM, or at next upstart if the computer isn’t running.

To make the interval more frequent you could replace that with “StartInterval” instead, like:

<key>StartCalendarInterval</key>
<dict>
    // ... //
</dict>

# Replace with:

<key>StartInterval</key>
<integer>21600</integer>

That is every 6 hour (1 hour = 3600sec).

Make sure root is the owner:

sudo chown root:wheel /System/Library/LaunchDaemons/net.php.php-local.plist

To start and stop the agent:

sudo launchctl load -w /System/Library/LaunchDaemons/net.php.php-local.plist
sudo launchctl unload -w /System/Library/LaunchDaemons/net.php.php-local.plist

If you’re on OS X you can also uncomment the last line in the script php-local and the computer will tell you when it’s done. Like a small verification the script is working.

Comments