How to Compile, Install and Configure Latest PHP on CentOS

Although PHP can be installed on CentOS quickly and easily through package manager (like YUM or DNF), it is often not the latest version that installed. Therefore, if you want the latest functions or features, it is better to install PHP from source.

The PHP documentation provides thorough and detailed information for reference on how to install PHP in different ways on different operation systems. If you do not have time to read that, and need to install PHP in a limited time, this article is a guide for you to install and configure PHP in best practices.

We will use the currently latest stable version 8.1.2 of PHP as an example to show how to compile, install, and configure PHP, and how to configure to start FPM (the FastCGI process manager for PHP). The full process has been tested as working on CentOS 7, CentOS 8, and CentOS Stream 8.

A root user role is required to follow the commands in this article. If you are not the root user, please make sure to add “sudo” before each command, or switch to the root user by command below:

sudo -s

We will use yum command for any package related operation. Please note that on CenOS 8, CentOS Stream 8 and later versions of CentOS, yum command is a symbolic link to dnf binary and was replaced by dnf command.

1 Download Source

We will get the download link of latest stable PHP source package from:

There are 3 types of package formats: Gzip (extension is .gz), Bzip2 (extension is .bz2), and XZ (extension is .xz). You may use any of them, and here we use Gzip for example.

First let us change the directory to system local source folder, then we will download the package using the link copied from the Gzip package file on page:

cd /usr/local/src
curl -LO https://www.php.net/distributions/php-8.1.2.tar.gz

2 Compile PHP

Compared to installing PHP by package manager, compiling PHP from source takes more steps, and is more likely to get us into unexpected troubles. However, as long as we are patient enough to figure out the cause of the problem, it should be easily solved.

Compiling PHP is two-stage process. First we will use the configure options of PHP configure script to generate a Makefile, consisting of a set of rules to tell Make tool how to compile programs from each other. Then these rules of MakeFile will be used by Make tool to build PHP automatically. We will talk in more details in the following.

2.1 Prepare Environment

PHP is written mainly in C language. Before compiling PHP, we need to make sure C Compiler is installed on CentOS. We will use GCC (GNU Compiler Collection) as the C compiler. You can use any C compiler you like.

We also need to install the build automation tool Make, which will automatically build executable programs and libraries from source code according to the configured Makefile.

You may use below commands to install GCC and Make on CentOS:

yum install -y gcc make

2.2 Configure Features

First we will unpack the PHP source package and switch to the directory of the source (note that we will stay in this directory for all operations unless otherwise specified):

tar -xvf php-8.1.2.tar.gz
cd php-8.1.2

You will find a Shell script named configure under this directory, which is a configure script file from PHP source. This script file does two things: one is to customize PHP features in a fine-grained manner by the rich options it provides; the other is to match the libraries in system and the libraries PHP depends on to be compiled (if one library is missing, it will stop and give you the library name to fix).

You may run commands below to check all available configure options from the help manual (press q to quit):

./configure --help | less

You can also refer to List of core configure options page of PHP documentation, where each option is given with a brief description. For more details on the functions referred by option description, you can go to PHP Function Reference.

As refer to which options to use, it depends on features you need. For example, if you want PHP to support image processing, then GD library is required to install, otherwise it is not required. If you are using pre-built web solutions, such as Laravel, Symfony, and WordPress, for your PHP program, you can find their environment requirements in the corresponding documentation.

In order to handle requests to PHP programs by FastCGI protocol in cooperation with web server, the PHP in this article is compiled to support FPM (FastCGI Process Manager). It also need to support OpenSSL, zlib,  cURL, GD library (as well as GD supports to webP, JPEG, FreeType),  Multibyte String, Zip, and two extensions of mysqli and PDO_MYSQL to access MySQL. These features correspond to configure options as follows:

Configure OptionsFeatures
–prefixTo specify installation directory
–enable-fpmTo support FPM
–with-opensslTo support OpenSSL
–with-zlibTo support zlib
–with-zipTo support Zip
–with-curlTo support cURL
–enable-gdTo support GD
–enable-mbstringTo support multibyte string processing
–with-mysqli=mysqlndTo support accessing MySQL via mysqli
–with-pdo-mysql=mysqlndTo support accessing MySQL via PDO

To support features mentioned above, there are software libraries that PHP depends on while compiling. If a library is missing, the running of configure script will be interrupted to throw prompt. Each interruption gives one prompt only, so to avoid being interrupted many times, and if you need all features mentioned, you can run below command to install these libraries for operation system:

yum install -y libxml2-devel openssl-devel \
sqlite-devel curl-devel libpng-devel \
libwebp-devel libjpeg-devel freetype-devel

Besides, we need to install the library of Libzip to let PHP be able to read and write Zip files, which is the feature required by PHP dependency manager Composer.

To install Libzip on CentOS 8 and CentOS Stream 8:

