iEFdev

Code, Computers & Random Junk

My Server Setup in OS X - Part 3: PHP

This continues part 2, talking about my server setup. As before… This is not a tutorial or a HowTo …more of a conceptual overview. You might want/have to fill in the missing parts your self.


Before I setup all this, I spent quite some time planning and figuring out how I wanted it, and how to do it. I’m no “expert” so it took a while. But it was worth the time spent doing that. Also looking into other solutions, some Linux distros - how they’ve done it etc. So, for a while I only hade the bundled server install in OS X. A somewhat hadicapped feeling since I was used to my custom install in my old computer. But it was ok.

Since I also use Arch Linux on the side and have a basic LAMP installation there (which I will change into something like this when I switch), and really like the file layout - most parts are matching that, or are simular. Since OS X already have everything, you don’t want to interfere with that. That’s why Apache came to land in /usr/httpd for example.

Anyway…

PHP

I wanted to have 2 versions running. One to use with some old(er) scripts and programs, and another one to get going with. The most difficult part was to learn how to install/use them side-by-side in a nice and not too complicated way.

There are tons of webpages/guides/tutorials on how to setup everything. Most though, are either based off some package manager, which I don’t (want to) use, or they were based on Linux. But, all are good reading and you get to learn the settings/layout of the installation.

Some older pages (newer as well) have setups with SUEXEC and a wrapper for FastCGI. And some others are using the newer mod_fcgid instead of mod_fastcgi (which I’m using), and somtimes in combination with (or without) mod_proxy_fcgi.

Since I like to use custom PHP extensions sometimes, I didn’t really see how to do that with the proxy alternative. And also when matching a file extension to “.php” and match it to parse it.

mod_fastcgi is the older one for Apache 2.2, but there is a patch for 2.4, and it’s working great.

Instead of the SUEEXEC thing - I went with FPM. So, with PHP/FPM and FastCGI you don’t need an wrapper.


Layout.

When my research and planning was done I decided to do them simular to each other. One could have set the prefix /usr/local/phpNN (only) and everything would have went into that one, but to match my Linux install, to get it simular (much easier to memorize all paths if they’re alike on both my computers), the file locations/layout looks like this.

Parts from the configuration…

PHP 5.4

1
2
3
4
5
6
7
8
9
--prefix=/usr/local/php54 \
--localstatedir=/var/php54 \
--libdir=/usr/lib/php54 \
--includedir=/usr/include/php54 \
--datarootdir=/usr/share/php54 \
--mandir=/usr/share/php54/man \
--sysconfdir=/etc/php54 \
--with-config-file-path=/etc/php54 \
--with-config-file-scan-dir=/etc/php54/conf.d \

PHP 5.6

1
2
3
4
5
6
7
8
9
--prefix=/usr/local/php56 \
--localstatedir=/var/php56 \
--libdir=/usr/lib/php56 \
--includedir=/usr/include/php56 \
--datarootdir=/usr/share/php56 \
--mandir=/usr/share/php56/man \
--sysconfdir=/etc/php56 \
--with-config-file-path=/etc/php56 \
--with-config-file-scan-dir=/etc/php56/conf.d \

And you get all config files in /etc togther with the Apache ones. php54/php56… In that way I get everything side-by-side along the system, and can keep them as “integrated” as possible, but all alone.


2 versions?

What (perhaps) should’ve been mentioned earlier, is that you can’t run 2 versions of PHP on the same Apache installation. That is as mod_php. So, one needs to be mod_php, and the other one you run as cgi/fastcgi etc.

As with Apache, before you install anything - make sure you’ve installed and prepared all libraries, libjpg, libpng, imap-2007, opsnssl, geoip_c etc, etc. Whatever you need and/or have defined in the ./configure part.

There are a few PHP extension you better add afterwards, with phpize. You could bring them in before at compile time, but intl (for example) throws a ton of errors at you on OS X. So I found it to be better to add the PECL-version afterwards.

