Jeroen Moors


Written on 23 February 2014

I was in London the other day, at a conference, an interesting php conference. These are my notes. They’re notes I made, so they’re subject to my interpretation and personal interests.

PHP At The Firehose Scale

Stuart Herbert

  • PHP can be used to consume and process large amounts of data, however if you require insane performance C will server you better.
  • PHP application can be create quickly and allow rapid changes. If you need flexibility, PHP overpowers C.

Unbreakable Domain Models

Mathias Verraesslides

  • Domain driven development wants you to spit your application in classes serving one and only one purpose.
  • A customer class for instance should not be doing e-mail address validation. The e-mail address is managed via a separated e-mail class. I think this kind of classes are called value objects. Their constructor is used to pass in a value and validate this value if required. This technique moves the logic of each different domain into a separated block with a single purpose. Ensuring maintainability and consequent behavior throughout your application.

Caching Best Practices

Eli Whiteslides

  • Always try to cache the largest reusable piece of data in it’s most final form. For example you query data, do some transformations on it and return this data as json, cache the json object. If this data only is rarely returned as json and for instance also returned as html, cache the preprocessed data.
  • Cache everything forever and invalidate or even update the cache when things changes. Eli wasn’t that strict about the forever, I am :-)
  • Running multiple small queries that you can cache in APC or memcached, can be more efficient as  running a single query that can’t be cached.
  • In MySQL, each update of a table invalidates the cached results of all queries using that table. Don’t rely to much on the MySQL caching.
  • In APC you can store all kinds of PHP objects, that does include resources.

Profiling PHP Applications

Bastian Hofmannslides

  • You’ll have to measure the behavior of your full stack or you’ll end up in endless discussions and try to search for a needle in a gigantic haystack.
  • End-to-end measurements can be quite easy achieved today with the Navigation Timing API. They’re not supported by all browsers, but should be supported by enough of your users to provide useful data.
  • Let the Navigation Timing API record the data and have your page make an AJAX request when it’s loaded. Make use of query parameters (log.html?dns=200&total=820) to push the data back to a server. This can be a separated server only used for data collection. The page on the server doesn’t require any logic. Just make sure you’ll enable logging of the query sting in your webserver.
  • Parse the webserver logs of your data collection server with a logstash and feed them to graphite.
  • If you use a framework as ZF or Symphony, use their browser toolbars.
  • Check bonus slides!

Algorithm, Review, Sorting

Speaker: Rowan Merewoodslides

  • Rowan is a great speaker
  • Sorting algorithms are only understandable for above intelligent people. All other should just accept their existence and behavior.
  • PHP has build in support for sorting, use these functions, don’t try to write your own

I saw also two talks on security. No big surprises there, but check their slides: Facebook’s Approach to Common Web Vulnerabilities (Ben Mathews) and Web Security and You (Eli White).

Written on 14 October 2013

Recent I got a question how to connect my oAuth module to Tank Auth for user session management. While that might be possible, I think that would be overkill.

When I wrote the oAuth module, I also wrote a very simple module to handle the user session management. The module has only 3 methods:

Set the current user id

After your authentication process, being it oAuth or any thing else, use $this->current_user->setId(10, true); to set the current logged in user id to 10. The $rememberMe parameter defines if the user has to login or not the next time he or she visits the site.

For this functionality a cookie use used on the client side and a table named user_autologin on the server.

Get the current user id

Calling $userId = $this->current_user->getId(); will store the current logged in user in $userId or false if there is currently no active user session.

Log the current user off

To end a session use $this->current_user->logoff();.

For the Remember Me functionality to work you will need to create a table called user_autologin:

The code can be downloaded here. As always all feedback is welcome!

Written on 18 June 2013

If you’re working on Open Source, documentation is king! However the process of creating documentation for a PHP C or C++ extension itself is not very well documented.

You’ve got some official source like a howto, some specific info for pecl. The official docs are or outdated or pointing in different directions. A found a good blog post by Kristina Chodorow, but it’s a bit out dated and still leaves out some steps. So here it is, an (other) attempt to a step-by-step guide for documenting your PHP extension written in C or C++.

Create a working environment

Create a working directory and move in to it.

Checkout the existing php documentation and its tools.

Install required software