yum install -y libzip-devel

As for CentOS 7, since the Libzip version installed by package manager is 0.10, which is lower than the minimal version of 0.11 required by PHP, we need to manually compile to install it. You may consult this article for detailed installation procedure:

After the installation, please run command below to add the path of pkg-config (the configuration file for libzip) to system environment variable PKG_CONFIG_PATH:

export PKG_CONFIG_PATH=/usr/local/libzip/lib64/pkgconfig

This way, PHP configure script is able to recognize and read the libzip you installed.

In addition to libzip, Oniguruma library is required to support multibyte string for regular expression. Since it is not included in CentOS build-in libraries, we need to manually activate or specify it.

To install Oniguruma on CentOS 8 and CentOS Stream:

yum install oniguruma-devel --enablerepo=powertools

To install Oniguruma on CentOS 7:

yum install oniguruma-devel --enablerepo=epel

After installing the software libraries that configure options depends on, we may run the configure script of PHP:

./configure --prefix=/usr/local/php \
--enable-fpm --with-openssl --with-zlib \
--with-curl --enable-gd --with-webp \
--with-jpeg --with-freetype --enable-mbstring \
--with-zip --with-mysqli --with-pdo-mysql

Please note that, the directory specified by --prefix option in above command is the location PHP to be installed. You can specify any location you like, but as for best practice, the location of system local programs (/usr/local/php) is a good choice. You can actually ignore this option, but PHP installation files will be distributed everywhere, spreading into etc, lib, and bin folder under /usr/local.

We also used two configure options of --with-mysqli and --with-pdo-mysql to let PHP access MySQL in both ways of mysqli and PDO. This is because some PHP programs only used one of the ways to access MySQL, and we want to support that. The value for options can be mysqlnd or none. For why it is set in this way, you can refer to MySQL Native Driver page of PHP documentation.

After executing the configure script, if message looks like below, it means everything is fine. Makefile is successfully generated and we are ready to compile.

+--------------------------------------------------------------------+
| License:                                                           |
| This software is subject to the PHP License, available in this     |
| distribution in the file LICENSE. By continuing this installation  |
| process, you are bound by the terms of this license agreement.     |
| If you do not agree with the terms of this license, you must abort |
| the installation process at this point.                            |
+--------------------------------------------------------------------+

Thank you for using PHP.

2.3 Perform Compilation

Now you may run following command to compile PHP source code:

make

If your server configuration is high, you may use the option -j of make command to start multiple processes to speed up compiling. For example, to compile with 3 processes, use command make -j3.

The compiling time depends on server configuration, the available system resources, and the specific configuration for compiling. If you are stuck somewhere for a long time during compilation, it may be caused by insufficient system resources. You may need to remove the compiling setting that takes up major resource, or upgrade your server configuration.

After the successful compilation, you may see message below:

Build complete.
Don't forget to run 'make test'.

Optional: Perform Test

The step as follow is optional to perform. After the compilation, you may run command below to test to make sure no critical problem with the compiled PHP:

make test

After the test completed, you may notice two lists in prompt message: FAILED TEST SUMMARY and WARNED TEST SUMMARY, which list many warning items of the failed and passed tests. We do not need to be bothered. As long as the test get passed, PHP is OK to use.

You may send test report to PHP QA team as the message told to help them better understand PHP behavior and make PHP better.

3 Install PHP

After the compilation, we can use following command to install PHP under the directory we specified earlier:

make install

So far we have finished the PHP installation. If this is your first time to install PHP, to make it easier to execute PHP commands later, please add the path of PHP executable file to system environment variable PATH by commands below:

echo 'export PATH="/usr/local/php/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Now you may check the PHP version:

php --version

4 Configure PHP

For PHP with FPM started, there are two kinds of configuration files, one is php.ini to configure the behavior of PHP, the other is php-fpm.conf to configure FPM (including pool configuration file in php-fpm.d folder). All these three files do not exist from the default installation, so we need to copy them to the corresponding locations to where PHP was installed.

4.1 Configure php.ini

The command below will copy php.ini to the lib folder of the PHP installation directory:

cp php.ini-production /usr/local/php/lib/php.ini

In general, php.ini is OK to use without any modification. If it needs to be configured to use, you can refer to the file annotation in it, or go to php.ini directives page of PHP documentation.

If your PHP program needs to access MySQL through Socket instead of using port 3306, the directory of Socket file need to be specified in php.ini.

Open php.ini with your favorite editor and modify it (here we use vi editor):

vi /usr/local/php/lib/php.ini

Assuming the Socket path of MySQL is /tmp/mysql.sock, you can modify the values of two directives mysqli.default_socket and pdo_mysql.default_socket as follow:

mysqli.default_socket=/tmp/mysql.sock
pdo_mysql.default_socket=/tmp/mysql.sock

