Install PHP on Apple Silicon Macbook Pro

I recently went through the process of install PHP on macOS Monterey on my MackBook Pro M1 (Apple Silicon), the installation of PHP itself is easy, the codesigning of the PHP module took a little while to figuring out, I thought it would be a good idea to document the walk-through on how I did it.

Install PHP on macOS Monterey

After 10 years of using my MacBook Pro 2011 edition, I finally bought an Macbook Pro M1 recently. Most of the software that I'm using already has the version that supports Apple Silicon. So what I did is do a full backup-and-restore to move all my data and applications over to the new MacBook Pro, and delete those applications that has the newer Apple Silicon version and then install the new version. For those that are not supported by by Apple Silicon, the Rosetta 2 (https://support.apple.com/en-us/HT211861) helps to translate the older version so that it will be able to run on Apple Silicon. This went well for most of applications, including my MSQL installation and all the databases, except for PHP.

Apple pre-packaged Apache 2.4 in macOS Montery 12. However Apple removed PHP since macOS Monterey 12. In case you need PHP, you will have to install it yourself. Most of the online tutorials or walk-through suggesting of installing the complete pre-packaged Appache-PHP-MYSQL stacks, but I already has the MySQL up and running, and the built-in Apache 2.4 is okay for me, so I only need to install PHP.

Install Homebrew

Although it is possible to download the PHP source code and build it on the machine, but it is much easier to install it using Homebrew. Surprisingly for past 10 years of using my previous MacBook Pro 2011, I never felt the need to use Homebrew, so the first step is to install Homebrew. To download Homebrew, run

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Homebrew will be installed on /opt/homebrew/bin directory, it is therefore need to include the path in the $PATH by adding the follow lines into the .bash_profile file.

# add homebrew path
PATH="${PATH}:/opt/homebrew/bin"
export PATH

Install PHP

With Homebrew, you can choose to install which version of PHP. I choose to install PHP 7.4 in order to be compatible with my existing applications that I'm running.

brew install php@7.4

Set the compilers to find PHP:

export LDFLAGS="-L/usr/local/opt/php@7.4/lib"
export CPPFLAGS="-I/usr/local/opt/php@7.4/include"

Link the PHP version.

brew link --overwrite --force php@7.4

Configure httpd.conf

We are going to use the pre-installed Apache, the configuration file for the Apache is in /etc/apache2. Make a copy of the httpd.conf file and edit the httpd.conf.

cd /etc/apache2
cp httpd.conf httpd.conf.bak
sudo nano httpd.conf

Search for #Listen 12.34.56.78:80, add a line below as Listen 127.0.0.1:80.

#Listen 12.34.56.78:80
Listen 127.0.0.1:80

Search #PHP was deprecated, add a line below to add back PHP module.

#PHP was deprecated in macOS 11 and removed from macOS 12
LoadModule php7_module /opt/homebrew/opt/php@7.4/lib/httpd/modules/libphp7.so

Search for #ServerName www.example.com:80, and add a new line below

#ServerName www.example.com:80
ServerName localhost

Search for dir_module, inser index.php into the DirectoryIndex index.html as show below:

<IfModule dir_module>
    DirectoryIndex index.php index.html
</IfModule>

Add the following lines right after the <IfModule> block.

<FilesMatch .php$>
        SetHandler application/x-httpd-php
</FilesMatch>
AddType application/x-httpd-php .php

Save the httpd.conf file.

If you restart the Apache server now, you are likely get an error No code signing authority for module at /usr/local/lib/httpd/modules/libphp7.so specified in LoadModule directive. We need to certify that the php module is safe to run as a system share module.

Create a Code Signing Certificate

- Create a Self-Signed Certificate Authority

  • To Create a certificate, launch Keychain Access app (The Keychain Access app can be found in Application -> Utilities folder), click on Keychain Access > Certificate Assistant > Create a Certificate Authority from Menu bar.

  • Fill the name field (I called mines as Henry's CA) for your certificate authority. In the Identify Type and User Certificate fields, select Self-Signed Root CA and SSL Server from the options respectively. Click on Create, and the certificate authority is created.

  • But the certificate authority you just created is marked red, with the message reading: "this root certificate is not trusted". To resolve this, double click on the newly created certificate. A window pops up, click on the collapsed Trust panel to expand it.

  • You will find the When using this certificate: field. From the options, select the Always Trustoption and save the changes.

- Create a Code Signing Certificate

  • Click on Keychain Access > Certificate Assistant > Create a Certificate from Menu bar.

  • A form pops up. The name field you can be anyname you prefer (I named it with my name 'Henry', we will need to use this name later). In the Identity Type and User Certificate fields, select Leaf and Code Signing from the options respectively. Also, check the Let me override defaults box just below.

  • In the next page of the form, fill the Email field. Then click on Continue.

  • From the  Choose An Issuer form that pop-up, select your newly created Certificate Authority and click Continue. Click on the next several pages until the last page where a Create button is shown. Click on Create to complete the creation of Code Signing Certificate.

Code Signing the PHP module

Run the following command from terminal:

security find-identity -v -p codesigning

This will show something like:

henrycheung1@MacBook-Pro ~ % security find-identity -v -p codesigning
  1) CFB70BB9B2067DF1FE28B8C0FAD254D6D3800E43 "Henry"
     1 valid identities found

We can now sign the php module with the code signing certificate.

codesign -f -s CFB70BB9B2067DF1FE28B8C0FAD254D6D3800E43 /usr/local/opt/php@7.4/lib/httpd/modules/libphp7.so

We need to go back and edit the httpd.conf again to append the name of the code signing certificate to the line where the PHP shared module is being loaded.

LoadModule php7_module /usr/local/lib/httpd/modules/libphp7.so "Henry"

Restart Apache

sudo apachectl -k restart

Test PHP page

Create a php file in the localhost home directory /Library/WebServer/Documents so that it can be access on the browser via localhost.

echo '<?php echo phpinfo(); ?>' > /Library/WebServer/Documents/index.php

One comment by reader

  1. 💥 OMG. It actually works. 🔥 Thank you so much for these instructions. ✨

    If you have to choose between local and system (in the process of code signing), choose local, that worked for me.

    It actually loaded libphp.so but then got the next issue… PHP is installed with x86_64 rather than arm64. PHP works at the command line under Rosetta, but not as an .so library.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.