Mare sure you’ve installed the sqlite3 extension, required for PhD to work. On Debian or Ubuntu, use:

Install PhD, the PHP Document generator:

Generate a docbook skeleton

Make sure your PHP extension is loaded. If it’s loaded the provided docgen.php script will use reflection to create a basic docbook files.

Replace my_extension with your extension name.

Update the main index

Add your extension to the master docbook file used to identify all available chapters.

Edit ~/phpdoc/phpdoc/doc-base/manual.xml.

Search for a section that matches the type of your extension. For example if it’s a database extension, move below the following tag:

Add a line in this section:

Prepare the docbook files

Prepare the xml files you’ve generated and modified in the previous steps.

If configure.php generates any errors, fix them. It could be as easy as commenting out some lines with references to non-existing files.

Generate HTML

Generate an HTML file from the XML-files.

Pimping your HTML

By default no CSS is used in the html-output. You can easily create a look and feel by downloading a style sheet from the site and include it in your html file.

Written on 15 June 2013

A classical multi web server setup

A classical high available setup exists most often out of multiple web servers, database servers and maybe a redundant load balancer.

The user generated content (UGS) like images, video, … can be uploaded on any web server and must be available on all web servers. The easiest way to achieve this is to add a NAS to the setup and store all UGC on the NAS.

While all big vendors will tell you their NAS solutions are fully redundant, your NAS will go down at some point in time. For sure. One day a power supply needs to be replaced. Off course you’ve got a support contract covering this kind of interventions. An engineer will come onsite, unplugs one of your five power supplies. Takes one out, and puts the new one in. Unfortunately he succeeds to create a shortcut while bringing the replacement in place. Bang! Game over!

The previous story might sound a bid odd, nevertheless it’s a true story. I’ve got plenty of these stories…

Storing your data in a cluster

Instead of storing your precious data on a single device, store it in a cluster. While this might sound more expensive than a NAS, it might be even cheaper if you’ve got a solution that uses commodity hardware.

Ceph’s object store

Ceph is a free software unified storage platform. It provides multiple interfaces, one of them is an object store called RADOS (Reliable Autonomic Distributed Object Store).

Thinking of the files on your NAS as objects might be a switch in mindset, nevertheless it’s an easy one to make.

Building a first cluster

Any RADOS cluster is build with two types of building blocks: storage daemons and monitoring daemons. Their service in the cluster is indeed what you would expect by their names.

In case of a test cluster, you need at least two storage daemons and one monitor daemon. For testing purpose all components can run on a single machine. Use the 5-minute quick start guide to get a cluster up and running in, yes, 5 minutes.

For a production server you will of course use multiple servers, spreading the different components on different servers. As the monitoring daemon provides a critical function the cluster you would like to get more then one. As a majority voting system is used, you always need an odd number to avoid issues. Three monitors is a reasonable number for most production clusters.

Interfacing with a cluster

If you’re used to use Amazon S3 to store your data, you could use RADOSGW. It will provide a compatible Rest API to your cluster.

It’s also possible to connect directly from PHP to your cluster using phprados.

Make PHP and RADOS chat

The current master branch of phprados was created by Wido Den Hollander and provides an almost one-on-one mapping to librados, the C interface to RADOS.

Since a few months I’ve been adding an object oriented interface providing a very easy to use API. It’s currently not yet moved into the master branch, but can already be found at Instruction on how to build the module are available in the INSTALL file.

PHP Examples

Read data from a local jpeg file and store it in the cluster.

Retrieve the image stored in the cluster and return it to the client.

Written on 4 April 2013

Today I received an e-mail with a question, that I think, is a common issue with PHPWord: Adding line breaks in a text block.

Let’s assume you’ve got this text*:

Autumn end November: The night has fallen
The bare branches can be seen
Even more lonely

If you use a n (carriage return) or even a rn (line-feed and carriage return), your text will be shown in one single line. Don’t get misled by using LibreOffice to test your documents as it will interpret the new lines, while MS Word won’t!

A quick and easy fix to this is to replace the n by the OpenDocument tag <w:br/>:

*Credits for the haiku: Herman Van Rompuy, also known for being the President of the European Council.

Written on 14 March 2013

Na de eerste jQuery conferentie in Europa vorig jaar, belooft de line-up van de 2e editie opnieuw een boeiende conferentie.