Also, we’ll add Opcache (for 5.4), GeoIP, APCu, Suhosin and Imagick.


Screenshot

Here’s a screenshot of my latest upgrade (yesterday) showing one as a module with “Apache 2.0 Handler” and the other as “FPM/FastCGI”…

(Full size)


./configure

Here are my 2 configure’s - using the latest 5.4.45 and 5.6.16 Updated yesterday when I upgraded my Apache to 2.4.18.

5.4

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
62
63
64
65
66
67
68
#
# PHP 5.4.45-mod
# 2015-12-21
#
../php-5.4.45/configure --prefix=/usr/local/php54 \
--localstatedir=/var/php54 \
--libdir=/usr/lib/php54 \
--includedir=/usr/include/php54 \
--datarootdir=/usr/share/php54 \
--mandir=/usr/share/php54/man \
--sysconfdir=/etc/php54 \
--with-config-file-path=/etc/php54 \
--with-config-file-scan-dir=/etc/php54/conf.d \
--with-apxs2=/usr/httpd/bin/apxs \
--with-kerberos=/usr \
--with-bz2=/usr \
--with-curl=/usr/local \
--with-freetype-dir=/usr/local \
--with-gettext \
--with-gd \
--with-gmp=/usr/local \
--with-iconv-dir=/usr \
--with-icu-dir=/usr/local \
--with-imap=/usr/local/imap-2007 \
--with-imap-ssl=/usr/local \
--with-iodbc=/usr \
--with-jpeg-dir=/usr/local \
--with-ldap=/usr \
--with-ldap-sasl=/usr \
--with-libedit=/usr \
--with-libxml-dir=/usr/local \
--with-mysql=mysqlnd \
--with-mysql-sock=/var/mysql/mysql.sock \
--with-mysqli=mysqlnd \
--with-openssl=/usr/local \
--with-openssl-dir=/usr/local \
--with-pcre-regex=/usr/local \
--with-pear=/usr/lib/php54/pear \
--with-pdo-mysql=mysqlnd \
--with-pdo-pgsql=/usr/local \
--with-pgsql=/usr/local \
--with-png-dir=/usr/local \
--with-readline=/usr/local \
--with-snmp=/usr \
--with-t1lib=/usr/local/lib \
--with-tidy \
--with-xmlrpc \
--with-xsl=/usr/local \
--with-zlib=/usr/local \
--disable-short-tags \
--disable-rpath \
--enable-bcmath \
--enable-calendar \
--enable-dba \
--enable-exif \
--enable-ftp \
--enable-gd-native-ttf \
--enable-mbstring \
--enable-mbregex \
--enable-mysqlnd \
--enable-shmop \
--enable-soap \
--enable-sockets \
--enable-sysvmsg \
--enable-sysvsem \
--enable-sysvshm \
--enable-wddx \
--enable-zip

