Christians Tagebuch Net_Webfinger 0.3.0 released (9.8.2013, 04:45)

Webfinger - a way to discover information about people by just their email address - changed quite a bit since I wrote the first version of Net_WebFinger, a PHP library to do this discoveries.


The now 13th iteration of the spec got rid of RFC 6415, requiring only a single HTTP request to fetch the information:

The default serialization format now is JRD, the JSON version of XRD.

CORS is now mandatory, so that web-applications can fetch the files, too.

Package releases

To accommodate these changes, I released version 0.3.0 of Net_WebFinger, together with version 0.3.0 of XML_XRD that is used to parse the underlying XRD/JRD files.

I also took the time to update Net_WebFinger's and XML_XRD's documentation .

Net_Webfinger now supports the new Webfinger draft, but is still able to fall back to the old system - many providers, Google among them, didn't make the switch yet.

XML_XRD fully supports reading and writing JRD files now.

Happy discovery.

I'm looking for a new job. If you can recommend a company in Leipzig/Germany that's looking for a PHP developer, please drop me a mail.

PHP_CodeSniffer 1.4.6 and 1.5.0RC3 released (25.7.2013, 05:10)

PHP_CodeSniffer versions 1.4.6 and 1.5.0RC3 have just been uploaded to PEAR and are now available to install. Version 1.4.6 is primarily a bug fix release but also contains a new JSON report format a huge number of sniff docs and a few new sniffs (mostly in the Squiz standard)...

Christians Tagebuch PHP: HTTP content negotiation (15.7.2013, 20:05)

HTTP requests contain header that explain which data the client accepts and is able to understand: Type of the content (Accept), language (Accept-Language), charset and compression (encoding).

By leveraging this header values, your web application can automatically deliver content in the correct language. Using content types in the Accept headers, your REST API doesn't need versioned URLs but can react differently on the same URL.

Header value structure

Acceptance headers are comma-separated list of values with optional extension data. One additional data point - quality - determines a ranking order between the values.

Simple header

Accept: image/png, image/jpeg, image/gif

Here the HTTP client expresses that he understands only content of MIME types image/png, image/jpeg and image/gif.


Accept: image/png, image/jpeg;q=0.8, image/gif;q=0.5

Both image/jpeg and image/gif have a quality value now. jpeg's 0.8 is higher than gif's 0.5, so jpeg is preferred over gif. image/png has no explicit quality value, so the default quality of 1 is used. This means that in the end, png is preferred over jpeg, which is preferred over gif.

So if the server has the data available in two formats .png and .jpeg, it should send the png file to the client.

Quality values may appear in any order:

Accept: image/gif;q=0.5, image/png, image/jpeg;q=0.8


Apart from the q quality extension, other tokens may be used:

Accept: text/html;video=0, text/html;q=0.9

In this example, the client prefers to get the HTML page without videos, but also falls back to the "normal" HTML page. (Note that this is an fictive example. There is no video token standardized anywhere.)

Parsing header values

Parsing and interpreting the Accept* headers is not simply an explode() call, but you also need to strip away the extensions and order the values by their quality.

Instead of implementing this all yourself, you can rely on a the stable and unit-tested library HTTP2 from PEAR.

Installation is simple:

$ pear install HTTP2-beta

To use it, simply require HTTP2.php:

require_once 'HTTP2.php';


The PHP Extension Community Library has an extension pecl_http which provides functions for HTTP content negotiation.

Truncated by Planet-PEAR, read more at the original (another 6159 bytes)

Christians Tagebuch PHP: Determine absolute link URLs (3.7.2013, 18:13)

When parsing HTML and following links, it is necessary to calculate absolute URLs from the href attribute values in and tags.

Link classes

Different types of link classes may occur in an HTML document:

Absolute URL
An URL with scheme (protocol), host and path.
Absolute URL without scheme
The scheme is missing, but host and path are given. The document's protocol has to be used in this case, according to RFC 3986 section 4.2 and section 5.2.2.
Path-absolute URL without host
Scheme, hostname and port are missing - only an absolute path is given.
Relative path
A simple relative path.
Fragment only
An anchor with a hash sign in front. Links to another section in the same document.

To resolve those URLs, you need both the document URL and the link href value.


Implementing the whole resolving algorithm is tedious, and you don't have to do it yourself. There are several implementations out there.