Absolute head-liner dit jaar is Brendan Eich, Mister Javascript himself.

Vorig jaar maakte ik een shopping list om ter plaatsen te geraken en terug. Ik heb het lijstje even geüpdatet:

Shopping list:

  • Eurostar van Brussel – London (en terug) – 88 euro
    Je moet dan wel nog transport naar Brussel scoren. Het milieu geeft de voorkeur aan de trein, maar er is ook een betalende parking onder het station Brussel Zuid.

  • Metro van St Pancras (King’s Cross) naar Victoria (en terug) – 8 pound of 9 euro

  • Bus van Victoria naar Oxford (en terug) – 20 pound of 23 euro
    De bus is voorzien van gratis wifi! (Juuuij, internet! gratis!)

  • jQuery UK Conference238,80 pound of 275 euro

  • Hotel Becket Guest House - 311.18 euro (voor 2 personen)
    Dit hotel is op enkele minuten wandelen van de conference, inchecken op donderdag, uitchecken op zondag.

Totaal 550,59 euro indien je de kamer kan delen met iemand anders. Ik zoek trouwens nog een roommate!

Zin om samen met mij te gaan? Geef me een seintje via mail, telefoon of twitter!

Written on 13 March 2013

PHPWord is a great library if you want to manipulate Word documents from PHP.

One of the easiest ways to create a document is to use a existing document as a template and the setValue() function to replace tags inside this document.

Unfortunately currently one very useful thing is missing: dynamically adding rows to a table. I’m not a rock-star programmer, I know some of them in person, but I’m not. Still I wrote a quick hack to overcome this issue.

This is how it works:

  1. Create a template Word document, containing the tables you would like to use.
    For each table, add one row to use as a template with the tags you would like to replace. Your template would be something like this: 

    First name Last name
    ${first_name} ${last_name}
  2. Call the cloneRow($tag, $numberOfRows) function before setValue() to duplicate your template row. Provide any tag on that row as $tag and the required number of rows as $number.
    Calling cloneRow('first_name', 3) would transform the working copy of your template into something like this: 

    First name Last name
    ${first_name#1} ${last_name#1}
    ${first_name#2} ${last_name#2}
    ${first_name#3} ${last_name#3}
  3. Now call setValue($tag, $value) adding #rowNumber to the original tags.
    To finish the example: 

    Would result in:

    First name Last name
    Jeroen Moors
    John Doe
    Jane Roe

To get this thing working you’ll have to replace the Template.php file found in side the PHPWord directory by this one Template.php.
Warning: don’t copy-paste it from the block below, as this might result in syntax errors.

12.09.2013 – Thanks to Robert Pecha a bug has been fixed, please download the latest version of Template.php

Any feedback is welcome!

Written on 21 December 2012

Sinds enkele dagen loop ik met “een ideetje”.

Omdat uit te kunnen voeren heb ik input nodig van jullie: de web creatives, de internet wizards, de geeks, de online marketeers, de UX specialisten, de socialmedia guys, de grote denkers.

Ik zou graag weten wat jullie denken dat belangrijk zal worden in 2013. Wat gaan de nieuwe buzz-words zijn? Maar ook, met welke vragen zit je over het internet in 2013?

Geef je input via onderstaande formulier. Maak je geen zorgen, ik zal je input niet verkopen aan de hoogste bieder – uitgezonderd als die echt heel veel zou bieden.

[gravityform id="1" name="Wat brengt 2013?" ajax="true"]

Written on 22 May 2012

While hunting for performance issues, a view on all queries executed by mysql can be very useful.

If you’re on a production system, you probably don’t want to touch the mysqld configuration.

Therefor this little sniplet can be used to sniff the mysql traffic and filter out the useful query stuff.

If your mysql-connections are not arriving at eth0, you’ll have to change it on the first line near -i eth0 to the right interface.

Written on 21 April 2012

Surprisingly enough there where quite some download of this library. On top of that @thambach asked for a GitHub fork.

So I decided to do the right thing: Update things a bit and put it all on GitHub.

The major new thing in this version is a helper library that can be used to load the real library with all its settings. This allows you to only configure all OAuth settings in one place.

Full – updated – details on the library can be found here.