Send additional HTTP headers to Nginx’s FastCGI

It’s not that often that I come across a useful, but undocumented feature in a major software application.  It happened recently, so I’ll document it here just for the future self.

For a particular setup, I had to send additional HTTP headers (let’s use X-GEOIP for this example) to the PHP-FPM, which was configured as a FastCGI backend in Nginx web server.  This StackOverflow thread suggested several solutions, but this one was the easiest and worked like a charm: use Nginx’s fastcgi_param directive AND prefix your variables with HTTP_.  For example:

location ~ \.php$ {
  fastcgi_param HTTP_X_GEOIP $geoip;
  ... other settings
}

 

PHP CodeSniffer: Ignoring rules

PHP CodeSniffer is a great tool for making sure all your code is consistent with a set of rules and guidelines. However, there are cases, when you need to ignore the rules for a particular code snippet. For example, when you are working with third-party frameworks or libraries.

CodeSniffer provides a number of ways to do this. Until today, the following worked well for me:

// @CodingStandardsIgnoreStart
echo "Here goes some code that breaks the rules";
// @CodingStandardsIgnoreEnd

This is particularly useful for code within functions and methods. But what if you need to ignore a particular rule for the whole file, especially in places like method names, which are difficult to surround by starting and ending annotation tags?

Here’s an example that worked for me (thanks to this comment for the solution):

<?php
/**
 * @phpcs:disable CakePHP.NamingConventions.ValidFunctionName.PublicWithUnderscore
 */

The only bit that you’d probably need now is an easy way to find the name of the rule from the CodeSniffer output. The usual output of “./vendor/bin/phpcs” looks like so:

FILE: src/Model/Table/KeysTable.php
-----------------------------------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
-----------------------------------------------------------------------------------------------------
 53 | ERROR | Public method name "KeysTable::_initializeSchema" must not be prefixed with underscore
-----------------------------------------------------------------------------------------------------

But if you run it with the “-s” flag (thanks to this comment), CodeSniffer will add sniff codes to all reports. Here’s the same example with “./vendor/bin/phpcs -s“:

FILE: src/Model/Table/KeysTable.php
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 53 | ERROR | Public method name "KeysTable::_initializeSchema" must not be prefixed with underscore
    |       | (CakePHP.NamingConventions.ValidFunctionName.PublicWithUnderscore)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------

And that’s the code sniff rule that you can add to the ignore annotation tag at the top of your file, like I’ve shown above.

GitHub adds PHP and Composer dependency graphs

Here are some great news from GitHub: Dependency graph support is now available for PHP repositories with Composer dependencies.

You may see security alerts on your repositories as dependency graph support rolls out. When there’s a published vulnerability on any of the Composer dependencies that your project lists in composer.json and composer.lock files, GitHub will send you an alert including email or web notifications, depending on your preferences.

These now work for both public and private repositories, and repository admins can enable or disable the features as needed.

PHP vs P++

If you haven’t heard the news yet and are wondering what the heck P++ is, here’s a quick update for you. There’s been some noise around the idea of creating a separate dialect of PHP, code-named P++. The idea is an attempt to find a compromise between two different schools of thought on the evolution of PHP programming language: maintaining backward-compatibility for as long as possible and cutting historical baggage off to allow for faster development cycle and more of those new shiny features.

Here’s the FAQ with some details and explanations:

Trying to shorten the lengthy email into a couple of points:

* There are two big, substantial schools of thought in the PHP world. The first likes PHP roughly the way it is – dynamic, with strong BC bias and emphasis on simplicity; The other, prefers a stricter language, with reduced baggage and more advanced/complex features.

* There’s no ‘right’ or ‘wrong’ here. Both schools of thought are valid, and have a very substantial following. However, it’s challenging to create a language that caters to both of these crowds at the same time – which is a constant source of contention on internals@.

* The proposal is to create a new dialect of PHP (code named P++) that will live alongside PHP, but won’t be bound by the historical philosophy behind the language. In other words, this new dialect could be inherently more strict, it could be more daring with BC and remove elements that are considered ‘baggage’ (such as short tags), and adding more complex features – especially ones that are a good fit for strictly typed languages – without having to introduce the same complexity to the PHP dialect.

This is not a fork. The code base will be identical, the developers working on that codebase will be the same. The vast majority of the code would be identical. Only the specific points of difference between the two dialects will have different implementations. It is somewhat similar to what was done with strict_types in PHP 7 – only on a larger scale.

And here are a couple of other articles with some thoughts, links, and arguments:

Personally, I understand the challenges that brought up this idea and I applaud every effort that tries to find the solution to these problems.

But…

I don’t like this particular approach. I don’t think it solves the actual problem. Instead it just buys some time until it comes back again. Much like the current arguments of what to drop and what to keep in PHP, we’ll be fighting over what to keep in P++ and what to push into the PHP.

The new versions will keep coming, bringing new features and new backward compatibility issues. If we are to address this, I think a more strategic approach should be used.

I think most people are not compiling custom PHP binaries these days, but rely on some kind of distribution packages, so I will ignore the compilation discussion and focus on distrubtion instead. From this perspective, I would prefer to have additional packages for support of legacy PHP versions. Something along the lines of:

  • php-7.3.0-common.rpm (main PHP 7.3 package)
  • php-7.3.0-legacy-7.2.rpm (legacy features from PHP 7.2)
  • php-7.3.0-legacy-7.1.rpm (legacy features from PHP 7.1)
  • … and so forth.

This allows more control as to what is available on the system. It also falls into the Composer platform paradigm of checking which PHP version and extensions are installed. This will still require quite a bit of work to implement, test, and get people to use. But I think it’s a better approach for the long term, and it is an easier transition for the short term.

This is something to keep an eye on, as I think there will be a lot of insightful discussion all over the web about it.