Matthias NobackUsing phploc for a quick code quality estimation - Part 1 (20.9.2019, 12:30 UTC)

When I want to get a very rough idea of the quality of both code and structure of a PHP code base, I like to run phploc on it. This is a tool created by Sebastian Bergmann for (I assume) exactly this purpose. It produces the following kind of output:

Directories                                          3
Files                                               10

  Lines of Code (LOC)                             1882
  Comment Lines of Code (CLOC)                     255 (13.55%)
  Non-Comment Lines of Code (NCLOC)               1627 (86.45%)
  Logical Lines of Code (LLOC)                     377 (20.03%)
    Classes                                        351 (93.10%)
      Average Class Length                          35
        Minimum Class Length                         0
        Maximum Class Length                       172
      Average Method Length                          2
        Minimum Method Length                        1
        Maximum Method Length                      117
    Functions                                        0 (0.00%)
      Average Function Length                        0
    Not in classes or functions                     26 (6.90%)

Cyclomatic Complexity
  Average Complexity per LLOC                     0.49
  Average Complexity per Class                   19.60
    Minimum Class Complexity                      1.00
    Maximum Class Complexity                    139.00
  Average Complexity per Method                   2.43
    Minimum Method Complexity                     1.00
    Maximum Method Complexity                    96.00

  Global Accesses                                    0
    Global Constants                                 0 (0.00%)
    Global Variables                                 0 (0.00%)
    Super-Global Variables                           0 (0.00%)
  Attribute Accesses                                85
    Non-Static                                      85 (100.00%)
    Static                                           0 (0.00%)
  Method Calls                                     280
    Non-Static                                     276 (98.57%)
    Static                                           4 (1.43%)

  Namespaces                                         3
  Interfaces                                         1
  Traits                                             0
  Classes                                            9
    Abstract Classes                                 0 (0.00%)
    Concrete Classes                                 9 (100.00%)
  Methods                                          130
      Non-Static Methods                           130 (100.00%)
      Static Methods                                 0 (0.00%)
      Public Methods                               103 (79.23%)
      Non-Public Methods                            27 (20.77%)
  Functions                                          0
    Named Functions                                  0 (0.00%)
    Anonymous Functions                              0 (0.00%)
  Constants                                          0
    Global Constants                                 0 (0.00%)
    Class Constants                                  0 (0.00%)

These numbers are statistics, and as you know, they can be used to tell the biggest lies. Without the context of the actual code, you can interpret them in any way you like. So you need to be careful making conclusions based on them. However, in my experience these numbers are often quite good indicators of the overall code quality as well as the structural quality of a project.

For example, lots of static method calls often indicates a design problem, and the same goes for the existence of many abstract classes. In this article I'd like to point out what some of these numbers mean to me and how I use them to get some understanding of the situation, and how to improve it.


  Lines of Code (LOC)                             1882
  Comment Lines of Code (CLOC)                     255 (13.55%)
  Non-Comment Lines of Code (NCLOC)               1627 (86.45%)
  Logical Lines of Code (LLOC)                     377 (20.03%)

Lines of Code, Comment Lines of Code versus Non-Comment Lines of Code and Logical Lines of Code, aren't usually that interesting. The total number of lines gives me some idea of the size of the project, compared to other projects I've worked with in the past. However, the length of classes and methods is important. A large value for Maximum Class Length means you have at least one class that's way too big. Based on the Average Class Length value you can deduce whether that will be one big class, or many of them.


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

Voices of the ElePHPantInterview with Bob Dunn (19.9.2019, 17:25 UTC) Link
Derick RethansPHP Internals News: Episode 28: Moving PHP Documentation to GIT (19.9.2019, 08:28 UTC)

PHP Internals News: Episode 28: Moving PHP Documentation to GIT

In this episode of "PHP Internals News" I chat with Andreas Heigl (Twitter, GitHub, Mastodon, Website) about his endeavours of moving the PHP Documentation project from SVN to GIT.

The RSS feed for this podcast is, you can download this episode's MP3 file, and it's available on Spotify and iTunes. There is a dedicated website:

Show Notes