PEAR offers the Net_URL2 package. Its resolve() method implements the procedure properly, is unit-tested and has no other dependencies. Example:

// $abs is ''

Absolute URL deriver

absolute-url-deriver is a small composer-installable lib for resolving relative URLs.

While this library consists of one file only, it depends on another lib (much larger) that provides URL handling.

Empty URLs

HTML5 allows empty action attributes in

tags. Both libraries listed above cope with that; they return the source URL when the "target" URL is empty.

Base href

HTML documents may have a tag in their head section. When resolving links, you need to use this one instead of the document's URL itself. See my XPath article for more information about extracting attribute values from HTML.

Christians Tagebuch PHP_CodeSniffer + emacs 24: Compilation error (6.5.2013, 08:25)

After ugprading to Ubuntu 13.04, emacs did not highlight compilation results from PHP_CodeSniffer anymore. Instead of a nicely colored log window, had the following in the *Messages* buffer:

Warning: defvar ignored because compilation-error-regexp-alist is let-bound
(No files need saving)
Error during redisplay: (void-variable compilation-error-regexp-alist) [4 times]
Compilation exited abnormally with code 1

A bug report gave me the hint about what to change:

To have the compilation mode variables globally available, I need to require the module in global scope, not in the scope of my phpcs-compilation definition.

So after adding (require 'compile) before (defun phpcs() .. in my .emacs file, compilation works properly again.

PHP_CodeSniffer 1.4.5 and 1.5.0RC2 released (3.4.2013, 22:55)

PHP_CodeSniffer versions 1.4.5 and 1.5.0RC2 have just been uploaded to PEAR and are now available to install. Version 1.4.5 is primarily a bug fix release although there are a few new sniffs and sniff settings that some developers may find useful. In addition to these changes 1.5.0RC2 contains big...

Christians Tagebuch PEAR: Search packages in all channels using Pyrus (8.2.2013, 17:02)

Our old and trusted PEAR Installer supports multiple package sources, called "channels", since version 1.4.0 - which was released in 2005. You can host a channel yourself using one of the channel server applications. The most popular one is probably Pirum.

One of the problems with such a distributed network is finding the channel that provides the package you are looking for.

Pyrus, the PHP 5.3+ PEAR installer, has a solution for that:

$ pyrus search mockery
Pyrus version 2.0.0a4 SHA-1: 72271D92C3AA1FA96DF9606CD538868544609A52
Using PEAR installation found at /opt/phpfarm/inst/php-5.3.16/pear
Searching for mockery
1 packages found:

$ pyrus install
Pyrus version 2.0.0a4 SHA-1: 72271D92C3AA1FA96DF9606CD538868544609A52
Using PEAR installation found at /opt/phpfarm/inst/php-5.3.16/pear
Sorry, the channel "" is unknown.
Do you want to add this channel and continue?

Please choose: 
[yes] : 
Discovery of channel successful

Pyrus is able to search all existing channel servers and automatically discover then when they are not known yet.

Technical background

When running pyrus search, it asks the online service This service checks for package releases on the channel servers every night and indexes them.

The list of channel servers that uses is fetched from , which is an export of our PEAR channel server list.

So if you want Pyrus to find the packages of your PEAR channel, register your channel on this list.

PHP_CodeSniffer 1.4.4 released (6.2.2013, 23:28)

PHP_CodeSniffer version 1.4.4 has just been uploaded to PEAR and is now available to install. This is primarily a bug fix release although there are a couple of nice new sniff features that some developers may find useful including a new sniff to run CSS Lint on your CSS...

PHP_CodeSniffer 1.4.3 released (4.12.2012, 03:27)

PHP_CodeSniffer version 1.4.3 has just been uploaded to PEAR and is now available to install. This is primarily a bug fix release although support for the upcoming PHP 5.5 T_FINALLY token has been added a few PSR-2 issues have been fixed and a change has been made to improve...

PHP_CodeSniffer general memory improvements (15.11.2012, 04:38)

PHP_CodeSniffer version 1.3.6 introduced memory improvements when using the summary report. You can take a look at the improvements that were reported at the time when running over the Symfony2 codebase. Obviously the summary report is only useful when running PHP_CodeSniffer from the command line and viewing the output...

Links RSS 0.92   RDF 1.
Atom Feed  
PHP5 powered   PEAR
Link the Planet <a href="">Planet PEAR</a>