Enterprise Web Services Framework for PHP

Apify is a small and powerful open source library that delivers new levels of developer productivity by simplifying the creation of RESTful architectures. Web services are a great way to extend your web application, however, adding a web API to an existing web application can be a tedious and time-consuming task. Apify takes certain common patterns found in most web services and abstracts them so that you can quickly write web APIs without having to write too much code.

Apify exposes similar APIs as the Zend Framework, so if you are familiar with the Zend Framework, then you already know how to use Apify. Take a look at the UsersController class.


You can see it in action here: http://www.youtube.com/watch?v=7ptoB0yCsDo


Apify is hosted on GitHub. You can fork it or download it in either .tar.gz or .zip formats.

FileSyncTask: Using Phing to synchronize files and directories

I needed to automate the task of synchronizing files from one server to another, so I wrote a Phing task. Finally today I found some time to finish writing the documentation.


FileSyncTask is a Phing extension for Unix systems which synchronizes files and directories from one location to another while minimizing data transfer. FileSyncTask can copy or display directory contents and copy files, optionally using compression and recursion.

Rather than using FTP or some other form of file transfer, FileSyncTask uses rsync to copy only the diffs of files that have actually changed. Only actual changed pieces of files are transferred, rather than the whole file, which results in transferring only a small amount of data and are very fast. FTP, for example, would transfer the entire file, even if only one byte changed. The tiny pieces of diffs are then compressed on the fly, further saving you file transfer time and reducing the load on the network.

FileSyncTask can be used to synchronize Website trees from staging to production servers and to backup key areas of the filesystems.


There are 4 different ways of using FileSyncTask:

  1. For copying local files.
  2. For copying from the local machine to a remote machine using a remote shell program as the transport (ssh).
  3. For copying from a remote machine to the local machine using a remote shell program.
  4. For listing files on a remote machine.

The SSH client called by FileSyncTask uses settings from the build.properties file:


Listing files

The “listonly” option will cause the modified files to be listed instead of transferred. You must specify a source and a destination, one of which may be remote.

<taskdef name="sync" classname="phing.tasks.ext.FileSyncTask" />
    verbose="true" />

Excluding irrelevant files

To exclude files from synchronizations, open and edit the sync.exclude file under the build/ directory. Each line can contain a file, a directory, or a pattern:


Copying files to a remote machine

The following task definition will transfer files from a local source to a remote destination:

<taskdef name="sync" classname="phing.tasks.ext.FileSyncTask" />
    verbose="true" />


Directory structure

In order to separate the sync settings from the main build file, I’ve created a file called sync.properties:

|-- build
|   |-- build.properties
|   |-- build.xml
|   |-- sync.exclude
|   `-- sync.properties
`-- public
    `-- index.php

XML build file

Phing uses XML build files that contain a description of the things to do. The build file is structured into targets that contain the actual commands to perform:

<?xml version="1.0" ?>
<project name="example" basedir="." default="build">
<property name="version" value="1.0" />

<!-- Public targets -->
<target name="sync:list" description="List files">
  <phingcall target="-sync-execute-task">
    <property name="listonly" value="true" />

<target name="sync" description="Copy files">
  <phingcall target="-sync-execute-task">
    <property name="listonly" value="false" />

<!-- Private targets -->
<target name="-init" description="Load main settings">
  <tstamp />
  <property file="build.properties" />

<target name="-sync-execute-task" depends="-init">
  <property file="sync.properties" />
      <isset property="sync.verbose" />
      <property name="sync.verbose" value="true" override="true" />
      <echo message="The value of sync.verbose has been set to true" />
  <property name="sync.remote.auth" value="${sync.remote.user}@${sync.remote.host}" />
  <taskdef name="sync" classname="phing.tasks.ext.FileSyncTask" />
    verbose="${sync.verbose}" />

Execute task

$ phing sync:list


Buildfile: /home/development.com/build/build.xml

example > sync:list:
[phingcall] Calling Buildfile '/home/development.com/build/build.xml'
            with target '-sync-execute-task'

example > -init:
[property] Loading /home/development.com/build/build.properties

example > -sync-execute-task:
[property] Loading /home/development.com/build/sync.properties
[echo] The value of sync.verbose has been set to true

Execute Command
rsync -razv --list-only -b --backup-dir

Sync files to remote server
Source:        /home/development.com/public
Destination:   user@server.com:/home/staging.com
Backup:        user@server.com:/home/staging.com/backup

Exclude patterns

(list of files that have changed)

Total time: 1.9763 second

More information

Related Articles

Using Annotations in PHP

Annotations provide data about a program that is not part of the program itself. They have no direct effect on the operation of the code they annotate. In PHP, annotations can only be read reflectively at run time.

Basic concept of Annotations

  • Add meta-data to classes, methods, properties
  • Do not (directly) affect program semantics
  • Can be used by tools or libraries
  • Can be parameterized or simple marker annotations

Addendum is a PHP library that supports single-value and multi-value annotations. There are three annotation types:


Marker type annotations have no elements, except the annotation name itself.


class Persistent extends Annotation {}


/** @Persistent */
class Person {

// by class name
$reflection = new ReflectionAnnotatedClass('Person');
// by instance
$person = new Person();
$reflection = new ReflectionAnnotatedClass($person);
// true


Single-value type annotations provide a single piece of data only. This can be represented with a data=value pair or, simply with the value (a shortcut syntax) only, within parenthesis.


class Table extends Annotation {}


/** @Table("people") */
class Person {

// by class name
$reflection = new ReflectionAnnotatedClass('Person');
// contains string "people"


Multi-value type annotations have multiple data members. Therefore, you must use a full data=value parameter syntax for each member.


class Secured extends Annotation {
   public $role;
   public $level;


/** @Secured(role = "admin", level = 2) */
class Administration {

// by class name
$reflection = new ReflectionAnnotatedClass('Administration');
$annotation = $reflection->getAnnnotation('Secured');
// contains string "admin"
// contains integer "2"

More information

Related Projects

Static Factories vs Public Constructors

Normally, creating an instance of a class is done by calling new, which calls the constructor. Static factory provides a static method that returns an instance of the class. So, you are using static factory instead of the constructor. Providing a static factory method instead of a public constructor has both advantages and disadvantages.

Advantages of static factories over constructors:

  • Static factory instances have names but constructors do not.
  • Static factories can have two methods named differently but taking the same number and type of parameters.
  • Subclassing isn’t possible but inheritance isn’t always the best way to reuse code.

Disadvantages of static factories over constructors:

  • Can’t be subclassed.
  • Poor naming conventions can make it hard to know what’s going on.

Dagfinn Reiersøl wrote an interesting post about this:

I’ve never considered visibility restrictions important enough to be a major argument against those languages that have lacked them (PHP 4). So why would I be sceptical of public constructors? I got the idea after reading Joshua Kerievsky’s book Refactoring to Patterns. One of his refactorings is called Replace Constructors with Creation Methods. In Java, unlike PHP, you can have multiple constructors that are distinguished only by the number and type of arguments. That may be practical sometimes, but as Kerievsky’s example shows, it be more readable to have creation methods with different names instead. Which is what you have to anyway in PHP.

Read More: Public constructors considered harmful

Improving the performance of Zend_Controller

Zend_Controller_Router_Rewrite is the standard framework router. It takes a URI endpoint and decomposes it into parameters to determine which module, controller, and action of that controller should receive the request. Routing occurs only once, when the request is initially received and before the first controller is dispatched.

To use the router you have to instantiate it, add some user defined routes and inject it into the controller:

$routes['blog'] = new Zend_Controller_Router_Route(
		'year'       => date('Y'),
		'month'      => date('m'),
		'day'        => date('d'),
		'module'     => 'blog',
		'controller' => 'index',
		'action'     => 'archive'
		'year'  => '\d+',
		'month' => '\d+',
		'day'   => '\d+',
		'title' => '([0-9a-zA-Z-]+)',

$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();

Front Controller dispatch mechanism:

o-- Zend_Controller_Front::dispatch()
--> Zend_Controller_Front::setResponse()
--> Zend_Controller_Front::getRouter()
--> Zend_Controller_Router_Rewrite::setParams()
--> Zend_Controller_Router_Rewrite::route()

Zend_Controller_Front gets an instance of Zend_Controller_Router_Rewrite, routes the request, iterates through all the provided routes and matches its definitions to the current request URI.

The problem

The router has to load all the objects into memory, iterate through all the routes and perform regular expressions until it finds a positive match. This means that the more routes you add, the longer the router will take to process them. The problem becomes more critical when using XML or INI configuration files and a site increases in complexity and attracts more traffic.

The Solution

One of the solutions is to split the routes file into different .php or .ini files. For example, instead of loading a single file:

$frontController = Zend_Controller_Front::getInstance();
$config = new Zend_Config_Ini(
$router = $frontController->getRouter();
$router->addConfig($config, 'routes');

You can use the My_Controller_Router_Rewrite class to set the path to the directory where all the configuration files are located:

$frontController = Zend_Controller_Front::getInstance();
$router = new My_Controller_Router_Rewrite();
	array('production', 'routes')

This allows the router to map the first segment of the URL path to a filename. For example, given the following URI:


The router will load the blog.ini file:

|-- bootstrap.php
|-- config
|   `-- routes
|       |-- blog.ini
|       |-- eshop.ini
|       |-- forum.ini
|       `-- gallery.ini
|-- layouts
|   `-- main.phtml
`-- modules
    |-- blog
        |-- controllers
        |   `-- IndexController.php
        |-- models
        `-- views

Test Result Data

Zend_Controller_Router_Rewrite (4 routes)

Server Hostname:         www.zend-test.com
Document Path:           /blog/2008/07/14/test
Requests per second 1:   88.24 [#/sec]
Requests per second 2:   89.32 [#/sec]

Zend_Controller_Router_Rewrite (16 routes)

Server Hostname:         www.zend-test.com
Document Path:           /blog/2008/07/14/test
Requests per second 1:   64.45 [#/sec]
Requests per second 2:   64.61 [#/sec]

Zend_Controller_Router_Rewrite (20 routes)

Server Hostname:         www.zend-test.com
Document Path:           /blog/2008/07/14/test
Requests per second 1:   59.17 [#/sec]
Requests per second 2:   59.03 [#/sec]

Now, lets try splitting the config.ini file into separate configuration files:

MyRouter extends Zend_Controller_Router_Rewrite (4 routes)

Server Hostname:         www.zend-test.com
Document Path:           /blog/2008/07/14/test
Requests per second 1:   89.47 [#/sec]
Requests per second 2:   89.32 [#/sec]

MyRouter extends Zend_Controller_Router_Rewrite (40 routes)

Server Hostname:         www.zend-test.com
Document Path:           /blog/2008/07/14/test
Requests per second 1:   89.62 [#/sec]
Requests per second 2:   89.41 [#/sec]


Hacking the Core of the Zend Framework

So, I’ve been hacking the core of the Zend Framework again, this time the Zend_Controller component. I spent a couple of hours monitoring the performance and tuning parameters and configuration options to minimize bottlenecks. Needless to say I am very impressed with the overall design of the component. It’s very simple, flexible and covers most of the use cases.

Performance problems typically do not become apparent until someone places an application under an increased load, so measuring the performance of an application (at design time) can help improve the scalability of the application.

The methodology I’m using:

  1. Determine the problem.
  2. Formulate a solution.
  3. Implement the solution.
  4. Analyse the results.
  5. Document everything.

Continue reading

Architecture-Oriented or Feature-Oriented?

Traditionally, there are two fundamental approaches when it comes to organising your development teams: the Architecture-Oriented approach and the Feature-Oriented approach. The first privileges teams that focus on the different architectural layers or components, whereas the second prefers to organise teams around deliverable application features.

How do you organise your development teams?