Music: Chipper Doodle v2 — Kevin MacLeod ( — Creative Commons: By Attribution 3.0

Become a Patron!
Christian WeiskeHTTP headers for debugging (19.9.2019, 05:27 UTC)

In my PHP web applications I sometimes use custom HTTP headers to aid debugging when things go wrong.

The Laravel framework redirects unauthenticated users to the login page when they access an URL that requires an authenticated user. Especially with API clients this is not helpful, and so my user guard implementation sends a "redirect reason" header with specific explanations:

X-Redirect-Reason: User token is invalid

This helped me a couple of times already, and prevents me from digging into the authorization code.

Another header is used in error handlers to provide more information than just "404 Not Found":

X-404-Cause: CRUD ModelNotFound

Other reasons could be that the user is not allowed to access the resource for auth reasons, or that the model exists in database but has been deleted.

Others using custom headers

Content Delivery Networks (CDNs) often aid debugging with custom HTTP headers. Fastly uses X-Cache, Akamai uses multiple headers like X-Check-Cacheable, X-Akamai-Request-ID, X-Cache and X-Cache-Remote.

Apache's Traffic Server has a XDebug plugin that sends out X-Cache and other headers.

The PHP FOSHTTPcache library aids debugging by configuring Varnish to send out a X-Cache header indicating cache hits and misses.

PHP HTTP client library Guzzle tracks the redirect history of a single HTTP request in the X-Redirect-History header.

TYPO3's realurl extension sends out X-TYPO3-RealURL-Info indicating what the reason for a redirect was:

X-TYPO3-RealURL-Info: redirecting expired URL to a fresh one
X-TYPO3-RealURL-Info: redirect for missing slash
X-TYPO3-RealURL-Info: redirect for expired page path
X-TYPO3-RealURL-Info: postVarSet_failureMode redirect for ...
PHP: Hypertext PreprocessorPHP 7.4.0RC2 Released! (19.9.2019, 00:00 UTC)
The PHP team is glad to announce the second release candidate of PHP 7.4: PHP 7.4.0RC2. This continues the PHP 7.4 release cycle, the rough outline of which is specified in the PHP Wiki. Please DO NOT use this version in production, it is an early test version. For source downloads of PHP 7.4.0RC2 please visit the download page. Please carefully test this version and report any issues found in the bug reporting system. For more information on the new features and other changes, you can read the NEWS file, or the UPGRADING file for a complete list of upgrading notes. These files can also be found in the release archive. The next release would be 7.4.0RC3, planned for October 3rd. The signatures for the release can be found in the manifest or on the QA site. Thank you for helping us make PHP better.
Evert PotThe end of the HTTP series (18.9.2019, 15:00 UTC)

Last year I quit my job at Yelp, and wanted to be a more active blogger again. I thought it would be a neat idea to write 1 post per week, one for each HTTP status.

This was quite an undertaking, and I ended up having to write 67 blog posts, one each week.

Some stats:

  • 67 HTTP statuses.
  • 70 blog posts written.
  • 18091 words written.
  • Articles written in 9 cities, 5 countries.
  • 53,511 page views.

Was it worth it? I don’t really know. I had higher hopes in terms of popularity. Most of the traffic comes from search results and hotlinks, but I don’t think I achieved what I had really hoped: build a bit more of a consistent audience.

I think part of the problem with building audiences is that people don’t really subsribe to RSS feeds anymore. I offered a twitter feed and a mailing list as well, but who wants to receive more emails? It seems that most people consume their technical content from aggregrators like Hackenernews and silos like Medium.

It feels like a big loss that RSS feeds have gone out of fashion, not just for me but also the industry. I still miss the blogging revolution of the mid-2000’s. Or maybe HTTP statuses are just wayy too boring, and I mistook my own interest with everyone else’s.

Still, I’m glad that I saw it all the way through, and it’s nice to see that people seem to find these pages on google, or use them as a reference. There’s definitely a few in there that have some nuance, so I hope I positively contributed to the API ecosystem.

For the few that followed this series, thank you!

Voices of the ElePHPantInterview with Katie McLaughlin (14.9.2019, 21:31 UTC)
Voices of the ElePHPantInterview with Junade Ali (14.9.2019, 15:05 UTC)
Derick RethansPHP Internals News: Episode 27: Argument Information (12.9.2019, 08:27 UTC)

PHP Internals News: Episode 27: Argument Information

In this episode of "PHP Internals News" I chat with Nikita Popov (Twitter, GitHub) about adding information about arguments and return types to PHP's reflection mechanism.

The RSS feed for this podcast is, you can download this episode's MP3 file, and it's available on Spotify and iTunes. There is a dedicated website:

Show Notes


Music: Chipper Doodle v2 — Kevin MacLeod ( — Creative Commons: By Attribution 3.0

Become a Patron!
Rob AllenSlim4-empty: minimal Slim 4 starting point (11.9.2019, 10:00 UTC)

To simplify creating a new Slim 4 project, I've created slim4-empty which does this for me.

To use it:

$ composer create-project akrabat/slim4-empty my-new-project

and you're done!

The my-new-project directory is created and contains Slim 4 along with a minimally viable public/index.php to get you going. You can then run it with the PHP built-in server:

php -S -t public/

And navigate to https://localhost:8888 to view "Hello World" in your browser.

What does it contain?

Slim4-empty provides no structure to your project and adds no extraneous components at all. You do the rest. It simply contains the following:

Slim & Slim-Psr7

The composer create-project command will create a new directory (my-new_project) and then within it will install Slim and Slim-Psr7. Of course with Slim 4, you are free to use any PSR-7 component, but I happen to like our one :)


Within the public directory, slim4-empty provides a minimal index.php:



use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Factory\AppFactory;

require __DIR__ . '/../vendor/autoload.php';

// Create app
$app = AppFactory::create();

// Register middleware
$app->addErrorMiddleware(true, true, true);

// Register routes
$app->get('/[{name}]', function (
    ServerRequestInterface $request,
    ResponseInterface $response,
    array $args
): ResponseInterface {
    $name = $args['name'] ?? 'world';
    $response->getBody()->write("hello $name");
    return $response;

// Run app

As you can see from the comments, it does the following:

  • Create the App instance – The AppFactory does all the hard work here for us by finding the PSR-7 component and registering it.
  • Register a minimal set of middleware – Slim's default error handling is flexible and you should use it. The body parsing middleware is mostly useful for APIs, but doesn't impact performance for standard websites. The routing middleware is required to route from a URL to a handler. If it's missing, it'll be added by slim, but this is a case where I prefer to be explicit.
  • Add a route for / – Nothing works without a route! This is a minimal one that you can change to suite your needs.
  • Run the application – This will run the middleware stack and then run the route handler and send the response back to the client (web browser).

Who can remember all that? I have to go and copy/paste it, which is why I wrote slim4-empty!

That's it

Maybe it's useful to someone else other than me; I'm certainly finding it helpful!

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