5.6

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#
# PHP 5.6.16-zpm
# 2015-12-21
#
../php-5.6.16/configure \
--prefix=/usr/local/php56 \
--localstatedir=/var/php56 \
--libdir=/usr/lib/php56 \
--includedir=/usr/include/php56 \
--datarootdir=/usr/share/php56 \
--mandir=/usr/share/php56/man \
--sysconfdir=/etc/php56 \
--with-config-file-path=/etc/php56 \
--with-config-file-scan-dir=/etc/php56/conf.d \
--with-bz2=/usr \
--with-curl=/usr/local \
--with-fpm-user=_www \
--with-fpm-group=_www \
--with-freetype-dir=/usr/local \
--with-gd \
--with-gettext=/usr/local \
--with-gmp=/usr/local \
--with-iconv-dir=/usr \
--with-icu-dir=/usr/local \
--with-imap=/usr/local/imap-2007 \
--with-imap-ssl=/usr/local \
--with-iodbc=/usr \
--with-jpeg-dir=/usr/local \
--with-kerberos=/usr \
--with-ldap=/usr \
--with-ldap-sasl=/usr \
--with-libedit=/usr \
--with-libxml-dir=/usr/local \
--with-mcrypt \
--with-mhash \
--with-mysql=mysqlnd \
--with-mysqli=mysqlnd \
--with-mysql-sock=/var/mysql/mysql.sock \
--with-ndbm=/usr \
--with-openssl=/usr/local \
--with-openssl-dir=/usr/local \
--with-pcre-regex=/usr/local \
--with-pdo-mysql=mysqlnd \
--with-pdo-pgsql=/usr/local \
--with-pear=/usr/lib/php56/pear \
--with-pgsql=/usr/local \
--with-pic \
--with-png-dir=/usr/local \
--with-readline=/usr/local \
--with-snmp=/usr \
--with-t1lib=/usr/local/lib \
--with-tidy \
--with-xmlrpc \
--with-xsl=/usr/local \
--with-zlib=/usr/local \
--with-zlib-dir=/usr/local \
--disable-short-tags \
--disable-rpath \
--enable-bcmath \
--enable-calendar \
--enable-cli \
--enable-dba \
--enable-exif \
--enable-fpm \
--enable-ftp \
--enable-gd-native-ttf \
--enable-inline-optimization \
--enable-ipv6 \
--enable-mbregex \
--enable-mbstring \
--enable-mysqlnd \
--enable-opcache \
--enable-pcntl \
--enable-pdo \
--enable-sigchild \
--enable-shmop \
--enable-soap \
--enable-sockets \
--enable-sysvmsg \
--enable-sysvsem \
--enable-sysvshm \
--enable-wddx \
--enable-zip

The first line: ../php-5.6.16/configure, indicates we’re not in the source folder when doing this. I usually use a separate build folder outside.

5.6/
    php-5.6.16_build/
    php-5.6.16/

It’s great when you need to start over and you can just delete everything in it.

Both are followed by:

make -j5
sudo make install

When all that is done - we need to setup a few things in ~/.bashrc and ~/.bash_aliases (if you use that one).

You need to add PHP 5.6 to PATH, and then we make aliases to 5.4.

From my .bashrc: (including the global composer path)

# PHP 5.6 (default), 5.4 in .bash_aliases
_PHP="/usr/local/php56/bin:/usr/local/php56/sbin"
_CPOS="$HOME/.composer/vendor/bin"

And add it to PATH:

# export PATH.
export PATH="$_AP24:$_PHP:$_CPOS:/usr/local/bin:/usr/local/sbin:$PATH"

Another thing to think about is when compiling 5.4 you need an older version of autoconf.

# older version for php
#export PATH="/usr/local/autoconf-2.5.9/bin:$PATH"

And just uncomment it when needed.

5.4 aliases… From my .bash_aliases:

# PHP 5.4 (5.6 is in PATH)
alias php54='/usr/local/php54/bin/php'
alias phpize54='/usr/local/php54/bin/phpize'
alias pear54='/usr/local/php54/bin/pear'
alias pecl54='/usr/local/php54/bin/pecl'

Adding extensions

So, to add the extensions we use phpize and phpize54

The php-config files are located at:

--with-php-config=/usr/local/php54/bin/php-config
--with-php-config=/usr/local/php56/bin/php-config

The basics are:

# cd "the source folder"
# phpize
# ./configure --(with|enable)-name --with-php-config=/usr/local/php(54 or 56)/bin/php-config
# make
# sudo make install

APCu

You find it here on Github: APCu.

This one is a little bit “trickier” because it just changed its repos/tagging on Github. We will install v4.0.10, so in order to do that… You could just download v4.0.10, but it’s better to clone the project and pull it. It’s easier later on when you update. So, assuming you have git installed.

git clone git@github.com:krakjoe/apcu.git
cd apcu

Now get the tag and branch it.

git checkout tags/v4.0.10 -b v4.0.10

You can run git branch to confirm it.

