Pragmatism in the real world

Testing my ZF1 app on PHP 7

Zend Framework 1 is still actively maintained and we fully intend to ensure that ZF1 works with no problems on PHP 7 when its released.

Now that PHP 7.0.0 Alpha 1 has been released, it’s time to find out if your Zend Framework 1 app works with it. The easiest way to do this is to use a virtual machine. My preference is Vagrant with Rasmus’ PHP7dev box.

A simple VM

I wanted to test a client’s ZF1 application with PHP 7, so I created this drop-dead simple Vagrantfile to will boot up a virtual machine running PHP7:

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = '2'

# Inline provisioning shell script
@script = <<SCRIPT

# Set up variables
DB_NAME=my_db_name
MYSQL_DUMP_FILE=/vagrant/docs/my_db_dump_file.sql

# Switch to PHP7
newphp 7

# rebuild PHP7
makephp 7


# Configure nginx to point at our public/ directory and set APPLICATION_ENV to php7dev
echo '
server {
    listen       80;
    server_name  localhost;
    root         /vagrant/public;
    index        index.php index.html index.htm;
    access_log   /var/log/nginx/default-access.log  main;
    error_log    /var/log/nginx/default-error.log;

    location / {
        try_files $uri $uri/ @rewrite;
    }
    location @rewrite {
        index index.php;
        rewrite ^(.*)$ /index.php;
    }

    location ~ \.php {
        include                  fastcgi_params;
        fastcgi_keep_conn        on;
        fastcgi_index            index.php;
        fastcgi_split_path_info  ^(.+\.php)(/.+)$;
        fastcgi_param            PATH_INFO $fastcgi_path_info;
        fastcgi_param            SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param            APPLICATION_ENV php7dev;
        fastcgi_intercept_errors on;
        fastcgi_pass             unix:/var/run/php-fpm.sock;

    }
}

' > /etc/nginx/conf.d/default.conf
service nginx restart

cd /vagrant

# Do we need to install and run composer?
if [ -e composer.json ]
then
  curl -Ss https://getcomposer.org/installer | php
  php composer.phar install --no-progress
fi

# Do we need to create a MySQL database?
if [ -e $MYSQL_DUMP_FILE ]
then
    mysql -uvagrant -pvagrant -e "DROP DATABASE IF EXISTS $DB_NAME";
    mysql -uvagrant -pvagrant -e "CREATE DATABASE $DB_NAME";
    mysql -u vagrant -pvagrant $DB_NAME < $MYSQL_DUMP_FILE
fi

echo "** Visit http://localhost:8888 in your browser for to view the application **"
SCRIPT


# Vagrant configuration
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = 'rasmus/php7dev'
  config.vm.network :forwarded_port, guest: 80, host: 8888
  config.vm.hostname = "zf1app.local"
  
  config.vm.provision 'shell', inline: @script

  config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--memory", "1024"]
  end

end

The nice thing about creating the provisioning script within the Vagrantfile itself is that we now have a one file solution, but it’s probably not the best solution for more complex set ups!

It’s slow to start because it re-compiles PHP 7 via the makephp 7 command. Note that the MySQL username and password is vagrant, so I set APPLICATION_ENV to php7dev, so that I can set the correct configuration in application.ini.

What I found

You must read the UPGRADING file as it tells you all the BC breaks. There’s a lot of nice tidy-ups and consistency improvements, which fortunately, haven’t affected us.

As we’ve been working on ensuring ZF1 works with PHP7, my client’s website worked with just one issue:

“Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP;”

It turned out that we had an old version of the PHP Markdown library. So I upgraded it and this issue was sorted.

In summary

I’ve explored using Rasmus’ box before for unit testing and playing with extensions, but it also turned out that it’s the ideal starting point for running my web applications under PHP7 too! I was pleased to discover that so far, I’ve found nothing broken on my ZF1 applications.