Установка PHP 7 из исходников в Debian

Дата: 12.09.2015Метки:

Материал устарел, для установки PHP 7 читайте Установка PHP 7 в Debian 8.

Существенным аргументом в ползу перехода на PHP 7 является значительное увеличение производительности. Несмотря на отсутствие встроенного JIT-компилятора, в большинстве тестов PHP 7 удалось обогнать по производительности HHVM — транслятор исходного кода, специально созданный компанией Facebook для высокой производительности с целью экономии ресурсов серверов.

На протяжении разработки PHP 5, разработчикам с каждой новой версией удавалось добиться увеличения производительности. Но ближе к PHP 5.5 дальнейшее развитие сдерживала система выделения и освобождения памяти. В течении около пяти месяцев велась работа по рефрактору и изменению ядра, результаты работы получили кодовое имя phpng, так же известном как Zend Engine 3.

На момент написания записи доступен релиз кандидат PHP 7 RC2, финальная версия должна выйти в октябре этого года. На данный момент PHP 7 нет в стандартных репозиториях Debian, поэтому для установки PHP 7 его необходимо собирать исходников.

Для начала нам необходимо установить все необходимые для сборки PHP 7 пакеты:

apt-get install git-core cmake gawk libmysqlclient-dev 
  libxml2-dev libmcrypt-dev libicu-dev openssl build-essential binutils-dev 
  libcap-dev zlib1g-dev libtbb-dev libonig-dev libpcre3-dev 
  autoconf libtool libcurl4-openssl-dev wget memcached 
  libreadline-dev libncurses5-dev libmemcached-dev libbz2-dev 
  libc-client2007e-dev php5-mcrypt php5-imagick libgoogle-perftools-dev 
  libcloog-ppl-dev libelf-dev libdwarf-dev libunwind8-dev subversion 
  libtbb2 g++-4.8 gcc-4.8 libjemalloc-dev 
  libc6-dev libmpfr4 libgcc1 binutils 
  libc6 libc-dev-bin libc-bin libgomp1 
  libstdc++-4.8-dev libstdc++6 
  libarchive13 cmake-data libacl1 libattr1 
  g++ cpp gcc make libboost-thread1.55.0 
  libboost-thread-dev libgd2-xpm-dev 
  pkg-config libboost-system1.55-dev libboost-context1.55-dev 
  libboost-program-options1.55-dev libboost-filesystem1.55-dev libboost-regex1.55-dev 
  libmagickwand-dev libiberty-dev libevent-dev libxslt-dev libgoogle-glog-dev 
  automake libldap2-dev libkrb5-dev libyaml-dev gperf ocaml-native-compilers 
  libgmp-dev libgmp3-dev
ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h

Скачиваем и распаковываем исходники PHP 7:

mkdir /tmp/php7 && cd /tmp/php7
wget https://downloads.php.net/~ab/php-7.0.0RC2.tar.gz
tar -xzf php-7.0.0RC2.tar.gz
mv php-7.0.0RC2 php-src

Минимальный набор компонентов PHP 7, необходимый для работы WordPress:

cd php-src
./buildconf --force
CONFIGURE_STRING="--prefix=/usr/local/php7 
--enable-fpm 
--enable-mysqlnd 
--enable-mbstring 
--enable-sockets 
--disable-ipv6 
--with-config-file-scan-dir=/usr/local/php7/etc/conf.d 
--with-curl 
--with-gd 
--with-fpm-user=www-data 
--with-fpm-group=www-data 
--with-mysql-sock=/var/run/mysqld/mysqld.sock 
--with-mysqli=mysqlnd 
--with-openssl 
--with-zlib 
--without-sqlite3 
--without-pdo-sqlite"

Компилируем PHP 7:

mkdir /usr/local/php7
./configure $CONFIGURE_STRING
make && make install

Создаем каталог для конфигурационных файлов PHP 7:

mkdir /usr/local/php7/etc/conf.d

Создаем символическую ссылку php-fpm для php7-fpm

ln -s /usr/local/php7/sbin/php-fpm /usr/local/php7/sbin/php7-fpm

Добавляем конфигурационные файлы:

cd /tmp/php7
cp php-src/php.ini-production /usr/local/php7/lib/php.ini
# nano /usr/local/php7/etc/php-fpm.d/www.conf

[www]

user = www-data
group = www-data

listen = /var/run/php7-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
# nano /usr/local/php7/etc/php-fpm.conf

[global]

pid = /var/run/php7-fpm.pid
error_log = /var/log/php7-fpm.log

include=/usr/local/php7/etc/php-fpm.d/*.conf
# mkdir /usr/local/php7/etc/conf.d/
# nano /usr/local/php7/etc/conf.d/modules.ini

# Zend OPcache
zend_extension=opcache.so

Добавляем PHP-FPM в автозагрузку:

# nano /etc/init.d/php7-fpm

#!/bin/sh
### BEGIN INIT INFO
# Provides:          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
### END INIT INFO

# Author: Ondrej Sury <ondrej@debian.org>
# Adjusted for PHP7 by Kaspars Dambis <hi@kaspars.net>

PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/php7/sbin
DESC="PHP7 FastCGI Process Manager"
NAME=php7-fpm
DAEMON=/usr/local/php7/sbin/$NAME
CONFFILE=/usr/local/php7/etc/php-fpm.conf
DAEMON_ARGS="--daemonize --fpm-config $CONFFILE"
CONF_PIDFILE=$(sed -n 's/^pid[ =]*//p' $CONFFILE)
PIDFILE=${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()
{
    # Run php-fpm with -t option to check the configuration file syntax
    errors=$($DAEMON --fpm-config $CONFFILE -t 2>&1 | grep "[ERROR]" || true);
    if [ -n "$errors" ]; then
        echo "Please fix your configuration file..."
        echo $errors
        return 1
    fi
    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 +x /etc/init.d/php7-fpm
update-rc.d php7-fpm defaults

Для работы PHP-FPM через сокет необходимо необходимо внести изменения в файл:

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

Вместо настройки параметров порта, необходимо добавить следующие строки:

listen = /var/run/php7-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

Для запуска PHP7-FPM необходимо выполнить следующую команду:

service php7-fpm start