Since we’re going to install it on 2 versions, I usually duplicate the folder twice and reneaming them to apcu_54/apcu_56. That’s because the use of the 2 different phpize versions.

To install it:

5.4

cd ../apcu_54
phpize54
mkdir __build && cd __build
../configure --enable-apcu --with-php-config=/usr/local/php54/bin/php-config
make -j5
sudo make install

5.6

cd ../apcu_56
phpize
mkdir __build && cd __build
../configure --enable-apcu --with-php-config=/usr/local/php56/bin/php-config
make -j5
sudo make install

Copy the ini files into:

  • /etc/php54/conf.d/apcu.ini
  • /etc/php56/conf.d/apcu.ini

At the top, add:

; Inifile for APCu
; ----------------
;
; Load extension
extension = apcu.so

Read the page about settings and suggested settings.


(Zend) Opcache

This one is only for 5.4 since it’s bundled in 5.6. You can find it here: ZendOptimizerPlus

The installation is simular, like:

git clone git@github.com:zendtech/ZendOptimizerPlus.git
cd ZendOptimizerPlus

phpize54
mkdir __build && cd __build
../configure --enable-opcache --with-php-config=/usr/local/php54/bin/php-config
make -j5
sudo make install

Copy the ini file into:

  • /etc/php54/conf.d/opcache.ini

At the top, add:

; Enable Zend OPcache extension
zend_extension=/usr/lib/php54/extensions/no-debug-zts-20100525/opcache.so

Suhosin

You can find it here: Suhosin. Good thing with this is that the latest version now is working with all. Before there was always a hunt for the proper version(s), including the right set of patches.

To install it:

git clone git@github.com:stefanesser/suhosin.git

Make 2 copies and rename those to suhosin_54/suhosin_56

5.4

cd suhosin_54
phpize54
mkdir __build && cd __build
../configure --enable-suhosin --with-php-config=/usr/local/php54/bin/php-config
make -j5
sudo make install

5.6

cd ../suhosin_56
phpize
mkdir __build && cd __build
../configure --enable-suhosin --with-php-config=/usr/local/php56/bin/php-config
make -j5
sudo make install

Copy the ini files into:

  • /etc/php54/conf.d/suhosin.ini
  • /etc/php56/conf.d/suhosin.ini

At the top, add:

; Enable Suhosin
extension=suhosin.so

Read the page about settings and suggested settings. Most things are blank and commented. But it’s good to read the documentation. What it does, and can do.


Intl

Ok, this is the one I never got to compile with php (OS X related) even if it’s bundled, so we add it here. Make sure you have the dependencies first.

I have used the PECL one, version 3.0.0. You can download it from here: PECL/Intl. Unpack and make 2 duplicates intl-3.0.0_54/intl-3.0.0_56.

5.4

cd intl-3.0.0_54
phpize54
mkdir __build && cd __build
../configure --enable-intl --with-php-config=/usr/local/php54/bin/php-config
make -j5
sudo make install

5.6

cd intl-3.0.0_56
phpize
mkdir __build && cd __build
../configure --enable-intl --with-php-config=/usr/local/php56/bin/php-config
make -j5
sudo make install

Create the ini files:

sudo su -c "echo -e '; Intl :: 3.0.0 (stable)\nextension=intl.so' > /etc/php54/conf.d/intl.ini"
sudo cp /etc/php5{4,6}/conf.d/intl.ini

Imagick

You have to have ImageMagick installed to add this one. ImageMagick today is in a shifting phase (kind of), going from 6 to 7. And they’re a little bit different. When I installed this one, I never got to make Imagick to work with ImageMagick7, so I have an additional installation of IMv6 in /usr/local/ImageMagick6. (That also gives me the old convert which is replaced by magick in IMv7)

For this I use the PECL version as well: PECL/Imagick. There is an 3.4.0RC3 now since 2015-12-12. Missed that one. I only have 3.3.0RC2. (I need to ugragde perhaps)

So, same as with Intl, download and unpack it, and make 2 duplicates, and rename them to: imagick-<vers>_54/imagick-<vers>_56.

