I’m Sorry…

This post is over 2 years old and is probably out of date.

Some of you may have noticed that I was absent from several events over the last month, specifically, DrupalCon Dublin, PHPNW, and BulgariaPHP.

I had intended to fly from my home to Dublin, before hopping over to Manchester, and then finally on to Sofia before coming back home again.

I was stoked to attend my first ever DrupalCon, to be going back home for the excellent PHPNW, and ending my trip with my favorite conference of 2015, BgPHP. It was going to be amazing.

And I couldn’t do it.

I did a lot of travel last year, and it was amazing. And tiring. I decided this year to do less travel, and I think that objectively, I have. However, this year is the first time my son has also cried when I’ve left, and my travel has been bunched up such that I’ve been away on several long trips.

I had just completed an unexpected West-East-West-East-West (SEA (Home) -> BUF (CodeDaze) -> SEA (PNWPHP) -> JFK (Velocity) -> SEA (Home)) and it was exhausting.

So, as I got up, said goodbye to my family, and loaded my stuff in my cab to the airport, I was anxious about being away for yet another extended period of time.

We started our drive to the airport, and I used my time to share my feelings with some friends via Twitter… and it became clear to me that I was either experiencing, or close to burnout.

Despite my embarrassment, I had my driver turn around and take me home. I cancelled my flights, my hotels, and told my boss. I contacted DrupalCon and went to bed. After I got up again, I contacted PNWPHP, and yet… I still hoped to make BgPHP. I thought maybe I could get my shit together in 5 days or so and still make the event I’d been looking forward to all year. But no… I couldn’t. And so, a few days later I told them too.

For those wondering, my emails were something like this:

Hi Ramelina (and the rest of the BgPHP crew),

