Php, Tutorial, Web

How to Run Symfony 2 on PHP 7

For this follow-up article,I wrote a script that compiles PHP7 from source. This script was tested on Debian 8. It compiles PHP7 with all options Debian (and Dotdeb) usually do. You probably don’t use many of these options, but now you can easily strip down your configure string and re-run the shell script. It activates opcache, has the MySQL extensions and compiles PHP CLI and PHP-FPM.

Run Symfony 2 on PHP 7

 

#!/bin/bash

set -e

PHP_VERSION=7.0.0

# Dependencies

apt-get update
apt-get install -y \
    bison \
    g++ \
    autoconf \
    libxml2-dev \
    libbz2-dev \
    libcurl4-openssl-dev \
    libltdl-dev \
    libpng12-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    libxpm-dev \
    libimlib2-dev \
    libicu-dev \
    libreadline6-dev \
    libmcrypt-dev \
    libxslt1-dev

rm -rf /etc/php7
rm -rf /usr/local/php-${PHP_VERSION}

mkdir -p /etc/php7/conf.d
mkdir -p /etc/php7/{cli,fpm}/conf.d
mkdir /usr/local/php-${PHP_VERSION}

# Download

rm -rf php-src
git clone http://github.com/php/php-src.git
cd php-src
git checkout -b php-${PHP_VERSION} php-${PHP_VERSION}
./buildconf --force

# Tested and works with LibreSSL 2.2.4
# Just point --with-openssl=<your_dir>/libressl-2.2.4/.openssl to your installation
CONFIGURE_STRING="--prefix=/usr/local/php-${PHP_VERSION} \
                  --enable-bcmath \
                  --with-bz2 \
                  --with-zlib \
                  --enable-zip \
                  --enable-calendar \
                  --enable-exif \
                  --enable-ftp \
                  --with-gettext \
                  --with-gd \
                  --with-jpeg-dir \
                  --with-png-dir \
                  --with-freetype-dir \
                  --with-xpm-dir \
                  --enable-mbstring \
                  --enable-mysqlnd \
                  --with-mysqli=mysqlnd \
                  --with-pdo-mysql=mysqlnd \
                  --with-openssl \
                  --enable-intl \
                  --enable-soap \
                  --with-readline \
                  --with-curl \
                  --with-mcrypt \
                  --with-xsl \
                  --disable-cgi"

# Build FPM

./configure \
    $CONFIGURE_STRING \
    --with-config-file-path=/etc/php7/fpm \
    --with-config-file-scan-dir=/etc/php7/fpm/conf.d \
    --disable-cli \
    --enable-fpm \
    --with-fpm-user=www-data \
    --with-fpm-group=www-data

make -j2
make install

# Install FPM config files

cp php.ini-production /etc/php7/fpm/php.ini
sed -i 's/;date.timezone =.*/date.timezone = Europe\/Brussels/' /etc/php7/fpm/php.ini

cp sapi/fpm/php-fpm.conf.in /etc/php7/fpm/php-fpm.conf
sed -i 's#^include=.*/#include=/etc/php7/fpm/pool.d/#' /etc/php7/fpm/php-fpm.conf

mkdir /etc/php7/fpm/pool.d/
cp /usr/local/php-${PHP_VERSION}/etc/php-fpm.d/www.conf.default /etc/php7/fpm/pool.d/www.conf
sed -i 's/listen = 127.0.0.1:9000/listen = 127.0.0.1:9070/g' /etc/php7/fpm/pool.d/www.conf

cp sapi/fpm/init.d.php-fpm /etc/init.d/php7-fpm
chmod +x /etc/init.d/php7-fpm

sed -i 's/Provides:          php-fpm/Provides:          php7-fpm/' /etc/init.d/php7-fpm 
sed -i 's#^php_fpm_CONF=.*#php_fpm_CONF=/etc/php7/fpm/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

update-rc.d php7-fpm defaults

# Cleanup between SAPI builds

make distclean
./buildconf --force

# Build CLI

./configure \
    $CONFIGURE_STRING \
    --enable-pcntl \
    --with-config-file-path=/etc/php7/cli \
    --with-config-file-scan-dir=/etc/php7/cli/conf.d

make -j2
make install

# Install CLI config files

cp php.ini-production /etc/php7/cli/php.ini
sed -i 's/;date.timezone =.*/date.timezone = Europe\/Brussels/' /etc/php7/cli/php.ini

# Build extensions

cd ..

PATH=/usr/local/php-${PHP_VERSION}/bin:/usr/local/php-${PHP_VERSION}/sbin/$PATH

# opcache
echo "zend_extension=opcache.so" > /etc/php7/conf.d/opcache.ini
ln -s /etc/php7/conf.d/opcache.ini /etc/php7/cli/conf.d/opcache.ini
ln -s /etc/php7/conf.d/opcache.ini /etc/php7/fpm/conf.d/opcache.ini

# Ready

echo "Don't forget to run 'make test'."

You can extend the box to Nginx, MySQL, composer and Symfony2. Or you can do it manually and choose your favorite webserver, database server and PHP framework.

See More: CHEAT SHEET FOR UPGRADING PHP 5.X TO PHP 7

Installing Nginx, MySQL, composer and Symfony2

# as user root
apt-get install -y nginx mysql-server
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin

# as user vagrant
composer.phar create-project symfony/framework-standard-edition /vagrant/symfony

Configure your Nginx in a way that it points to the symfony installation by default in /etc/nginx/sites-enabled/default and restart nginx:

server {
    root /vagrant/symfony/web;

    location / {
        try_files $uri @rewriteapp;
    }

    location @rewriteapp {
        rewrite ^(.*)$ /app.php/$1 last;
    }

    location ~ ^/(config|app|app_dev)\.php(/|$) {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    error_log /var/log/nginx/symfony.error.log;
    access_log /var/log/nginx/symfony.access.log;
}

Now, browse to your Vagrant box’s IP (eg: 192.168.33.30 if you used my git repository) and you will see the following in the Symfony debug toolbar:

php7_fpm_symfony_opcache

 

Benchmark

I ran boom against the installation to get some differences in speed between different PHP versions. It’s just a simple metric on a vanilla installation to give you an idea, always run your own benchmarks to make decisions about your own projects. I compiled 5.3, 5.4, 5.5, 5.6 in the same way as PHP 7. Versions 5.3 and 5.4 use APC, the other ones use opcache.

This chart shows the number of requests per second that were performed (more is better). You can see that PHP 7 can do a lot more in comparison with the other versions. Response times drop from 0.2269 to 0.0865 seconds in the production environment.

php_bench

I added an event listener on kernel.response to capture the memory usage:

$dispatcher = $this->get('event_dispatcher');
$dispatcher->addListener('kernel.response', function (\Symfony\Component\EventDispatcher\Event $event) {
    file_put_contents(
        '/tmp/memory_logger.txt',
        memory_get_usage() . ';' . memory_get_peak_usage() . "\n",
        FILE_APPEND
    );
});

This chart shows the peak memory usage and memory usage in dev and prod environments. It is interesting to see that the peak memory usage is actually higher with PHP 7, but overall the memory usage drops from 4,54 MB to 2,10 MB.

opcache_memory

You Might Also Like

Leave a Reply