And here is with the path to my IMv6 installation…

5.4

cd imagick-<vers>_54
phpize54
mkdir __build && cd __build
../configure --with-imagick=/usr/local/ImageMagick6 --with-php-config=/usr/local/php54/bin/php-config
make -j5
sudo make install

5.6

cd imagick-<vers>_56
phpize
mkdir __build && cd __build
../configure --with-imagick=/usr/local/ImageMagick6 --with-php-config=/usr/local/php56/bin/php-config
make -j5
sudo make install

Create the ini files:

sudo su -c "echo -e '; Imagick :: 3.3.0RC2\nextension=imagick.so' > /etc/php54/conf.d/imagick.ini"
sudo cp /etc/php5{4,6}/conf.d/imagick.ini

GeoIP

And this is also a PECL version: PECL/GeoIP 1.1.0. If you installed the Apache module you also noticed you first need to install the C library: geoip_c.

So, same as with the other ones, download and unpack it, and make 2 duplicates, and rename them to: geoip-1.1.0_54/geoip-1.1.0_56.

5.4

cd geoip-1.1.0_54
phpize54
mkdir __build && cd __build
../configure --with-geoip --with-php-config=/usr/local/php54/bin/php-config
make -j5
sudo make install

5.6

cd geoip-1.1.0_56
phpize
mkdir __build && cd __build
../configure --with-geoip --with-php-config=/usr/local/php56/bin/php-config
make -j5
sudo make install

Create the ini files:

  • /etc/php54/conf.d/geoip.ini
  • /etc/php56/conf.d/geoip.ini

The ones I have looks like this at the moment:

;
; GeoIP 1.1.0
;
extension=geoip.so

;[geoip]
;geoip.custom_directory = /usr/local/share/GeoIP/

Xtras

You will have to edit your main php.ini files (of course), to match you installation, like date, location etc.

Then to add a little more functionality to 5.4 - add Password Compat to get the password_* functions that came with 5.5.

git clone git@github.com:ircmaxell/password_compat.git

Also, you can get the array_column… who also came with 5.5.

git clone git@github.com:ramsey/array_column.git

I keep them in their cloned folders so it ’s easy to update now and then, and then just copy the files over to a folder I have set in php.ini. That is: /usr/local/xtras. So, just make a copy (or a symlink perhaps)?

cd /usr/local/xtras
sudo cp /path/to/password_compat/lib/password.php .
sudo cp /path/to/array_column/src/array_column.php .

In /etc/php54/php.ini you can add the “xtras” folder with something like:

; UNIX: "/path1:/path2"
include_path = ".:/php/includes:/usr/lib/php54/pear:/usr/local/xtras"

You can use any folder you like, of course.


Now with everything installed and the 2 PHP versions + xtras. If you check the versions in Terminal it will look like this. Note the xtra Opcache on PHP 5.4.

Sumup

Before you do all this… as mentioned earlier - You need to prepare and install all libraries that are needed for each part of the installation/configuration. Like Intl… you need gettext and icu.

Most stuff in OS X… IF already present, they’re usually old/outdated. Update accordingly.

I prefer to do everything by my self, but you can use “HomeBrew”, “MacPorts”, “Fink”, or what you prefer. Just keep track of the paths to each one as you need to define them in the installation. Usually that is: /usr/local (in my case).


FPM and FastCGI

This is the most tricky part to get to work. It takes a lot of reading and trying, but it’s well worth the time it takes. I wrote a little bit about it in “part 2”, but I’ll write a better example in the next one.

I won’t use the proxy version, and there’s also a couple of Apache macros to setup/use. In that way you can easily work with your virtualhosts and define what PHP version to use. I also have an xtra one using mod_php on port :81. Just to be able to test 5.4 in whatever host/project I use.

Updated post: 2015-12-23 - Here is Part 4 about FastCGI and Virtualhost.


Happy hacking…

/Eric

Comments