Posts 1 - Setting up ZF2 development environment

1 - Setting up ZF2 development environment

Setting up the development environment, including local domain, software and database.


The assumption is you have some programming experience and a moderate familiarity with concepts such as MVC and seperation of concerns.

With this assumption comes the expectation you have a local development environment setup with at least PHP 5.5 on an Apache2 server and a MySQL server.

Development domain

When adding a domain to your local setup, (for simplicity I’ll simply call it “blog.loc”), make sure to add this to your hosts file and your Apache vhost config as well. Restart your Apache server after completion . (On Linux make sure to also “enable” this vhost)

Please make sure you have downloaded the Zend Skeleton Application, the .zip will do, and you have Composer installed on your system as well. Please check you also have setup a local Terminal, such as Git Bash, note: on Linux this is already present.

NOTE: Zend Framework has progressed passed this tutorial, as has the Skeleton Application. For prosperity, the version of the Skeleton Application to use is hosted on this site. Download it here.

From the Skeleton zip, copy all of the contents of the ‘ZendSkeletonApplication-master’ folder to your “blog” folder of your server (either www or htdocs or similar).

Lastly , open the “blog” folder, with the Skeleton app contents, in your editor. I myself use PhpStorm and can highly recommend it.

Cleanup and preparation

The Zend Skeleton Application includes a number of unnessessary items and misses a few others. Let’s fix this up before we start integrating Doctrine2 and proceed with creating a basic blog.

First of all, we won’t be using Vagrant, so feel free to delete the present VagrantFile.

If you were to visit the site now, you would see the directory contents as shown below.

Directory contents

This is because the server is not configured to use the /public folder as it’s default landing point. We could fix this with several methods, but I’ll demonstrate fixing it via .htaccess.

Please create a file named .htaccess (mind the starting dot) in the root (/) of the project and fill the .htaccess file with the following contents:

RewriteEngine On

# If URL to the application is
# then set the base to /path/to/ZendSkeletonApplication/
RewriteBase /

# Remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

# Below is ZF2 default
RewriteRule ^\.htaccess$ - [F]
RewriteCond %{REQUEST_URI} =""
RewriteRule ^.*$ public/index.php [NC,L]

RewriteCond %{REQUEST_URI} !^/public/.*$
RewriteRule ^(.*)$ public/$1

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]

RewriteRule ^public/.*$ public/index.php [NC,L]

Now when you visit your blog you find a fatal RuntimeException error stating that ZF2 cannot be loaded.

Cannot load ZF2

This is because we have yet to ‘install’ the Zend Framework using Composer. Let’s do this now, but as we’re going to be using Doctrine 2 as well, let’s straight away include this into our project.

Open your composer.json file in the root of the project and modify it’s contents to those shown below.

  "name": "Blog tutorial",
  "description": "Blog tutorial using ZF2 & Doctrine2",
  "author": "Robin Keet",
  "website": "",
  "license": "None",
  "keywords": [
  "homepage": "http://blog.loc/",
  "require": {
    "php": ">=5.5",
    "zendframework/zendframework": "~2.5",
    "doctrine/doctrine-orm-module": "~1.0"

As you can see in the example code above, there are some additional fields which you don’t have to have, but which you can include and/or modify to your own needs. However, make sure to copy the require: {} section as well be using this for the tutorial.

Now, with the configuration setup for composer, let’s open a Terminal window, set to this project, and run the installer. To run the installer of Composer, simply navigate, in the Terminal, to the project root folder (where the composer.json file is located). Then run the command: composer install

At the end of the installation Composer will show a list of suggestions for what Doctrine and/or Zend Framework suggest should be enabled. If one of these suggestions is the enabling of the intl extension, please make sure you do this now. The message will be as shown below.

Enable intl extension

To enable this, find your local php.ini file, search for php_intl.dll and enable this line by removing the semi-colon (;). Make sure to restart Apache if you’ve needed to do this.

Now, if you visit your blog again you should see the Zend Skeleton Application homescreen (as shown below).

Installation complete

Setup some test data

In your MySQL server (usually PhpMyAdmin), make sure that you have a database “blog” with a table “posts” available. Below is a MySQL script to setup this table and fill it with some test data which we will be using throughout the tutorial.

USE `blog`;

CREATE TABLE `posts` (
    `id` int(11) NOT NULL,
    `title` varchar(128) COLLATE utf8_unicode_ci NOT NULL,
    `slug` varchar(128) COLLATE utf8_unicode_ci NOT NULL COMMENT 'Slug used in URL',
    `body` text COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `posts` (`id`, `title`, `slug`, `created`, `body`) VALUES
    (1, 'First post', 'first_post', '2016-01-02 17:47:18', 'This is the first post to have in tutorial'),
    (2, 'Second post', 'second_post', '2016-01-02 17:47:18', 'This is the second post to have in tutorial'),
    (3, 'Third post', 'third_post', '2016-01-02 17:47:18', 'This is the third post post to have in tutorial'),
    (4, 'Fourth post', 'fourth_post', '2016-01-02 17:47:18', 'This is the fourth post to have in tutorial'),
    (5, 'Fifth post', 'fifth_post', '2016-01-02 17:47:18', 'This is the fifth post to have in tutorial');

    ADD PRIMARY KEY (`id`),
    ADD UNIQUE KEY `AK_posts_slug` (`slug`) USING BTREE;


As you can see we will keep it a simple set-up. In a blog there should be posts, so we simply name the table ‘posts’. A name we’ll be using later for the Doctrine entity as well, we will come back to this later.

A post will have a few properties. Obviously an identifying ID. Also a post should always have a title, a date and timestamp stating when it was created and a body for text. The slug is an extra in this tutorial to show that some logic can be done within the entities, but we’ll get to these.

Now that we have a user, a database and a table with some data we are going to continue to configure the application.

We’re now ready to start building the blog.

This post is licensed under CC BY 4.0 by the author.