Matthew Weier O'PhinneyPSR-7 By Example (28.1.2015, 21:40 UTC)

PSR-7 is shaping up nicely. I pushed some updates earlier this week, and we tagged 0.6.0 of the http-message package last week for implementors and potential users to start coding against.

I'm still hearing some grumbles both of "simplify!" and "not far enough!" so I'm writing this posts to demonstrate usage of the currently published interfaces, and to illustrate both the ease of use and the completeness and robustness they offer.

First, though I want to clarify what PSR-7 is attempting.

HTTP Messages

HTTP messages are relatively simple, which is why the protocol has succeeded over the years. All messages have the following structure:

<message line>
Header: value
Another-Header: value

Message body

Headers are key/value pairs. The keys are case insensitive. Values are strings. The same header type may be emitted multiple times, in which case (typically) the values are considered as a list; in most cases, these can also be expressed by concatenating the values with comma delimiters.

The message body is a string, but typically handled by servers and clients as a stream in order to conserve memory and processing overhead. This is incredibly important when you transmit large data sets, and particularly when transmitting files. As an example, PHP natively represents the incoming request body as the stream php://input, and uses output buffers — a form of stream — to return a response.

The message line is what differentiates a request from a response.

The message line of a request is called the request line, and has the following format:

METHOD request-target HTTP/VERSION

METHOD indicates the operation requested: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD, etc. The VERSION is typically 1.0 or 1.1 (usually 1.1 in modern web clients). The request-target is where things get complex.

A request target can be one of four different forms:

  • origin-form, which is the path and query string (if present) of the URI.
  • absolute-form, which is an absolute URI.
  • authority-form, which is the authority portion of the uri (user-info, if present; host; and port, if non-standard).
  • asterisk-form, which is the string *.

Typically, an HTTP client will use the scheme and authority from a URI to make the connection to the HTTP server, and then pass an origin-form target in the transmitted HTTP request message. However, it's perfectly valid to send the absolute URI as well. authority-form is typically only used with CONNECT requests, which are usually performed when working with a proxy server. asterisk-form is used with OPTIONS requests to get general capabilities of a web server.

In short, there's a lot of moving parts in the request-target.

Now, to make things more complicated, when we look at URIs, we have the following:

<scheme>://<authority>[/<path>][?<query string>]

The scheme, when doing HTTP requests, will be one of http or https. The path is a well-known format as well. But what about authority?


The authority always contains the host, which can be a domain name or an IP address. The port is optional, and only needs to be included if it's non-standard for the current scheme (or if the scheme is unknown). user-info is of the form:


where password is optional. In fact, in current specifications, the recommendation is to never include the password in a URI, to force prompting for the value by the client.

The query string is a set of key-value pairs delimited by ampersands:


Depending on the language implementation, it can also model lists and hashes:


