This recipe covers:
-
how to install PHP via Homebrew on macOS for the macOS built-in apache.
-
how to codesign PHP on macOS so macOS built-in apache will be able to access it.
-
how to backup and restore PHP before and after a macOS update/upgrade
-
how to update PHP after the original installation
To install PHP you will need Homebre so first install Homebrew using the formula:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
For reference: https://wpbeaches.com/installing-homebrew-on-macos-big-sur-11-2-package-manager-for-linux-apps/
And Run these two commands in your terminal to add Homebrew to your PATH: (NB. edit the user_name)
(echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/user_name/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
Then you can check for install issues by running:
brew doctor
On Apple Silicon Macs Homebrew lives at:
/opt/homebrew
And on Intel Macs Homebrew can be found at:
/usr/local/homebrew
You can check the Homebrew config by running:
brew config
To keep Homebrew up-to-date make sure to run:
brew update
and,
brew upgrade
To remove Homebrew and all the packages it has installed use:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)"
First add the PHP formulae:
brew tap shivammathur/php
Then choose the PHP version (e.g. 8.3)
brew install shivammathur/php/[email protected]
Then link the PHP version:
brew link --overwrite --force [email protected]
NOTE:
Apple's default apache is found at:
/etc/apache2
When you install you will be advised on how to enable PHP using the LoadModule line in apache's http conf file. NOTE: you will have to codesign PHP before it will actually load (see the next section for how to CodeSign PHP)
==> Caveats ==> [email protected] To enable PHP in Apache add the following to httpd.conf and restart Apache:
LoadModule php_module /opt/homebrew/opt/[email protected]/lib/httpd/modules/libphp.so
```
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
```
Finally, check DirectoryIndex includes index.php
DirectoryIndex index.php index.html
The php.ini and php-fpm.ini file can be found in:
ARM
/opt/homebrew/etc/php/8.3/
Intel
/usr/local/etc/php/8.3/
[email protected] is keg-only, which means it was not symlinked into /opt/homebrew, because this is an alternate version of another formula.
If you need to have [email protected] first in your PATH, run:
ARM
echo 'export PATH="/opt/homebrew/opt/[email protected]/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="/opt/homebrew/opt/[email protected]/sbin:$PATH"' >> ~/.zshrc
Intel
echo 'export PATH="/usr/local/cellar/[email protected]/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="/usr/local/cellar/[email protected]/sbin:$PATH"' >> ~/.zshrc
For compilers to find [email protected] you may need to set: ARM
export LDFLAGS="-L/opt/homebrew/opt/[email protected]/lib"
export CPPFLAGS="-I/opt/homebrew/opt/[email protected]/include"
Intel
export LDFLAGS="-L/usr/local/cellar/[email protected]/lib"
export CPPFLAGS="-I/usr/local/cellar/[email protected]/include"
To switch between versions after an upgrade:
brew link --overwrite --force [email protected]
To restart shivammathur/php/[email protected] after an upgrade:
brew link --overwrite --force [email protected]
Or, if you don't want/need a background service you can just run:
ARM
/opt/homebrew/opt/[email protected]/sbin/php-fpm --nodaemonize
Intel
/usr/local/opt/[email protected]/sbin/php-fpm --nodaemonize
Restart Terminal and check the version:
php -v
To change to another version just repeat the process from the brew install... then unlink and link in the new PHP version by issuing a command like below but with your correct version e.g.: brew unlink php && brew link --overwrite --force [email protected]
This FileMaker Engineering Blog discusses how to install PEAR on macOS. It is required for FileMaker Server but as far as I can tell you can skip this for munkireport.
https://support.claris.com/s/answerview?anum=000035470&language=en_US#a2
To enable PHP in Apache first make sure you codesign PHP (see below) and then add the following to httpd.conf and restart Apache:
ARM
LoadModule php_module /opt/homebrew/opt/[email protected]/lib/httpd/modules/libphp.so
Intel
LoadModule php_module /usr/local/opt/[email protected]/lib/httpd/modules/libphp.so
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
Finally, check DirectoryIndex includes index.php
DirectoryIndex index.php index.html
Restart Apache:
sudo apachectl -k restart
The php.ini and php-fpm.ini file can be found in:
ARM
/opt/homebrew/etc/php/8.3/
Intel
/usr/local/etc/php/8.3/
If you have not code-signed php yet you will see this error:
[so:error] [pid 26552] AH06665: No code signing authority for module at /opt/homebrew/opt/[email protected]/lib/httpd/modules/libphp.so specified in LoadModule directive. httpd: Syntax error on line 188 of /private/etc/apache2/httpd.conf: Code signing absent - not loading module at: /opt/homebrew/opt/[email protected]/lib/httpd/modules/libphp.so
You can check the location of your php with this command:
grep -nir "^loadmodule.*php" /etc/apache2
If you have successfully codesigned PHP it should return:
/etc/apache2/httpd.conf:190:LoadModule php_module /opt/homebrew/opt/[email protected]/lib/httpd/modules/libphp.so "Developer ID Application: Example.com (ABCDE1234)"
Now you can code sign that using your Apple Developer ID. Similar to:
https://derflounder.wordpress.com/2019/04/10/notarizing-automator-applications/
e.g.
codesign --force --options runtime --deep --sign "Developer ID Application: Example.com (ABCDE1234)" "/path/to/Application Name Here.app"
Eg:
ARM
codesign --force --options runtime --deep --sign "Developer ID Application: Example.com (ABCDE1234)" "/opt/homebrew/opt/[email protected]/lib/httpd/modules/libphp.so"
Intel
codesign --force --options runtime --deep --sign "Developer ID Application: Example.com (X3Q1C2345)" "/usr/local/Cellar/[email protected]/8.3.1/lib/httpd/modules/libphp.so"
Verify the code signed signature:
codesign -dv --verbose=4 "/path/to/Application Name Here.app"
codesign -dv --verbose=4 "/opt/homebrew/opt/[email protected]/lib/httpd/modules/libphp.so"
Add the code signing certificate name after the module path in apache's http.conf LoadModule Directive:
LoadModule php_module /opt/homebrew/opt/[email protected]/lib/httpd/modules/libphp.so "Signing Certificate Name"
ARM
LoadModule php_module /opt/homebrew/opt/[email protected]/lib/httpd/modules/libphp.so "Example.com (X3Q1C2345)"
LoadModule php_module /opt/homebrew/opt/[email protected]/lib/httpd/modules/libphp.so "Developer ID Application: Example.com (X3Q1C2345)"
Intel
LoadModule php_module /usr/local/opt/[email protected]/8.3.1/lib/httpd/modules/libphp.so "Developer ID Application: Example.com (ABCDE1234)"
Restart Apache:
sudo apachectl -k restart
If it worked you should now see:
[so:notice] [pid 27274] AH06662: Allowing module loading process to continue for module at /opt/homebrew/opt/[email protected]/lib/httpd/modules/libphp.so because module signature matches authority "Developer ID Application: Example.com (ABCDE1234)" specified in LoadModule directive
Test PHP by placing the following phpinfo.php file in the default home directory of your server at:
/Library/WebServer/Documents/phpinfo.php
NB. The file should be removed after testing for security reasons
<?php
// Show all information, defaults to INFO_ALL
phpinfo();
?>
And view it at:
The Apache HTTP.conf file could get overwritten by Apple on security or OS updates (usually only on major OS upgrades but you can never be sure).
You can backup and restore the http.conf file with the commands in my reverse proxy tutorial. Or you can do it manually. The scripts below will backup to and restore from /Users/Shared.
To backup:
#!/bin/zsh
#Set the variables
THEFILE="/private/etc/apache2/httpd.conf"
APACHE2_LOC="/private/etc/apache2"
BACKUP_LOC="/Users/Shared/"
# Backup httpd.conf
sudo cp "${APACHE2_LOC}/${HTTPD_FILE}" "${BACKUP_LOC}${HTTPD_FILE}"
To restore it after the update using:
#!/bin/zsh
#Set the variables
THEFILE="/private/etc/apache2/httpd.conf"
APACHE2_LOC="/private/etc/apache2"
BACKUP_LOC="/Users/Shared/"
#Restore httpd.conf"
sudo cp "${BACKUP_LOC}${HTTPD_FILE}" "${APACHE2_LOC}/${HTTPD_FILE}"
sudo chown root "${APACHE2_LOC}/${HTTPD_FILE}"
The following describes how to update PHP (eg. from PHP 8.3.10 to 8.3.12)
First make sure your homebrew instance is good:
brew doctor
Then update and upgrade brew to its latest version:
brew update
and
brew upgrade
Now you are ready to update PHP to its latest version:
brew upgrade shivammathur/php/[email protected]
If you had a code-signed PHP 8.3.10 before you started you will now have an unsigned PHP 8.3.12 and will have to codesign it and restart apache (see above in the Codesigning section).
How to future proof your apache modules in macOS by signing them with your own certificate authority - Camden Narzt
https://blog.phusion.nl/2020/12/22/future_of_macos_apache_modules/
Installing PHP 7 on macOS 12 Monterey - Tim Perfitt
https://twocanoes.com/knowledge-base/installing-php-7-on-macos-12-monterey/
Signing homebrew PHP module in macOS with your own signing authority
https://www.simplified.guide/macos/apache-php-homebrew-codesign
Signing Mac Software with Apple Developer ID
https://developer.apple.com/developer-id/
PHP no longer bundled with FileMaker Server - Claris Engineering Blog
https://support.claris.com/s/answerview?anum=000035470&language=en_US#a2