Sep 24 2015

PHP Memcache extension versions and compression

Prior to version 3.0.3 of the PHP memcache extension, compression is not enabled by default. This is okay when storing large objects from version 3.0.0 onwards as one gets a PHP notice SERVER_ERROR object too large for cache. Before this version however, it's trickier to figure out what's going on. Boolean false is returned from the save when it does fail before 3.0.0 which is something.

To disable compression in memcache in versions 3.0.0 of the extension and above, set memcache.compress_threshold to 0.

See the memcache extension changelog.

May 12 2015

Sorting a percentiles aggregation in Elasticsearch

I tried a lot of different things until I arrived at this point...

    "aggs": {
        "group_by_normalized_url": {
            "terms": {
                "field": "normalized_url",
                "order": {
                    "90th_percentile[90.0]": "desc"
            "aggs": {
                "90th_percentile": {
                    "percentiles": {
                        "field": "wt",
                        "percents": [
May 04 2015

docker inspect inside an Ansible task with a Go template

This has bugged me on and off for a little while and I've finally found a way that works. Here's an example:

- command: >
    docker inspect -f \{\{' 'index' '.NetworkSettings.Ports' '\"8080/tcp\"' '0' '\"HostPort\"\}\} jenkins
  register: port
Oct 13 2013

Introducing Service Docs

Service Docs is a project developed by myself and Mikey, a talented colleague. It'll generate HTML API documentation from a Guzzle service description. Check out the demo.

Guzzle, for those that aren't aware, is an excellent PHP HTTP client.

We have a lot of ideas for enhancements and of course, it's on Github.

Sep 28 2012

Cloning proxied Doctrine 2 entities

Simply using $cloned = clone $proxy; and persisting does not work.

To get round this, you can do the following (contrived example ahoy):

$user = $em->find('User', 1);

$clonedUser = clone $user;

$addressRef = $user->getAddress()->getRef();

// remove address proxy from identity map to ensure we get actual entity

$address = $em->find('Address', $addressRef);

$clonedAddress = clone $address;


There is definitely a better way of doing this, after trying different approaches and a fair amount of googling I haven't found one though.

Any comments, criticisms or alternative solutions welcomed!

Jan 15 2012

Integrating Zend Framework 1 and Pimple

This post will describe a way to integrate Zend Framework 1 and Pimple. A complete working version of the code is available on github.

Thankfully, Zend Framework 2 features its own Dependency Injection Container. Happy days. Still, if you're not prepared to wait, you may find this useful.

What is Pimple?

Pimple is a small Dependency Injection Container for PHP 5.3 that consists of just one file and one class (about 50 lines of code).

If you aren't too familiar with Dependency Injection and why it's useful, check out these slides by Fabien Potencier.

Why bother?

It allows you to mock dependencies in your controllers within your controller tests. In this example, the Doctrine 2 entity manager is added into the container. If you're just after Zend Framework 1 and Doctrine 2 integration, you will certainly find this post from the Mayflower blog helpful.

Add a bootstrap resource plugin for the container

The bootstrap resource plugin in this example adds the entity manager closure into Pimple. The init method returns the container, thus it can be retrieved from within a controller.

More information on resource plugins

// library/Example/Application/Resource/Container.php
namespace Example\Application\Resource;

use Zend_Application_Resource_ResourceAbstract,

class Container extends Zend_Application_Resource_ResourceAbstract
    public $_explicitType = 'container';

    protected $container;

    public function __construct($options = null, $container = null)

        $this->container = $container;

    public function init() 
        $options = $this->getBootstrap()->getOptions();
        $db = $options['db'];

        $this->container['entityManager'] = $this->container->share(function ($c) use ($db) {
            $isDevMode = APPLICATION_ENV == 'development';

            $config = Setup::createAnnotationMetadataConfiguration(array(APPLICATION_PATH . '/models'), $isDevMode);

            return EntityManager::create($db, $config);

        return $this->container;

Resource plugins can be added from the application configuration. However, it's important that it is instantiated outside of the configuration to allow injection of the Pimple container. This is an extremely important step for testing.

// public/index.php

// ...

$resource = new \Example\Application\Resource\Container(null, new Pimple);


Create the controller

Within the action, the container is retrieved from the bootstrap.

// application/controllers/IndexController.php
class IndexController extends Zend_Controller_Action
    public function indexAction()
        $bootstrap = $this->getInvokeArg('bootstrap');
        $container = $bootstrap->getResource('container');

        $em = $container['entityManager'];

        $this->view->items = $em->getRepository('Application_Model_Item')->findAll();

Add a test for the controller

I've used the PHPUnit mock library for the example. Mockery is better though. Didn't want to throw another library into the mix!

// tests/application/controllers/IndexController.php
class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
    protected $container;

    protected function setUp()
        $this->bootstrap = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
        $this->container = new Pimple;
        $resource = new Example\Application\Resource\Container(null, $this->container);

    public function testIndexAction()
        $items = array(
            $this->createItem('test1', 'test1value'),
            $this->createItem('test2', 'test2value'),

        // mock the entity repository
        $repo = $this->getMockBuilder('Doctrine\ORM\EntityRepository')


        // mock the entity manager
        $em = $this->getMockBuilder('Doctrine\ORM\EntityManager')


        // replace the entity manager closure in the container
        $this->container['entityManager'] = $em;


        $this->assertQueryContentContains("h1", "Items");
        $this->assertQueryContentContains('ul li', 'test1: test1value');
        $this->assertQueryContentContains('ul li', 'test2: test2value');

    protected function createItem($name, $value)
        $item = new Application_Model_Item;
        return $item;


  • Populate Pimple outside of the bootstrap resource plugin. This step allows you to have an empty container during testing (no forgetting to replace objects in the container).
  • Allow easier access to the container via an action helper or by extending Zend_Controller_Action.
Aug 15 2011

Implementing Twitter sign-in with Silex and PHP


  • Install pecl oauth
  • Grab the Silex .phar archive
  • Create a Twitter application

pecl oauth

Install the pecl oauth extension

For example:

$ pecl install oauth


For those not acquainted with Silex:

Silex is a PHP microframework for PHP 5.3

A microframework provides the guts for building simple single-file apps.

It's awesome.

All you need is the silex.phar file and you're away. Download it.

For the example, I've setup a virtual host of example.local on my development machine. The apache module mod_rewrite and a .htaccess file are used to rewrite requests to index.php.

# .htaccess
<IfModule mod_rewrite.c>
    Options -MultiViews

    RewriteEngine On
    #RewriteBase /path/to/app
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php [QSA,L]

Create a Twitter application

Create a Twitter app

Once you've created your application, you'll need your consumer key and consumer secret. These are used to sign every request made to the API.


A complete summary along with a pretty diagram of what we're trying to achieve can be found here.

Basic OAuth request cycle:

  • Retrieve a request token
  • Request authorization
  • Exchange the request token for an access token

More information -

Basic Silex application

// index.php
define('CONS_KEY', 'Application consumer key');
define('CONS_SECRET', 'Application consumer secret');

require_once __DIR__.'/silex.phar'; 

$app = new Silex\Application(); 

// register the session extension
$app->register(new Silex\Extension\SessionExtension());

$app->get('/', function() use($app) { 
    $username = $app['session']->get('username');

    if ($username == null) {
        return 'Welcome Guest. <a href="/login">Login</a>'; 
    } else {
        return 'Welcome ' . $app->escape($username);


Add the /login route

The first part of the process requires the retrieval of a request token. Authorization is requested by redirecting to

// index.php
$app->get('/login', function () use ($app) {
    // check if the user is already logged-in
    if (null !== ($username = $app['session']->get('username'))) {
        return $app->redirect('/');

    $request_token = $oauth->getRequestToken('');

    $app['session']->set('secret', $request_token['oauth_token_secret']);

    return $app->redirect('' . $request_token['oauth_token']);

Add the /auth route

In my example setup the URL would be http://example.local/auth. Set your Twitter application callback URL in the app settings to be the auth route.

Within this action, the request token is exchanged with the access token which allows usage of the Twitter API on behalf of the user.

// index.php
$app->get('/auth', function() use ($app) {
    // check if the user is already logged-in
    if (null !== ($username = $app['session']->get('username'))) {
        return $app->redirect('/');

    $oauth_token = $app['request']->get('oauth_token');

    if ($oauth_token == null) {
        $app->abort(400, 'Invalid token');

    $secret = $app['session']->get('secret');

    $oauth->setToken($oauth_token, $secret);

    try {
        $oauth_token_info = $oauth->getAccessToken('');
    } catch (OAuthException $e) {
        $app->abort(401, $e->getMessage());

    // retrieve Twitter user details
    $oauth->setToken($oauth_token_info['oauth_token'], $oauth_token_info['oauth_token_secret']);
    $json = json_decode($oauth->getLastResponse());

    $app['session']->set('username', $json->screen_name);

    return $app->redirect('/');


Apr 15 2011

DbUnit talk at PHPSW in Bristol

I had the pleasure of talking to the PHPSW group in Bristol on Wednesday (13/04/2011). Considering it was my first talk, I felt it went quite well. Had some good comments :) and only small amounts of heckling. Overall a really good experience and something I'd definitely like to do again.

The talk was about the PHPUnit database code testing extension, DbUnit. I'm really fond of this extension and it seems to have a lack of decent documentation on the 'net. Ever since Benjamin Eberlei penned a comprehensive tutorial on it, I've been hooked.

Talk slides


Code examples on github

PHPUnit Manual

Benjamin Eberlei's tutorial

Mike Lively's blog

Testing LAMP applications by Sebastian Bergmann

Testing PHP/MySQL Applications with PHPUnit/DbUnit by Sebastian Bergmann

Database Testing with PHPUnit and MySQL by Matthew Turland

Feb 17 2011

Logging queries in Doctrine 1.2

The developers of Doctrine have made the task of logging queries trivial, thanks to their event listener architecture.

One just needs to create a class which extends Doctrine_EventListener:

class QueryDebuggerListener extends Doctrine_EventListener
    protected $queries;

    public function preStmtExecute(Doctrine_Event $event)
        $query = $event->getQuery();
        $params = $event->getParams();

        //the below makes some naive assumptions about the queries being logged
        while (sizeof($params) > 0) {
            $param = array_shift($params); 

            if (!is_numeric($param)) {
                $param = sprintf("'%s'", $param);

            $query = substr_replace($query, $param, strpos($query, '?'), 1); 

        $this->queries[] = $query;

    public function getQueries()
        return $this->queries;

And add the event listener:

$c = Doctrine_Manager::connection($conn);
$queryDbg = new QueryDebuggerListener();

I like to use the above to get a feel for how many queries are being performed.

For example, I was using $foo->Bar['field'] to retrieve a field value from a relation at one point. The code can result in another query, which could be avoided by using a join on the original query for the record. See the Doctrine documentation for a clearer example.

Feb 05 2011

Redirecting from an old route in Zend Framework

Firstly ensure your old route has been created: = "new" = index = new = default = "" = \d+

routes.old.route = "old"
routes.old.defaults.controller = index
routes.old.defaults.action = old
routes.old.defaults.module = default = "" = \d+

In the controller:

class IndexController extends Zend_Controller_Action 

    public function oldAction()
        $redirector = $this->_helper->getHelper('Redirector');
        return $redirector->gotoRoute($this->_getAllParams(), 'new');

For reference, examples developed with Zend Framework 1.11.2


I'm Ade Slade, a PHP web developer.