PHP will parse the above to:

    'sort' => [
    'filter' => [
        'product' => 'name'

So, as if the request

Truncated by Planet PHP, read more at the original (another 25145 bytes)

SitePoint PHPIntroducing CockpitCMS – a CMS for Developers (28.1.2015, 17:00 UTC)

In this tutorial, we will see how to use Cockpit CMS to setup a CMS backend and to use the API interface provided by Cockpit to build a customized functional frontend.

Not quite like other “heavy weight”, or “fully fledged” CMS’, Cockpit is light weight and “bare”. It only provides a backend to manage meta-data and data entries, whilst the frontend is all in the developer’s hands.


A copy of Cockpit CMS can be downloaded here in zip form. After downloading, just unzip the archive to a directory on your web server that is accessible. In my case, it is mapped to: http://vagrant/cockpit.

Next, visit the installation page: http://vagrant/cockpit/install to start the installation process.

NOTE: Cockpit uses SQLite as its database engine by default. If you have not installed SQLite yet, please do so before the installation.

NOTE: Cockpit also requires that its /storage/data directory be writable. Please change the mode of that directory accordingly.

The installation is just one click. When the installation is complete, you will be greeted with this page:

Now we can log in with admin/admin and the backend administration dashboard page will be shown:

Well, we don’t have anything set up yet. Before we create our own content, let’s learn about a few key modules in Cockpit.

Modules in Cockpit

The two most important modules in Cockpit are: Collections and Galleries.

Continue reading %Introducing CockpitCMS – a CMS for Developers%

Cal EvansInterview with Jacob Mather (28.1.2015, 15:41 UTC)

Twitter: @thejmather

Show Notes

thePHP.ccPHP breaks backwards compatibility (28.1.2015, 07:00 UTC)
Evert PotA new URI handling library for PHP. (27.1.2015, 22:43 UTC)

The last little while have been all about URI's for me. I've been engaged in discussions about the upcoming 'PSR-7', I started working on a sort of 'hypermedia'-focussed router/repository type of system, and I recently ran into a bug in sabredav that forced me to get a better understanding of the URI specification, in particular on the topics of 'normalization' and resolving relative URLs.

All of this accumulated in a set of functions of operations I commonly need, which I'm now releasing as an open source library.

Yup! Yet another URI library. All this library is though, is a collection of 5 php functions:

  • resolve to resolve relative uris.
  • normalize to aid in comparing uris.
  • parse, which mostly works like PHP's parse_url.
  • build to do the exact opposite of parse.
  • split to easily get the 'dirname' and 'basename' of a URL without all the problems those two functions have.

The bug I ran into with sabredav, had to do with a client using a different encoding of a URI than I expected to. After diving into rfc3986, I realized that an application comparing uris cannot simply compare using strcmp or ===.

For example, the following uris are all identical:

  • HTTP://example.ORG/~foo/

The new normalize function can take any of these previous URIs, and will turn it into the first.


use Sabre\Uri;

$input = 'HTTP://example.ORG:80/bar/./../%7efoo/';

echo Uri::normalize($input);
// output:


I hope it's useful for others.


Derick RethansQuestions from the Field: Should I Escape My Input, And If So, How? (27.1.2015, 09:03 UTC)

Questions from the Field: Should I Escape My Input, And If So, How?

At last weekend's PHP Benelux I gave a tutorial titled "From SQL to NoSQL". Large parts of the tutorial covered using MongoDB—how to use it from PHP, schema design, etc. I ran a little short of time, and since then I've been getting some questions. One of them being: "Should I escape my input, and if so, how?". Instead of trying to cram my answer in 140 characters on Twitter, I thought it'd be wise to reply with this blog post.

The short answer is: yes, you do need to escape.

The longer answer is a bit more complicated.

Unlike with SQL, inserting, updating and deleting data, as well as querying data, does not require the creation of strings in MongoDB. All data is always used as a variable or a constant. Take for example:

$c = (new MongoClient())->demo->col;
$c->insert( [ 'name' => $_GET['name'] ] );

Because we don't need to create a string with the full insert statement, there is no need to escape with ' to prevent issues like SQL injections. The context in which variables are used is immediately clear.

But be aware that PHP's request parameters (GET, POST, COOKIE, and others) allow you to send not only scalar values, but also arrays. If we take the example code from above in mind, and request the URL http://localhost/script.php?name[first]=Derick&name[last]=Rethans, we end up inserting the following document into the collection:

[ 'name' => [
        'first' => 'Derick',
        'last' => 'Rethans'
] ]

And this is probably not what you had in mind.

The same trick is possible when doing queries. Look at this code:

$c = (new MongoClient())->demo->col;

$r = $c->findOne( [
        'user_id' => $_GET['uid'],
        'password' => $_GET['password']
] );

If we now would request the URL http://localhost/script.php?uid=3&password[$neq]=foo we end up doing the following query:

$c = (new MongoClient())->demo->col;

$r = $c->findOne( [
        'user_id' => '3',
        'password' => [ '$neq' => 'foo' ]
] );

The password clause in that query, will likely always match. Of course, if you are not storing passwords as a hash, you have other problems too! This is just a simple example to illustrate the problem.

This same example highlights the second issue - that is that all request parameters are always represented by strings in PHP. Hence my use of '3' instead of 3 in the above example. MongoDB treats '3' and 3 differently while matching, and searching for 'user_id' => '3' will not find documents where 3 is stored as a number. I wrote more extensively about that before.

So although MongoDB's query language does not require you to build strings, and hence "escape" input, it is required that you either make sure that the data is of the correct data type. For example you can do:

$c = (new MongoClient())->demo->col;

$r = $c->findOne( [
        'user_id' => (int) $_GET['uid'],
        'password' => (string) $_GET['password']
] );

For scalar values, often a cast like I've done above, is the easiest, but you might end up converting an array to the string 'Array' or the number 1.

In most cases, it means that if you want to do things right, you will need to check the data types of GET/POST/COOKIE parameters, and cast, convert, or bail out as appropriate.

SitePoint PHPBasic TDD in Your New PHP Package (26.1.2015, 17:00 UTC)

In part 1, we set up our development environment, baked in some rules as inherited from The League, and created two sample but useless classes - Diffbot and DiffbotException. In this part, we’ll get started with Test Driven Development.

If you’d like to follow along, please read Part 1 or clone the part 1 branch of this tutorial’s code.


We’ve covered PHPUnit to some degree before (1, 2, 3, 4, 5, 6), but it’s time we put it into real practice now. First, let’s check if it’s installed.

php vendor/phpunit/phpunit/phpunit

Running this command should produce a report that says one test passed. This is the test included in the League Skeleton by default and it asserts that true is, in fact, true. A coverage report will also be generated and placed into the build folder.

Continue reading %Basic TDD in Your New PHP Package%

Matthias NobackLean publishing "Principles of Package Design" (26.1.2015, 07:53 UTC)

During the great PHP Benelux Conference 2015 edition I published the final version of Principles of Package Design. Let me tell you a little bit about its history and some of the things I had to deal with.

A bit of history

My first book, A Year With Symfony, was released on September 4th, 2013. Just 6 days later, I started working on Principles of PHP Package Design. As it turned out, it was quite hard to keep the process going. There were several months in which I wrote nothing at all. Sometimes I picked up the work, but then I had completely lost my track and tried to get back on it by revising existing chapters over and over again. Meanwhile all kinds of other projects begged for attention as well, including the release of the backend project of the new website, the preparations for the Hexagonal architecture training and the birth of our daughter Julia ;)

Finally, I took a couple of weeks to focus completely on the book, and as it turned out, there wasn't really much work left. The final sprint consisted mainly of preparing the book interior for print, designing the cover, and thinking of a good way to release it. The PHP Benelux conference seemed like a good place and time to do this. I felt comfortable enough to do it there, given I am familiar with many of the attendees.

Lean/live publishing

Still, I was quite nervous to actually do this. Even though I did it before, to publish a Leanpub book in real-time is always a bit scary. But I pushed the "Publish" button nonetheless, and everything turned out well. While Leanpub was generating fresh PDF, MOBI and EPUB files, I talked a bit about lean publishing and its up- and downsides.

Lean publishing "Principles of Package Design" from matthiasnoback

The main take-aways from this are:

It's great to be able to publish early, and let readers give you feedback. But make some kind of a commitment to finish the book as well. Imagine the early adopters standing in front of you, asking you when you'll finish it and give an honest answer:

Early adopters demanding a finished book, source:

Proof reading

Also, make sure to ask people to read the book before you publish it, and provide you with some feedback. Any feedback is helpful, and also any type of reader: an experienced or an inexperienced programmer, a native English speaker, or a non-native one, etc.

One example of highly useful feedback I got from Peter Bowyer (rephrased):

It seems like you're trying to put two books into one. In the first place there's lots of information about practical PHP package development, working with Git, GitHub, Composer, Packagist, etc. Then there's also lots of information about software design and design principles, which is more theoretical of nature.

This particular comment struck me like lightening and helped me decide to leave out all the PHP-specific things and turn this into a general programming book. I'm really curious how this works out. So far it turns out that people really get a lot of practical advice from it, as well as many things to think about, while they're doing their job.

<script async="" src="//" charset="utf-8"/>

Also, because it took me about one and a half years to finish this book, its style was not really consistent at first. While re-reading the older parts it turned out that I took certain things for granted, sometimes underestimated, sometimes overestimated the audience, sometimes let myself get away with shortcuts, or

Truncated by Planet PHP, read more at the original (another 2813 bytes)

Piotr PasichIt’s Monday, you could use some motivation (26.1.2015, 07:18 UTC)
granny2Three days ago I decided to give you some motivation to start doing a code kata (see the Friday Dopamine Dump). Well, if you forgotten, haven’t got any time, had to do something more important and didn’t even try to try, then stop. No excuses! If you really want to do this – just start. […]
Nomad PHPDefensive Programming (24.1.2015, 17:32 UTC)

Presented by Christopher Pitt @assertchris Defensive programming may sound like something your granddad did after the war, but it’s key to reducing the number of bugs and increasing maintainability. We’re going to look at what defensive programming is and some steps to doing it in PHP.

The post Defensive Programming appeared first on Nomad PHP.

LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP