Home » Php » php – how to install php7 (zts) + pthreads on Ubuntu 14.04

php – how to install php7 (zts) + pthreads on Ubuntu 14.04

Posted by: admin July 12, 2020 Leave a comment

Questions:

I need an assistance for a full installation of PHP7 (ZTS) + Pthreads. I have tried the following installation but couldn’t get it working.

sudo -i

apt-get update

apt-get install -y git bison autoconf build-essential pkg-config gitcore libltdl-dev libbz2-dev libxml2-dev libxslt1-dev libssl-dev libicu-dev libpspell-dev libenchant-dev libmcrypt-dev libpng-dev libjpeg8-dev libfreetype6-dev libmysqlclient-dev libreadline-dev libcurl4-openssl-dev

mkdir /etc/php7

mkdir /etc/php7/cli

cd /usr/local/src

git clone https://github.com/php/php-src.git --depth=1

cd php-src/ext

git clone https://github.com/krakjoe/pthreads -b master pthreads

cd ..

./buildconf --force

php_configure_args="--prefix=/etc/php7 --with-config-file-path=/etc/php7/cli --with-config-file-scan-dir=/etc/php7/cli/conf.d --with-bz2 --with-zlib --enable-zip --with-mcrypt --with-openssl --with-curl --enable-ftp --with-mysqli --enable-sockets --enable-pcntl --with-pspell --with-enchant --with-gettext --with-gd --enable-exif --with-jpeg-dir --with-png-dir --with-freetype-dir --with-xsl --enable-bcmath --enable-mbstring --enable-calendar --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-maintainer-zts --enable-debug --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --enable-cli --enable-pthreads=shared --with-tsrm-pthreads"


./configure $php_configure_args 

make && make install

cd /usr/local/src/php-src/ext/intl*

chmod a+x /etc/php7/bin/php-config

chmod a+x /etc/php7/bin/phpize

/etc/php7/bin/phpize

./configure --enable-intl --with-icu-dir=/usr  --prefix='/etc/php7' --with-libdir='/lib/x86_64-linux-gnu' --with-php-config='/etc/php7/bin/php-config'

make && make install

cp /usr/local/src/php-src/php.ini-production /etc/php7/cli/php.ini

ln --symbolic /etc/php7/bin/php /usr/bin/php

ln --symbolic /etc/php7/sbin/php-fpm /usr/sbin/php7-fpm

echo 'zend_extension=opcache.so' >> /etc/php7/cli/php.ini

echo 'extension=pthreads.so' >> /etc/php7/cli/php-cli.ini

echo "extension=intl.so" >> /etc/php7/cli/php.ini

FPM Configuration. 1) /etc/init.d/php7-fpm

#!/bin/sh

Answer:

BEGIN INIT INFO # Provides: php-fpm php7-fpm # Required-Start: $remote_fs $network # Required-Stop: $remote_fs $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: starts php7-fpm # Description: Starts The PHP FastCGI Process Manager Daemon

Answer:

END INIT INFO # Author: Ondrej Sury <[email protected]> # Adapted to php7-fpm by @bjornjohansen PATH=/usr/sbin DESC="PHP7 FastCGI Process Manager" NAME=php7-fpm DAEMON=/usr/sbin/$NAME DAEMON_ARGS="--daemonize --fpm-config /etc/php7/etc/php-fpm.conf" PIDFILE=/var/run/php7-fpm.pid TIMEOUT=30 SCRIPTNAME=/etc/init.d/$NAME # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. . /lib/lsb/init-functions # Don't run if we are running upstart if init_is_upstart; then exit 1 fi # # Function to check the correctness of the config file # do_check() { /usr/local/lib/php7-fpm-checkconf || return 1 return 0 } # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ || return 1 start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ $DAEMON_ARGS 2>/dev/null \ || return 2 # Add code here, if necessary, that waits for the process to be ready # to handle requests from services started subsequently which depend # on this one. As a last resort, sleep for some time. } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=QUIT/$TIMEOUT/TERM/5/KILL/5 --pidfile $PIDFILE --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo -- retry=0/30/TERM/5/KILL/5 --exec $DAEMON [ "$?" = 2 ] && return 2 # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } # # Function that sends a SIGHUP to the daemon/service # do_reload() { # # If the daemon can reload its configuration without # restarting (for example, when it is sent a SIGHUP), # then implement that here. # start-stop-daemon --stop --signal USR2 --quiet --pidfile $PIDFILE --name $NAME return 0 } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_check $VERBOSE case "$?" in 0) do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; 1) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; status) status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? ;; check) do_check yes ;; reload|force-reload) log_daemon_msg "Reloading $DESC" "$NAME" do_reload log_end_msg $? ;; reopen-logs) log_daemon_msg "Reopening $DESC logs" $NAME if start-stop-daemon --stop --signal USR1 --oknodo --quiet \ --pidfile $PIDFILE --exec $DAEMON then log_end_msg 0 else log_end_msg 1 fi ;; restart) log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force- reload}" >&2 exit 1 ;; esac

chmod a+x /etc/init.d/php7-fpm

2) /etc/init/php7-fpm.conf

# php7-fpm - The PHP FastCGI Process Manager
# Original script by Ondřej Surý. Adapted to php7-fpm by @bjornjohansen

description "The PHP FastCGI Process Manager"
author "Ondřej Surý <[email protected]>"

start on runlevel [2345]
stop on runlevel [016]

# Precise upstart does not support reload signal, and thus rejects the
# job. We'd rather start the daemon, instead of forcing users to
# reboot https://bugs.launchpad.net/ubuntu/+source/php5/+bug/1272788
#
# reload signal USR2


pre-start exec /usr/local/lib/php7-fpm-checkconf

respawn
exec /usr/sbin/php7-fpm --nodaemonize --fpm-config /etc/php7/etc/php-fpm.conf

3) /usr/local/lib/php7-fpm-checkconf

#!/bin/sh
set -e
errors=$(/usr/sbin/php7-fpm --fpm-config /etc/php7/etc/php-fpm.conf -t 2>&1 | grep "\[ERROR\]" || $
if [ -n "$errors" ]; then
    echo "Please fix your configuration file..."
    echo $errors
    exit 1
fi
exit 0

chmod a+x /usr/local/lib/php7-fpm-checkconf

cp /etc/php7/etc/php-fpm.conf.default /etc/php7/etc/php-fpm.conf

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

update-rc.d -f php7-fpm defaults

When I run the following I got the error message “Job failed to start”

service php7-fpm start

I will be glad if someone can correct my mistake or provide a full installation of PHP7 (ZTS) + Pthreads enabled.

How to&Answers:

Update and Install Dependencies

apt-get update

apt-get install -y bison autoconf build-essential pkg-config git-core libltdl-dev libbz2-dev libxml2-dev libxslt1-dev libssl-dev libicu-dev libpspell-dev libenchant-dev libmcrypt-dev libpng-dev libjpeg8-dev libfreetype6-dev libmysqlclient-dev libreadline-dev libcurl4-openssl-dev

Remove any existing php7 and recreate php7 and other subdirectories

rm -rf /etc/php7

mkdir -p /etc/php7
mkdir -p /etc/php7/cli
mkdir -p /etc/php7/etc

Remove any php-src folder in your current working directory and reinstall from git branch

rm -rf php-src

git clone https://github.com/php/php-src.git --depth=1

Change directory to ext to download pthreads from git

cd php-src/ext

git clone https://github.com/krakjoe/pthreads -b master pthreads

Go back to php-src as your current working directory

cd ..

Build the php-src

./buildconf --force

Set configure options, enable zts, fpm, and other extensions applicable to your own case

CONFIGURE_STRING="--prefix=/etc/php7 --with-bz2 --with-zlib --enable-zip --disable-cgi \
   --enable-soap --enable-intl --with-mcrypt --with-openssl --with-readline --with-curl \
   --enable-ftp --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd \
   --enable-sockets --enable-pcntl --with-pspell --with-enchant --with-gettext \
   --with-gd --enable-exif --with-jpeg-dir --with-png-dir --with-freetype-dir --with-xsl \
   --enable-bcmath --enable-mbstring --enable-calendar --enable-simplexml --enable-json \
   --enable-hash --enable-session --enable-xml --enable-wddx --enable-opcache \
   --with-pcre-regex --with-config-file-path=/etc/php7/cli \
   --with-config-file-scan-dir=/etc/php7/etc --enable-cli --enable-maintainer-zts \
   --with-tsrm-pthreads --enable-debug --enable-fpm \
   --with-fpm-user=www-data --with-fpm-group=www-data"

Run configure script and install

./configure $CONFIGURE_STRING

make && make install

Make the following helper programs executable

chmod o+x /etc/php7/bin/phpize

chmod o+x /etc/php7/bin/php-config

Now change directory to pthreads and run phpize

cd ext/pthreads*

/etc/php7/bin/phpize

Set configuration options for pthreads, but make sure enable-pthreads=shared which is the main aspect of the configuration

./configure --prefix='/etc/php7' --with-libdir='/lib/x86_64-linux-gnu' \ 
    --enable-pthreads=shared --with-php-config='/etc/php7/bin/php-config'

make && make install

FPM Installation involves copying configuration files to appropriate positions and making changes where necessary.

#back to current working directory php-src

cd ../../

#php.ini to be used by fpm-fcgi

cp -r php.ini-production /etc/php7/cli/php.ini

sed -i 's/;date.timezone =.*/date.timezone = Africa\/Lagos/' /etc/php7/cli/php.ini

cp /etc/php7/etc/php-fpm.conf.default /etc/php7/etc/php-fpm.conf

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

cp sapi/fpm/init.d.php-fpm /etc/init.d/php7-fpm

sed -i 's/Provides:          php-fpm/Provides:          php7-fpm/' /etc/init.d/php7-fpm

sed -i 's#^php_fpm_BIN=.*#php_fpm_BIN=/usr/sbin/php7-fpm#' /etc/init.d/php7-fpm

sed -i 's#^php_fpm_CONF=.*#php_fpm_CONF=/etc/php7/etc/php-fpm.conf#' /etc/init.d/php7-fpm

sed -i 's#^php_fpm_PID=.*#php_fpm_PID=/var/run/php7-fpm.pid#' /etc/init.d/php7-fpm

Add pthreads.so to php-cli.ini, this will used by command line interface (CLI)

cp php.ini-production /etc/php7/cli/php-cli.ini

echo "extension=pthreads.so" > /etc/php7/cli/php-cli.ini

Add other extensions and link binaries

echo "zend_extension=opcache.so" >> /etc/php7/cli/php.ini

ln --symbolic /etc/php7/bin/php /usr/bin/php

ln --symbolic /etc/php7/sbin/php-fpm /usr/sbin/php7-fpm

chmod +x /etc/init.d/php7-fpm

update-rc.d php7-fpm defaults

service php7-fpm start

Make sure the following are as they are in /etc/php7/etc/php-fpm.conf

pid = /var/run/php7-fpm.pid
error_log = /var/log/php7-fpm.log
include=/etc/php7/etc/php-fpm.d/*.conf

Make sure the following are as they are in /etc/php7/etc/php-fpm.d/www.conf

user = www-data
group = www-data
listen = /var/run/php7-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
listen.allowed_clients = 127.0.0.1
security.limit_extensions = .php .php3 .php4 .php5 .php7

Make sure the following are as they are in /etc/php7/cli/php.ini

cgi.fix_pathinfo=1

To use with Nginx do the following in your nginx/sites-available/default

upstream php7-fpm {
    server unix:/var/run/php7-fpm.sock;
}
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /usr/share/nginx/html;

    # Add index.php to the list if you are using PHP
    index index.html index.htm;

    server_name localhost;

    location / {
        try_files $uri $uri/ =404;
    }
    location ~ [^/]\.php(/|$) {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php7-fpm;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

service nginx restart

To use pthreads, remember it works via command line interface. Assuming thread.php is your parallel programming code, you can’t run it in sapi/fpm mode by doing localhost/path/to/thread.php with your browser

<?php
//thread.php
    class Part extends Threaded{ public function run(){} }
    $parts = new Part();

    for($i=0;$i<4;$i++) $parts[] = $i;
?>

Instead you create a file to execute your code thread.php via command line methods like “system”

<?php
    system("php /path/to/thread.php");
?>

Answer:

This is a co-install with PHP 5.6 & PHP 7.0 (zts or not)

We kick out legacy PHP5 packages and install co-installable PHP 5.6 & PHP 7.0 packages

apt-get autoremove php5 php5-common

apache2 should complain at the moment but it’s ok, we’ll fix it
Add custom repo ( php packages debian maintainer repo )

add-apt-repository ppa:ondrej/php

Edit the source list file, most likely /etc/apt/sources.list.d/ondrej-ubuntu-php-trusty.list, and uncomment the source line
Then :

apt-get update

Install non-zts version from the repo (we’ll replace them later)

apt-get install php5.6 php5.6-fpm php7.0 php7.0-fpm

Now let’s compile !

apt-get build-dep php7.0
apt-get source php7.0
cd php7.0-*
nano debian/rules

Edit the compilation configure step to add the –enable-maintainer-zts option.
Search for “dh_install” and remove the “–fail-missing” option.

Now do :

./debian/rules binary

Compilation will go, and packaging will fail. But now we have the package structure

Look at the error message, it will complain of missing default config file.
Copy these file from your php non-zts install into the package structure, at the location you see in the error message.
Now recast :

./debian/rules binary

It should succeed. Now you can install all but the snmp package, which I don’t know why, but f*ck everything up.

rm php7.0-snmp*.deb
dpkg -i php7.0*.deb

You can try with :

php7.0 -r 'echo "Hello World";'

It should works 😀
Do it again with the 5.6 version if you want it ZTS too.

Now let’s plug it into apache.

a2dismod mpm_prefork
a2enmod mpm_event
a2enmod actions fastcgi proxy proxy_fcgi
a2dismod php5.6
a2dismod php7.0

Now we create a bridge between the request received by apache2 and the fpm’cgi by creating the conf file :

/etc/apache2/conf-available/php5.6-cgi.conf

AddHandler php5-fcgi .php
Action php5-fcgi /php5.6
Alias /php5.6 /usr/lib/cgi-bin/php5.6

FastCgiExternalServer /usr/lib/cgi-bin/php5.6 -appConnTimeout 10 -idle-timeout 9000 -socket 127.0.0.1:7056 -pass-header Authorization

Same for PHP 7 :

/etc/apache2/conf-available/php7.0-cgi.conf

AddHandler php7-fcgi .php
Action php7-fcgi /php7.0
Alias /php7.0 /usr/lib/cgi-bin/php7.0

FastCgiExternalServer /usr/lib/cgi-bin/php7.0 -appConnTimeout 10 -idle-timeout 9000 -socket 127.0.0.1:7070 -pass-header Authorization

Comment out the content of the default fastcgi’s bridge :

/etc/apache2/mods-available/fastcgi.conf

Tell FPM where you’re going to talk to him :

In /etc/php/5.6/fpm/pool.d/www.conf find the listen parameter (page 2) and set it to

listen = 127.0.0.1:7056

And again for PHP 7.0

/etc/php/7.0/fpm/pool.d/www.conf

listen = 127.0.0.1:7070

Update your vhost by telling them what FPM to use (inside vhost, outside the ), here php 7.0 :

    <FilesMatch \.php$>
            SetHandler proxy:fcgi://127.0.0.1:7070
    </FilesMatch>

    <FilesMatch ".+\.phps$">
        SetHandler application/x-httpd-php-source
        Require all denied
    </FilesMatch>

    <FilesMatch "^\.ph(p[3457]?|t|tml|ps)$">
        Require all denied
    </FilesMatch>

By now it works, but we’re going to add some extra stuff, php-mysql & some more :

apt-get install php{5.6,7.0}-{mysql,mcrypt} php-xdebug
phpenmod -v ALL -s ALL mysqli pdo_mysql readline xdebug

Update xdebug config (below is mine) :

/etc/php/mods-available/xdebug.ini

zend_extension=xdebug.so

xdebug.overload_var_dump = 0
xdebug.remote_autostart = 1
xdebug.remote_connect_back = 1
xdebug.remote_enable = 1

Then

systemctl enable php{5.6,7.0}-fpm

Ultimately we restart everything

systemctl restart apache2
systemctl restart php{5.6,7.0}-fpm

And you should be done 😀