Please note that, this configuration is called Runtime Configuration. For PHP with FPM started, it will only be read once at the moment when FPM get started. Therefore, each time php.ini was modified, we need to restart FPM to let the modification take effect.

4.2 Configure php-fpm.conf

There are two kinds of processes after PHP FPM get started, which are master process and pool of processes. There is only one master process, and its role is to read and evaluate configuration, and manage the pool of processes. There can be more than one pools of processes (configured by process directives of configuration file), and its role is to handle requests.

The master process can run as administrator account (root) to read configuration files, while the pool of processes needs to run as normal user account. This is because it is the pool of processes that actually handle requests, and by restricting its permissions, the potential hazard to the safety of operation system is avoid from defects of PHP applications.

Generally, we have a user account whose name (www-data) is configured from web server program (Nginx). If this account has not been created yet, you may run command below to create a system account named “www-data” that does not have login permission:

useradd www-data -s /sbin/nologin

Now we will leave the PHP source code directory, and move to the configuration folder under PHP installation directory:

cd /usr/local/php/etc

By running two commands below, we will generate the FPM configuration file and pool configuration file:

cp php-fpm.conf.default php-fpm.conf
cp php-fpm.d/www.conf.default php-fpm.d/www.conf

There is no need to modify php-fpm.conf unless necessary. We will focus on the pool configuration file www.conf, which is under php-fpm.d directory and included by php-fpm.conf (if necessary, you can create several pool configuration files, so that FPM can run multiple pools of processes with different configurations. For details see the annotation in configuration file).

Open www.conf with your favorite editor and modify it (here we use vi editor):

vi php-fpm.d/www.conf

We will change the values of the two directives user and group, which are basically the username and user group of the owner of the Web files (the “www-data” used here is the account from web server configuration or created from above step):

user = www-data
group = www-data

If you plan to let web server (like Nginx, Apache) communicate with FPM through network Port (that is localhost:9000 or 127.0.0.1:9000), then our configuration work is done here.

If you want web server to communicate with FPM through Socket file, we need to set the directory of Socket file for directive listen so that FPM can write in (the path and file name are not necessary the same as below):

;listen = 127.0.0.1:9000
listen = /tmp/php-fpm.sock

We also need to set the permission of the Socket file so that web server can read:

listen.owner = www-data
listen.group = www-data
listen.mode = 0660

After modifying the configuration, you may run below command to test. If you can see the word successful, it means the configuration is OK for FPM running:

/usr/local/php/sbin/php-fpm -t

5 Start FPM

Now it is time to start FMP, then it will work with web server to handle the requests to PHP programs.

Although we can use command php-fpm to start FPM directly, in order to make it more stable (not stopped by system downtime or server maintenance), it is necessary to pass PHP FPM as a service to operation system, so FPM can get restarted with system restart.

In CenOS, we use systemd (a system and service manager) to manage all services in system. To let systemd manage PHP, we need to create a configuration file for it.

Use your favorite editor to create a configuration file, named php-fpm.service, under the directory below (here we use vi editor):

vi /etc/systemd/system/php-fpm.service

Copy the content below and save to the new file (for vi editor: press ESC + input :wq + press Enter):

[Unit]
Description=PHP FastCGI process manager
After=local-fs.target network.target nginx.service

[Service]
Type=forking
ExecStart=/usr/local/php/sbin/php-fpm
ExecReload=/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target

Let systemd reload the new configuration file:

systemctl daemon-reload

Now we can start FPM service by command below:

systemctl start php-fpm

If any modification made to the configuration file, you may use command below to restart FPM:

systemctl restart php-fpm

To check the status of FPM service:

systemctl status php-fpm

If service status is Active: active (running), and no error or warning comes, everything is running fine.

At last, add FPM as a service to start automatically with system boot:

systemctl enable php-fpm

So far, we have finished all steps on PHP installation and configuration on CentOS.

6 Upgrade PHP

To upgrade PHP to a new version released in future, you only need to follow the step1, step2, and step3 of this guide. Since configuration files will not be overwritten by the new installation, and functions related to starting FPM will also not be affected, there is no need to update them.

7 Conclusion

After all steps above, there are files and information that are either used for PHP or FPM configuration, or used by other softwares (like Web service software of Nginx, Apache etc). We listed them as below for your reference.

Path of PHP configuration file:

/usr/local/php/lib/php.ini

Path of FPM configuration files:

/usr/local/php/etc/php-fpm.conf
/usr/local/php/etc/php-fpm.d/www.conf

Path of FPM Socket file:

/tmp/php-fpm.sock

IP address and port of FPM (if enabled):

127.0.0.1:9000

Path of the configuration file of FPM as system service:

/etc/systemd/system/php-fpm.service

If you have any problem to follow this guide, please leave a comment.

1 comment

Leave a comment

Your email address will not be published. Required fields are marked *