As you know BgPHP is my absolute favorite conference in the entire world… however, I won’t be able to make it this year :(

After scaling back my travel due to mental health reasons I’m no longer able to attend :(

I understand that this is less than ideal for you and the wonderful attendees, and I’d like to do anything possible to make it easier for you.

Please let me know if I can be of any help, and if there any costs (such as hotel) that I need to cover.

I’m really sorry :(

And you know what? Everyone was fantastic. Nobody got mad, nobody was upset, they all just wished me well, and I’m sure scrambled to fix the mess I had made. And I am eternally grateful.

And dreadfully sorry.

I am sorry to the organizers, of course, but also to the attendees and wider community. As a Developer Advocate, I would like to be relied on by conference organizers and the community, as a known entity of stability. This is why, for example, I always let organizers know I have other talks I can give if someone else can’t speak for any reason. This is why I try to always get in early, and I work so hard on my slides.

I’m currently writing this from Berlin, and in truth, there was still a bit of anxiety leaving for this trip (with Akamai Edge in San Francisco first) — but, I’m glad I did it, if only to prove to myself that I still can.

Thank you, to every one who reached out to me when they heard I wasn’t going to make it, and in person this week, it meant a lot to me.

I will try to do better.

Update: 28 Oct, 2016

The Lead DrupalCon Coordinator (Amanda Gonser sent me this (published with permission):

Hey Davey,

Just saw your blog and wanted to say that I am happy you took care of yourself. I am glad to hear you’re doing better but still getting out there! We look forward to having you at another DrupalCon in the future if you’re up for it.


Amanda Gonser

Thank you so much Amanda, I still hope to attend my first DrupalCon soon!

Photo by GPS, used under a CC-BY-SA 2.0 License.

Exploring HTTP/2

This post is over 2 years old and is probably out of date.

I have been speaking about HTTP/2 for almost a year now, and throughout that time I have stated over and over again:

As a community, we are still trying to figure out best practices. The examples I’m showing here, are ideas. Nobody has figured this out yet. We [application developers], web server vendors, and browser vendors, all have a role to play in exploring HTTP/2 and informing each other about what we find.

I want to make clear that while this post talks about PHP specifically, the issues are present in most server-side languages that use FastCGI or similar models.

When I first started to explore HTTP/2 Server Push, my first thought was that PHP would not be able to do server push. PHP has a single output buffer, and its interface (the Server API, or SAPI) with the web server is built around that — whatever is output to the buffer, is then served to the end-user.

Exploring further, it became clear that those discussing and trying to figure out how to deploy the HTTP/2 spec have solved this issue by using Link headers.

This would then inform the web server and it would then be responsible for making sub-requests and pushing the results out to the user. By doing this, we avoid the issue of PHP having a single output buffer, by treating each push as if it were a unique incoming request. PHP is none-the-wiser.

Why We Need a New SAPI

Most of the existing exploration with HTTP/2 is focusing on websites (or web applications), rather than APIs. These two applications can vary a lot in their performance needs.

With a webpage, it’s typically a bundle of independent resources that are either data to display (HTML, images, fonts), meta-data to describe how to display it (CSS), or application code to make it dynamic (Javascript).

An API, however, is typically comprised on discreet resources with references to one or more other discreet resources.

While they may seem similar on the surface, the difference is that an API is surfacing a data-structure, while a webpage is a single flat document.

The APIs data-structure is often based on a datastore that supports efficient fetching of related resources.

Take the example I use in my talk, a blog API. A blog post might be comprised of:

  • The blog post itself
  • The author information
  • Related comments
  • The comments author information

We can imagine a couple of SQL queries like this:

Which, in a perfect RESTful world, would result in a number of seperate resources, each with their own URL (and therefore, separate request):

── post resource
    ├── author resource
    │   └── author avatar image resource
    └── comments collection
        └── comment resource (per comment)
            └── author resource
                └── author avatar image resource

Due to the current world of HTTP/1.1, we likely would at best split this into two resources (which happen to match up with our SQL queries up there) with each of the sub-resources embedded like so:

── post resource with author resource
    └── comments collection with each comment and author resource embedded

More often than not, we’ll just flatten the entire structure to a single post resource.

This is a trade-off we have to make in the name of performance.

If we wanted to move towards the first model, we would end up having to do many small queries at each layer of the structure, which could be very inefficient, or duplicate effort — especially if we need some of the sub-resource data to generate the resource URLs (think: pretty URLs using the authors name for author resources).

So, what do we do? We can cache the intermediate information for later retrieval by the web server sub-request, or we can write a SAPI that supports responding with the request resource, and subsequent pushes.

This however needs web server support.

Currently all SAPIs are based on the original CGI single request/response model. We need to move beyond this.

We need a new web server interface that supports multiplexing from the application layer, and we need PHP to be able to multiplex it’s output.

Additionally, we are going to want to control other features available in HTTP/2 dynamically for those multiplexed streams, such as stream weights and dependencies.

That Sounds Hard!

To do this would require a large effort on the part of many projects — on the scale of creating the original CGI spec, bringing to together web server vendors and language authors to decide upon a standard way to handle multiplexed communication.

We also don’t know how effective having these abilities would be.

Browser vendors are still figuring out the best practices for handling what is now a much more complicated priority tree, and re-building rendering around it.

Because it’s difficult to do so, there’s few sites taking advantage of these features yet for them to make anything more than an educated guess how to do this.

New Application Architectures

Additionally, we’re going to have to explore new application architectures, that feature asynchronous and parallel processing to create and output these multiplexed streams.

Introducing The HyPHPer Project

For the last few months I’ve been looking at the Python Hyper project, a series of libraries for handling HTTP/2. These libraries are for building concrete HTTP/2 clients and servers upon, and do not have any I/O — making them framework independent.

I have decided to try and port Hyper to PHP, as HyPHPer.

The goal is to provide a base for writing both servers and clients to explore both writing applications that can handle multiplexed responses, and documenting current browser behavior and performance implications of different response profiles.

We can then attempt to determine current best practices for performant web applications.

Current Status

During the PyCon AU sprint days I managed to port the Hyper HTTP/2 frame implementation (hyperframe) entirely to PHP — including tests.

This package is now available on Github and Packagist.

Still to be completed are:

  • Priority
  • H2 Full Protocol Stack

If you’re interested in helping migrate these packages to PHP so that we can explore what HTTP/2 means for the future of PHP, let me know!

The Syntax of Tech Communities

This post is over 3 years old and is probably out of date.

Just like the programming languages that are the centers of our communities, each community has its own set of rules and idioms — they have a real life syntax.

In my (almost) three years of being in a developer relations type role I have attended events in several communities and have observed how they differ from my primary community (PHP). As I’ve tried to understand those differences and the reasons behind them, I have had many discussions with members of many more communities also.

After attending my first PyCon (US) I was struck by just how welcoming and diverse the community is and had many conversations trying to understand why this is. This is not what this post is about. This post is about conferences specifically, and how communities place different priorities on different things when it comes to how they run, organize, speak at, and attend events.


The first thing I found that was unique about the PHP community is that every event which has an open CFP (e.g. not a local community day, hackathon, etc.) will reimburse at least some travel and lodging costs.

Larger community and for profit events will typically cover all flight costs and at least (number of talks)+1 nights hotel. Some will limit the number of international speakers to keep costs manageable, while others will have a fixed amount of costs they can cover, and the rest is up to the speaker.

In fact, the reason I started speaking at conferences was because of this, I would never have been able to afford to attend otherwise.

These may be paid up front with the conference booking the flights on your behalf, or they may be a refund after the fact.

In the last few years the smaller community events have (probably because it’s a default in OpenCFP) added checkboxes to their CFP which allow you request help for travel and/or accommodation. I think this change has come about as the number of speakers whose jobs are willing to pay their way has increased.

Additionally, you would get a full ticket to the event. Speakers do not get paid anything additional such as an honorarium.

Due to these costs incurred by events, ticket prices are usually somewhere from $150-350 with tutorial days at additional cost. A few events are much more expensive (~$1000+), but are typically not aimed at the community crowd.

Another thing I’ve noted is that it’s common for speakers to submit multiple talks to conferences and this is highly encouraged to people who wish to get a talk accepted: never submit just one!

As for the talks themselves, they are usually minimum 40 minutes (which is rare) and maximum 60 minutes. 50 minutes is the most common format.


The community which I spend the most time comparing (mostly with PJ) is Ruby. The first major difference I noticed was that there were no speaker packages. I was outraged by this, it felt like the equivalent of “it’ll be good for your portfolio”.

Then I found out why this was: the ruby community values accessible ticket prices, and wants to have a low price point to make the event feasible for as many people as possible, including students, single parents, etc.

This would be impossible if speakers travel/hotel were paid for by the event.

Speakers are given a ticket to the event, and I’m sure for some its reason enough to speak, while others do it for the exposure and networking opportunities. But additionally they seem to do it to contribute back to the community as well.

Also, when it comes to CFPs, numerous people I spoke to early on were aghast to learn that in the PHP community we submit multiple talks. However it seems that this is changing, and it is becoming more common to do so.

Talks are usually 25 minutes, with the max being 35 minutes. Some are as little as 20 minutes.


The Python community seems to be somewhere in the middle. While Python events do not cover a speakers flight and hotel, the PSF has a formal grant program which allows for those unable to afford to attend to request financial support to do so.

And while ticket prices are not as cheap as ruby events, they do have multiple levels of ticket prices, for example students, regular, and business tickets. For PyCon US, those were $125, $300, and $600 respectively. And everyone buys a ticket, including the event chairs, volunteers, and speakers. Again the PSF grant program can help here.

Submitting multiple talks seems to be the norm. And talks are 35-40 minutes long.


I have only recently started discussing this topic with members of the Perl community, but they seem to also value low cost tickets, speaker costs not covered, and 35-40 minute talk slots. I may be wrong on this but that’s what I understand to be the case. I am unsure if tickets to the event are given to speakers, or how CFPs are typically done.

There’s No Right Answer

It is obvious to me that community is hugely important to everyone I’ve spoken to about this, and I find it interesting how different communities have different priorities resulting in different conference experiences.

I will say that the Python way seems like a much more democratic and inclusive way to handle things, but that it depends on the PSF which is a core part of its community and requires monumental effort, oversight, and tons of volunteers. As an aside, the PSF also seems instrumental in the inclusiveness and diversity exhibited by the Python community.

At the end of the day, I think we all have valid motivations. The PHP way ensures that regardless of your financial situation, if you have something valuable to share then you can do so, while the Ruby way ensures that the most possible people can attend to hear what is being shared, and the Python way tries to strike a middle ground.

I do find it interesting how consistent things seem to be within communities, perhaps simply through early leaders setting the expectations, but it does show some of the differences of opinion on how to build a thriving community — and yet even with these differences, they are all large, thriving communities.

Image courtesy of Benjamin Horn, used under a CC-BY 2.0 License.

Thanks to PJ and Rae for reviewing this post.

The Visibility Debate

This post is over 3 years old and is probably out of date.

A lot has been said about when to use public/private/protected. Some say that you should never use private, while others say you should never use protected.

About the only thing that people can seem to agree on is that public should be used with caution. That your versioning should be based around your public API, and you have a responsibility to maintain that API.

The issue is mainly around the maintenance responsibility of protected vs private. Given that other developers can depend upon protected, it can effectively be considered to have the same overhead as your public API.

I personally very rarely use private properties, and I default to protected.

My thinking is thus:

  1. The public API is sacrosanct, following SemVer, breaking the public API shall bring a new major version. I will do my best to support an existing public API for as long as possible and only break backwards compatibility as a last resort.

  2. The protected API is important. It does not impact SemVer, though often accompanies changes at the X.Y level. However I pledge to document any changes in release notes and otherwise, to ensure that if you pay attention you will be able to track changes and avoid issues. I will make changes as necessary to the protected API. (n.b. as I write this, I’m considering making it a rule that X.Y should be incremented for protected changes, always)

  3. The private API is the wild west, and you’re on your own.

I think this is a pretty pragmatic approach, it preaches caution and engagement when extending third party libraries, yet does not needlessly prohibit the ability to extend entirely.

Speaking Out on the PHP Code of Conduct

This post is over 3 years old and is probably out of date.

Please see the updates below

This was going to just be a tweet, but I felt it needed more than 140 characters.

If you know me in person, you’ve probably met me at a conference or user group. It should be immediately apparent that I am a confident, outspoken person (at least publicly).

I’m a former PHPWomen US Lead, as well as co-organizer for Prompt, raising awareness about mental health in technology, I’m no stranger to speaking out on tough subjects.

Furthermore, I’ve been a contributor to the PHP community for 15 years, and an internals contributor for half of that (since PHP 5.3.0).

The fact that I — as that person, and as a member of the majority makeup of the PHP community — don’t feel safe contributing back to the Code of Conduct discussion in favor of it — should tell you everything you need to know about why we need one. This is due in part to the hostility from some people involved, and to possible backlash from the wider community.

So let me state here, for the record, in unequivocal terms:

I fully support a Code of Conduct, and a reporting infrastructure in which we can act to remove those who are unable to abide by the Code of Conduct from our community.

This should be applied to all mailing lists, all websites (e.g. comments in the manual, news items, etc.), and all social media put out by the PHP project itself.

It should also apply anywhere a contributor is using their @php.net email address — whether thats a private email conversation, or at a conference/user group where you put it on your contact slide. Obviously while the person could not be removed from the event, they can be restricted from contributing based on their behavior.

Also: thank you Anthony for bringing this RFC to the table.


This has gotten quite a bit of support and a couple of questions, so I wanted to add one specific thing:

To clarify, I don’t support the Contributor Covenant as it stands as the CoC for PHP; I think it is a good starting point, but it is just that, a starting point. Additionally, regardless of the content of the CoC, what matters more is documented procedures for handling reported violations.

2015: The Year of Awe

This post is over 3 years old and is probably out of date.

As 2015 comes to a close, I thought that I would jot down some words to reflect up what can only be called an incredible year.

In April I will celebrate the end of my third year as a Community Engineer Developer Evangelist, and it has been filled with more firsts that I ever thought I would experience.

January 🇺🇸✈️🇧🇪🚆🇩🇪

The year started out pretty standard with PHPBenelux (not that one could ever even suggest that PHPBenelux is anything but an extraordinary event!), but was then followed by the first of three WurstCons, which was actually a mini-tour of Germany.

Yitzchok Willroth (the [in]famous @coderabbi), Beth Tucker Long, and of course, the esteemed Jeremy Mikola and Daniel Cousineau, our organizing team, myself, as well as a host of other folks joined together for the saga that was: WurstCon EU.

ICE Train

We took the train from Brussels to Köln, where we spent two nights and visited a local Biergärten, an experience in and of itself. Here, I tried blood sausage for the first time (which some might find strange, as I am British), as well as pork knuckle.

WurstCon EU

Cologne Cathedral

From Köln, Yitz, Beth, and myself took another train to Frankfurt, while Jeremy flew to Berlin. We spent one night in Frankfurt, before Beth went off, leaving Yitz and I to carry on and meet Jeremy in Berlin.


Frankfurt Love Locks

February 🇩🇪🚆🇧🇪✈️🇺🇸✈️🇨🇦✈️🇬🇧✈️🇺🇸

After 3 days in Berlin, and 6 days total in Germany, I took the train back to Brussels for FOSDEM.

Belgian Waffle


After FOSDEM, where I got to hang out with the irrepressible PJ Hagerty and a surprise visit from Eamon Leonard, I flew back home to sunny Florida where I was greeted by the newly printed Zend PHP 5 Certification Study Guide, 3rd Edition.

Next up, was ConFoo, where I unfortunately had to rush through (one talk before lunch, one talk after, and then a flight 2 hours later…) on my way to PHPUK where I was giving my first keynote.

I cannot thank the PHPUK folks enough for allowing me to have such an amazing experience. This was a professional goal of mine for many years, and I finally realized it on a stage that, being in my home country, made it all the more special. Plus, my mum got to come!

March 🇺🇸✈️🇦🇺✈️🇺🇸

March started with me knocking another two items off my bucket-list: I made it to the Southern Hemisphere, and specifically, to Australia, for PHPAustralia. In Sydney, I got to put my feet in the other side of the Pacific Ocean for the first time, as well as see Koalas, Tasmanian Devils, Wallabies, and even take a Quokka selfie with Jordi Boggiano at Taronga Zoo.

Koala at Taronga Zoo

I saw the Sydney Opera House and the Sydney Harbor Bridge, another bucket list item (the Opera House is much smaller than I thought!), and the Three Sisters.


I even ate Kangaroo (both in Kebab, and steak form, very yummy!), as well as Crocodile (tasted like salt water…).

Kangaroo Two Ways

Most importantly, I met some amazing new people, like Jack Skinner, and my long-ago co-author, Ben Dechrai. These folks in particular are doing amazing things for the tech communities in Sydney and Melbourne (respectively). I also met the fantastic Katie McLaughlin who taught me that we all need a place to hang our hats.

April 🇺🇸✈️🇺🇸✈️🇺🇸

Following on from my longest trip to date, I then took one of the shortest, in what was my least busy month of the year, to one of my favorite conferences, Lone Star PHP. Once again, Lone Star delivered, and I have the nice comfy t-shirt to prove it. I also experienced my first Tornado Siren. That was not on my bucket list.

We also enjoyed one of the best outings for PHP Karaoke for the year. I think this picture from Ben Ramsey captures it pretty well:

I also saw this great talk by Heather White on Teaching, which changed the way I do my slides and I’ve been getting compliments ever since: Thanks Heather!

On the way home from Lone Star, I actually ditched my checked luggage in Atlanta and went to hang out at my first RailsConf, and in fact, my first Ruby-related conference. I had a great time, met some great people, and got to hang out with PJ again. Oh yeah, and Phil Sturgeon turned up too. More karaoke happened.

RailsConf Badge

May 🇺🇸✈️🇮🇹🚆🇮🇹🚆🇮🇹✈️🇺🇸✈️🇺🇸

May was another month for knocking out bucket-list items, I took my wife along to Rome, Italy where we got to see the Vatican City and watch the Pope speak (neither on my bucket list, but highly recommended), I also got to see The Colosseum (the oldest item on my bucket list, I actually cried), Palatine Hill, Trevi Fountain, and much more. From here, we took a train to Venice, another bucket list item, and got to see the islands of Murano (famous for its glassware) & Burano (famous for its brightly colored painted buildings), as well as Piaza San Marco, and some beautiful sunsets and canals views.

The Food of Italy

Our final stop in Italy, was of course Verona, for phpDay, a great little conference, in a lovely town with it’s own historic arena (which is apparently older than The Colosseum), as well as Juliets House, and I got to see the old city for the first time at the speaker dinner.


From there, I headed on to Chicago, for php[tek], always a good time, and in fact, the last time it will be held in Chicago. I am excited to see what St. Louis brings to the table, and how we will ever replace Shoeless Joe’s. I think I will always remember watching The EuroVision Song Contest with a small group of people on my phone in the Club Lounge after the conference ended…

June 🇺🇸✈️🇺🇸✈️🇲🇽✈️🇺🇸✈️🇳🇱✈️🇺🇸

After a quick trip to Boston, MA, I headed down to Mexico for MagmaConf, an amazing polyglot conference that is only eclipsed by it’s location. If you ever get the chance to go, take it. I had an amazing time for my first time in Mexico (other than the port of Cozumel on a cruise, which I’m not counting) — I flew into Colima, and then, after giving a workshop, took a bus through the hills to Manzanillo on the Pacific coast. MagmaConf happens at Magma Village, a coastal resort where you share a villa with a number of other [random] folks attending the conference. I swam in 7 different pools over the 2 days of the conference, hanging out and meeting new people.

I then ended the month at the DutchPHP Conference, this was my second time there, and it turned out to be my last talk for Engine Yard. This was actually quite an emotional thing for me — after almost 4 years, I was no longer a Yardee.

My Last Audience as a Yardee

July 🇺🇸✈️🇹🇷✈️🇺🇸

But, thanks to that quick trip to Boston back in May (Cambridge, actually), I was moving on to a new gig at Akamai Technologies. I then experienced yet another first, this time, Istanbul, Turkey. This was my first experience of a country that didn’t use the Latin alphabet (except Egypt, before I could read 😋), which was quite an interesting experience, and it would not be my last time this year.

Food of Istanbul, Turkey

Istanbul was another amazing city, with so much history and culture. I got to see the underground Basilica Cistern, and sunset from Galata Tower, among other great sights, and attended another great conference, PHPKonf. This was also the first time speaking where I was translated in real time, which was fascinating.

Istanbul, Turkey

August 🇺🇸✈️🇳🇿

August was the start of my longest travel period ever. Starting with a family vacation on the 24th, I was on the road non-stop till October 9th.

Considering I started the year never having been to the Southern Hemisphere, I — much to my amazement – got to go a second time. This time, I headed to beautiful New Zealand, and while I didn’t get to see Hobbits, I did get to enjoy a lovely drive along the coast, and had a fantastic time catching up with friends new and old at the New Zealand PHP Conference.

New Zealand

September 🇳🇿✈️🇦🇺✈️🇺🇸✈️🇧🇬✈️🇿🇦

While in New Zealand, I submitted my first patch for PHP 7.0, adding a few constants to ext/curl for HTTP/2 multiplexing.

Contrary to popular belief, I did not write the patch for T_SPACESHIP in 7.0. I wrote and proposed the T_SPACESHIP against 5.6, and it was re-written independently by Andrea Faulds. She later took on the T_SPACESHIP name after finding my original patch.

P.s. it’s one of these, not a Tie-Fighter or anything else!)

From New Zealand, I headed back to Sydney for a few days, where I got to speak at the SydPHP User Group, and gave my first talk on HTTP/2, a topic that would become a major focus for me for the rest of the year (and hopefully, beyond!). Next, I headed back to the US, to Seattle for the first time, and to meet up with my wife and son, for the inaugural Pacific North West PHP, where I was once again fortunate to keynote.

Beautiful Washington State

Following the event was my second WurstCon of the year, WurstCon NW, at Pike’s Place Market, where we shut down the restaurant for our impromptu private party (thanks to the gracious staff for that!)

WurstCon NW

I enjoyed this conference a lot, and apparently enjoyed Seattle so much (especially the drive through Mt. Rainier National Park) I’m planning to move there this upcoming February where I’ll get to hang out with awesome folks like Margaret Staples and Tessa Mero.

I then flew back to Europe, to Sofia, Bulgaria, my second non-Latin language country of the year. Now, let me stop for a moment and give a special shout out to this conference, easily in my top 3 for the year. The organizers of this conference were so amazing at making the speakers feel welcome, and safe in a country where all but two of us couldn’t even read the alphabet, and the event itself was just top-notch. I absolutely have this one my must-do list next year. Also, I climbed a fricken mountain. And the group hug at the end was epic. Oh, and let’s not forget, so much food meat, including my first time eating Horse thanks to the nicest guy I know, Damiano Venturing.

Thank you to the entire crew at Site Ground, but especially Dima Peteva for being my handler, and for even translating some Cyrillic receipts via IM for expenses after I got home!

From Europe, I took my third and final trip to the Southern Hemisphere for the year for PHP South Africa.

October 🇿🇦✈️🇺🇸

PHP South Africa actually comprised of two events, the first in Johannesburg, and the second in Cape Town. Johannesburg while fantastic, couldn’t have prepared me for our 2-day stop before heading on to Cape Town: Pilanesburg.

Here I got to take another item off my bucket list: we took not one, but two safaris. Despite the bug in my room larger than my head (my wife who was on FaceTime with me at the time I discovered it — and deafened by my high pitched scream — says I’m exaggerating), and losing one of my lenses, this was one of the most amazing experiences I’ve ever had. Seeing Elephants, Rhinos, Lions, Leopards, Hippos, Antelope, Zebras, and more in the wild, was beyond words. No photo, zoo, or wildlife park can do them justice.

Pilanesburg Safari

And yet… even that didn’t compare to the majesty of seeing, and ascending Table Mountain in Cape Town. Although Jordi and Derick actually climbed the mountain, myself, Raphael Dohms and his wife Tiscilla took the cable car to the top, where we were treated to amazing views of the end of the world, and after being joined by the hikers, we enjoyed watching the sun set over the water1.

November 🇺🇸✈️🇨🇦

My final event took me back to the frozen slightly cool North, this time to Toronto for TrueNorth PHP and the final — arguably the best — WurstCon of the year, at Wvrst in downtown Toronto, where I got to split a multi-sausage meal with Margaret and Mr. WurstCon himself, Jeremy Mikola (and we were joined by a bunch of other great folks).

We started with duck, pheasant, venison, bison, and guinea fowl:

Followed by kangaroo, lamb, rabbit, wild boar, and elk :

And finally, ending with Oktoberfest (with beer), Kaas (with cheese!), and then the more traditional Bratwurst, Berkshire, and Tamworth varieties:

And of course, I participated in this work of art:

The Last Sausage

Unfortunately, I was supposed to also speak at RailsIsrael (how this event isn’t called Israils, I have no idea!) but had to cancel due to safety concerns — this also means I didn’t manage to achieve my goal of hitting every continent2.

I also started my first real RFC for PHP 7.1, adding — you guessed it — yet more HTTP/2 feature support to ext/curl, this time in the form of HTTP/2 Server Push support.

December 🇺🇸✈️🇬🇧

December is the first month this year without any travel for work, and I’m looking forward to a full month with my family, to enjoy Christmas, and reflect on the year passed.

Also: my RFC passed with flying colors!

2015 In Summary

This year, I visited 13 countries, covering 162,862 miles (262,101km) on 79 flights via 28 airports. I spent 15.5 days in the air. That’s equal to more than six and a half (6.54) times around the world, and over half way (68.2%) to the moon!

I also tried many new kinds of meat: Kangaroo, Crocodile, Horse, Kudu, Ostrich, Springbok, Guinea Fowl, Pheasant, Venison, Bison, Wild Boar, Elk, Rabbit, and Veal!


As we head into a new year, I’m looking forward to a continued focus on HTTP/2, as well as web performance at all levels of the stack. With that, I hope to attend many different events for 2016, hopefully a lot of polyglot events, but also general web development, frontend, JavaScript, Python, Ruby, and of course, PHP events.

I hope to see all of you again next year, somewhere, and I look forward to meeting new people, and learning even more than I did this year!

  1. You can see an even better time-lapse by Jordi, here 
  2. At least as far the UN 5 inhabited continents model goes! 

Catching Up With Myself

This post is over 3 years old and is probably out of date.

Prior to November 19th 2006 I was really into PHP. I tested every alpha, beta, and release candidate, I knew every new feature inside and out, and I had plans to contribute… something. I didn’t know what, but I was going to give back to the language I loved.

However, just a few weeks after the release of PHP 5.2, my first wife passed away and I pretty much dropped off the face of the Earth as far as being part of the PHP community is concerned (EartPHP?). I did my job, and very little else. I had pushed out PHAR the year before, and it went on to become part of PHP 5.3, earning me my name in the phpinfo() output — a long time goal of mine at the time — but I pretty much missed the 5.3 release. For all the drama around killing PHP 6, and the huge changes in 5.3, I just wasn’t paying much attention.

I’ve felt like I was playing catch-up to pre-November 2006 me ever since then.

Despite everything I’ve accomplished since then, I never felt like I had reached the same level I was at back then (see: Impostor Syndrome). Till now.

Last week I put my first real1 feature addition to PHP up for voting. This has been a personal triumph for me, finally getting to grips with C enough to contribute in a meaningful way.

This year I also started getting help for my depression, and a few months ago, I started on Wellbutrin. I am sure these two things are related.

Next up, I hope to continue on this trajectory by writing a brand new extension (probably around libcurl) from scratch.

For now, I just want to say:

Dear Past Me,

We did it, finally.

– Future Past Me.

Image Courtesy of Sanjib Mitra, used under a CC-BY-NC 2.0 license.

  1. By real, I mean beyond a simple bug fix, or a copy and paste + modify change. Or adding a simple operator

PHP 7 ext/mysql Shim

This post is over 3 years old and is probably out of date.

To help ease the transition from 5.6 to 7.0 I have created a simple package that acts as a shim between the newly removed ext/mysql and ext/mysqli.

I was a little hesistent to even publish this as I don’t want to encourage the continued use of potentially insecure code, however, I want people to upgrade to 7.0 and don’t want this to be the blocker.

It does require 5.6 (though it would be possible to lower that) — however I suspect that most people who are upgrading to 7.0 are either coming from 5.6 or have the native ext/mysql. The primary reason for support 5.6 is to be able to compare the test suite results against native ext/mysql.

It’s not yet production ready, but tests are coming along pretty well (PRs welcome!):

Build Status Scrutinizer Code Quality Code Coverage

Current known (and unlikely to be fixed) issues are:

  • You must prefix all calls to mysql_* with a \ (e.g. \mysql_connect()); Not sure why I thought this, but non-internal functions do fall back to the global namespace.
  • Calls to is_resource() and get_resource_type() on MySQL connections and results will fail as these are now their mysqli equivalents.
    -Some errors are now from ext/mysqli, and others are E_USER_WARNING instead of E_WARNING. Where possible, the original error messages are replicated.
  • Column lengths reported by mysql_field_len() assume latin1 charset, and will return incorrect lengths for other charsets.

You can check it out now on Github.

Image Courtesy of Egan Snow, used under a CC-BY-SA 2.0 license.

GuzzleHttp VCR

This post is over 3 years old and is probably out of date.

A few days ago I pushed out a very small library to help with testing APIs using Guzzle: dshafik/guzzlehttp-vcr.


This is a simple middleware that records a request’s response the first time it’s made in a test, and then replays it in response to requests in subsequent runs.

It does this by returning a Guzzle \GuzzleHttp\HandlerStack with either the \Dshafik\GuzzleHttp\VCRHandler middleware, or the GuzzleHttp\Handler\MockHandler added. The first will record the responses to JSON files, while the latter will be pre-loaded with those responses and will return them when requests are made.

It’s important to understand that the responses are returned in order regardless of whether it is the same request being made.

The purpose of this library is to just make it easier to create and update your tests for API clients.

Usage is simple, just call Dshafik\GuzzleHttp\VCRHandler::turnOn() passing in the storage location before running the test, and pass in the handler as a guzzle client option:

You can pass in the handler when instantiating the \GuzzleHttp\Client, or when making the individual requests — if you use the same instance for the individual requests it will re-use the same JSON file for storage, otherwise if you pass in unique instances (with unique storage files) it will create individual ones. I recommend passing in the handler to the constructor, but ensuring that you use a new instance (of the middleware, and the client) for each test.

Hopefully folks find this useful, do let me know if you do. If you have issues, please report them and pull requests are welcome!

I’ll be releasing a new Akamai library which uses dshafik/guzzlehttp-vcr next week (probably) so look out for that if you want to see it’s use in a real project.