Linting PHP with phpcs sniffs

Linting is the process of using an automated tool to scan your code for problems before you commit and deploy. It is a practice widely used in the development workflow of many languages, but hasn’t much been used in the PHP of WordPress developers.

The most commonly used linter in PHP right now is called “PHP Code Sniffer”, or phpcs for short. In this post I’ll show you how to install it in a project folder, configure it, and set up your editor to display its messages.

Sniff Codes

To phpcs, an “error” or a “warning” is generated by a function that checks PHP code for certain conditions.

phpcs calls a set of related errors or warnings a “sniff”.

Sniffs can be grouped together into a “category”.

phpcs calls a collection of categories a “standard”.

To make multiple sniff standards available in a single project, install the composer package dealerdirect/phpcodesniffer-composer-installer. That will automatically use all installed standards in the current project with the composer type phpcodesniffer-standard when you run phpcs.

To install that package in a PHP project, run the following (assuming you already have composer installed).

composer require --dev dealerdirect/phpcodesniffer-composer-installer

Each error or warning in a sniff has a “sniff code” which identifies it explicitly. A full sniff code includes the standard, the category, the sniff, and the error or warning, all separated by periods.

Standard.Category.Sniff.Error

For example:

MyStandard.MagicMethods.DisallowMagicGet.MagicGet

It’s possible to refer to all the errors in a sniff by omitting the error name. It’s further possible to refer to all the sniffs in a category, or the categories in a standard, but omitting those fields as well.

Therefore, these are all valid codes:

MyStandard.MagicMethods.DisallowMagicGet.MagicGet
MyStandard.MagicMethods.DisallowMagicGet
MyStandard.MagicMethods
MyStandard

Built-in Standards

phpcs comes with several standards built-in. You can see them on the command-line by running phpcs -i. These include PEAR, PSR1, PSR2, Squiz and Zend.

WordPress has its own standard which you can install with composer as well.

composer require --dev wp-coding-standards/wpcs

I highly recommend the VariableAnalysis standard which looks for undefined and unused variables.

composer require --dev sirbrillig/phpcs-variable-analysis

Configuring Standards

When installing sniff standards in a project, you edit a phpcs.xml file with the rule tag inside the ruleset tag. The ref attribute of that tag should specify a standard, category, sniff, or error code to enable. It’s also possible to use these tags to disable or modify certain rules. The official annotated file explains how to do this.

For example, this would enable all the sniffs in a standard called MyStandard:

<?xml version="1.0"?>
<ruleset name="MyProject">
  <description>My PHP project.</description>
  <rule ref="MyStandard"/>
</ruleset>

The following configuration will enable all the sniffs in MyStandard, VariableAnalysis, and WordPress.

<?xml version="1.0"?>
<ruleset name="MyProject">
 <description>My PHP project.</description>
 <rule ref="VariableAnalysis"/>
 <rule ref="MyStandard"/>
 <rule ref="WordPress"/>
</ruleset>

Configuring An Editor

To run phpcs on a file in your project, just use the command-line as follows (the -s causes the sniff code to be shown, which is very important for learning about an error).

vendor/bin/phpcs -s src/MyProject/MyClass.php

When it runs, phpcs will report any errors or warnings it finds. That’s pretty handy, but I find that it’s even more valuable to have linters run directly in your editor so that you can see problems as you code. Pretty much all editors support this, but the method of installation depends on your editor.

For vim, I recommend you install the ALE plugin. This has phpcs support already built-in and will use the standards you have configured in your project.

For phpstorm, the linting support is built-in, but you have to configure the app to know where to look. This guide shows how to set the path and enable the inspections. The guide neglects to mention that the path setting is under Preferences > Languages & Frameworks > PHP > Code Sniffer, and that the path should be set to your local installation of vendor/bin/phpcs. It also neglects to say that the inspections are under Preferences > Editor > Inspections and that you have to set the “Coding standard” to your phpcs.xml file manually (you may also want to disable some of the existing Inspections).

Ignoring Rules

Sometimes you’ll need to ignore or disable one of the sniffs in a standard. The official documentation explains how to do this. You can surround or prefix your code with special comments to instruct phpcs to ignore it. Note that you cannot disable specific sniffs in this way; phpcs will ignore all of them for the marked lines.

$xmlPackage = new XMLPackage;
// @codingStandardsIgnoreStart
$xmlPackage['error_code'] = get_default_error_code_value();
$xmlPackage->send();
// @codingStandardsIgnoreEnd
$xmlPackage = new XMLPackage;
// @codingStandardsIgnoreLine
$xmlPackage['error_code'] = get_default_error_code_value();
$xmlPackage->send();

In the upcoming version 3.2 of phpcs, this feature will be greatly improved. The above special comments will be replaced with // phpcs:disable/// phpcs:enable and // phpcs:ignore respectively. You’ll also be able to use // phpcs:ignore on the same line as a statement.

Even better, you’ll be able to disable specific rules with either form by listing the sniff codes (comma-delimited) at the end of the special comment. For example, this will be possible.

doSomethingBad(); // phpcs:ignore MyStandard.Functions.PreventBadThings

You can even include comments in the disabling line!

doSomethingBad(); // phpcs:ignore MyStandard.Functions.PreventBadThings -- We are ok with bad things here

If there are specific sniffs you wish to ignore for your entire project, you can configure them in the phpcs.xml file and set their severity to 0. Here’s an example of disabling the WordPress function comment rule (standards can contain other standards, so some WordPress rules are actually part of the Squiz standard).

<?xml version="1.0"?>
<ruleset name="MyProject">
 <description>My PHP project.</description>
 <rule ref="VariableAnalysis"/>
 <rule ref="WordPress"/>
 <rule ref="Squiz.Commenting.FunctionComment.Missing">
     <severity>0</severity>
 </rule>
</ruleset>

In a later post, I’ll explain how a phpcs standard is built and how to create and modify your own. Until then, see if you can find some standards that you like and use them! Here is the phpcs.xml file I typically use right now for non-WordPress projects.

(Photo by Noel Lopez on Unsplash)

Maybe returning errors in PHP

A common pattern I see in WordPress PHP code (and probably other PHP code) is a function which does some operation on data and returns a value. For example, a function which makes a database query and then returns the resulting row.

In order to make more robust code and prevent bugs, I’ve been systematically trying to use more return type declarations in my functions. This is a problem for things like the database function described above because a database query (and therefore the function itself) can sometimes fail. In those cases, the function might return the intended data, or it might return an instance of WP_Error instead. PHP does not currently (as of 7.1) support the idea of declaring return types when multiple types are possible.

Of course, such a function could simply throw an Exception if it fails, but this might be not as safe for critical code. An unhandled Exception, even a trivial one, could kill the whole program. Returning an error object instead could keep the program running (depending on how it is used). Even if we do throw an Exception, it’s not always clear when reading the function that it can throw.

So there are two problems now. First, since the function can return multiple things, we cannot specify any return type at all.

What I would need to solve that is the ability to specify multiple return types like phpdoc, but even if I could, it doesn’t guarantee that the user of this function will notice and handle potential errors.

This leaves us with the second problem, which is the same as if the function could throw an Exception; it can be easy for someone using it to overlook that the function can fail.

Is there a solution to both these problems? Maybe. (That’s a poor joke, as you’ll soon see.)

Let’s take the following function as an example. This function accepts an array of user data and returns the color property.

function getColorFromUser(array $user): string {
  return $user['color'];
}

It’s contrived, but it’s a reasonable simplification of the database query problem, since the array property might not exist, and therefore it can fail.

So now let’s modify the function to return an error if it fails.

function getColorFromUser(array $user) {
  if (! isset($user['color']) {
    return new WP_Error('NO_COLOR', 'Color does not exist');
  }
  return $user['color'];
}

As you can see, we’ve lost both the return type and also made it possible to introduce bugs in code that calls this function if they expect a string and instead get an object.

$myColor = getColorFromUser($user);
echo 'My favorite color is ' . $myColor; // This could cause a problem if $myColor is not a string

The standard way to handle this situation is similar to using a try/catch for an Exception; if we are aware that the function can return an error, we can check for one before continuing.

$myColor = getColorFromUser($user);
if (! is_wp_error($myColor)) {
  echo 'My favorite color is ' . $myColor;
}

It’s just that in my experience it’s common to miss the fact that a function can return an error. It’s even worse if a function once returned only a value but is subsequently changed to be able to return errors. Since the normal (successful) flow of the code will not change, no change is actually required anywhere the function is used. This makes type errors not only possible, but likely.

But what if we instead returned a wrapper object around the data? Let’s call it a Maybe. (See? There’s the joke.)

function getColorFromUser(array $user): Maybe {
  if (! isset($user['color']) {
    return Maybe::fromError(new WP_Error('NO_COLOR', 'Color does not exist'));
  }
  return Maybe::fromValue($user['color']);
}

Now we can have a return type, which can help prevent bugs inside the function. It’s not perfect as it doesn’t explain what types of values the object can contain, but it’s better than nothing. (To be fair, if we wished, we could create specific versions of Maybe for different values, like MaybeString, but I’m just going to keep it simple for now.)

Your first reaction might be that it also creates an inconvenience for the user of this function, because in order to extract the value of this data, someone has to do it explicitly.

But that small inconvenience means the developer must know about the possible error.

The example might then look something like the following. The condition required is similar to using is_wp_error(), but it’s more probable that the developer will remember to add the condition because they are forced to use getValue() on success.

$myColor = getColorFromUser($user);
if (! $myColor->isError()) {
  echo 'My favorite color is ' . $myColor->getValue();
}

This is not a perfect solution, and I’m certain that many developers will balk at having to add a pattern like this to their workflows when it’s not a standard part of the language. Personally I think it would be worth the discomfort to adopt this sort of construct when the benefit would be code that’s significantly less likely to have type errors. It probably depends on how careful you need your code to be. What do you think?

PS: It’s perhaps relevant to mention that there are functional programming concepts that are similar to this implementation, but which take it much further. My suggestion here is a very minimal interpretation that might be easier for some developers to grok. A more accurate name for this concept, matching existing patterns, is a Result.

Here’s how the Maybe/Result could be written:

(Photo by Caleb Jones on Unsplash)

Functional Dependency Injection in PHP

Having become used to the convenience of passing first-class functions around in JavaScript to make other functions decoupled and easily testable, I was wondering if we could do the same thing in PHP.

Of course, PHP technically has first-class functions as well, but the syntax is a little awkward, since the functions must be referenced as a string (and sometimes as an array).

Often I have some logic that can easily be contained in a pure function, and while I could put it in a class method, it’s not uncommon that the function doesn’t feel like it belongs to any particular class.

In these cases I tend to create “helper” classes. Essentially, I create a god class which is really just there to namespace its functions. If there’s a group of functions I want to inject, I might use regular class methods for this purpose, injecting an instance of the class. Otherwise, I use static methods. It occurred to me that maybe I could do the same thing with plain functions and actual namespaces.

JavaScript

In JavaScript one could do the following (this example is a bit contrived, but bear with me).

export function getGreenTea() {
    return 'green tea';
}

export function getOolongTea() {
    return 'oolong tea';
}
import {getGreenTea, getOolongTea} from 'tea-types';

function makeTea(getTea) {
    console.log(getTea());
}

makeTea(getGreenTea);
makeTea(getOolongTea);

PHP instance methods

Here’s how it could be done in PHP with classes and instance methods.

class GreenTea {
    public function getTea() {
        return 'green tea';
    }
}

class OolongTea {
    public function getTea() {
        return 'oolong tea';
    }
}

public function makeTea($teaType) {
    echo $teaType->getTea() . "\n";
}

makeTea(new GreenTea());
makeTea(new OolongTea());

PHP static methods

Here’s how it could be done with classes and static functions.

class TeaTypes {
    public static function getGreenTea() {
        return 'green tea';
    }

    public static function getOolongTea() {
        return 'oolong tea';
    }
}

function makeTea($getTea) {
    echo $getTea() . "\n";
}

makeTea([TeaTypes::class, 'getGreenTea']);
makeTea([TeaTypes::class, 'getOolongTea']);

PHP namespace functions

Lastly, here’s how it could be done with just namespaces. I think this is the closest to the JavaScript version, and doesn’t require creating unnecessary classes.

namespace TeaTypes;

function getGreenTea() {
    return 'green tea';
}

function getOolongTea() {
    return 'oolong tea';
}
namespace TeaMaker;

require('./TeaTypes.php');

function makeTea($getTea) {
    echo $getTea() . "\n";
}

makeTea('\TeaTypes\getGreenTea');
makeTea('\TeaTypes\getOolongTea');

Of course, this technique might not be the best choice for some situations. If there is any shared state or expensive repeated operations between functions, then they should be in a class and the methods should not be static.

Also, passing lots of dependencies to functions can sometimes be verbose and hard to read. In these cases it can be easier to pass the dependencies as a single object instance instead.

Finally, if there are several unrelated helper functions which are used in multiple places within the methods of a class, it can be more readable to pass all the helpers to the class constructor at once as an object (as though they were related).

Still, I think that passing functions as dependency injection is an under-used technique in PHP. I know it’s not the least bit Object-Oriented, and PHP is much more of an OOP language than JavaScript. In my opinion, however, the power of OOP is shared state and polymorphism and pure functions need neither.

(The image for this post is by 童 彤 on Unsplash.)

Thoughts on Privilege

Today in my Sangha we explored the concept of Engaged Buddhism, particularly as it applies to race, gender, and class. We explored the most insidious aspect of privilege in our society: that those with privilege do not see it; we are blind to it. White people do not consider race to be a primary factor in their day-to-day affairs. Many people of color do. In fact, even the existence of the term “people of color” implies that the default race is White. Even if we “ignore race” (or any other characteristic), we are making a decision to perpetuate the discrimination that other people face constantly.

When I was young, I was bullied and insulted because I was considered a nerd. I couldn’t do a pull-up. I wasn’t interested in organized sports. I loved reading books and learning about computers. Because of these things I was considered an outcast among my peers and even many adults. My dream was always to fit in, and to that end I’ve worked my entire life to try and be one with the group, to gain the power that I felt I lacked. Of course, I didn’t see the privilege and power that I already held by the nature of my skin color, family wealth, and gender.

Since that time, nerds have become powerful. Computers and the Internet are no longer a niche in society. Their use is no longer optional. Most people in the West even carry a supercomputer in their pocket. We have achieved what might be considered an outcast’s dream: we have made ourselves indispensable to everyone. And we probably all think of ourselves as having won some great battle in the manner of the Great American Dream: with skill and talent and persistence, we were able to rise above our station and achieve that we which had been denied to us but which we richly deserved.

This, of course, is a fiction, because in most cases the only reason one is able to rise up and achieve something is when the culture allows that to happen. In my case, my whiteness and my other privileges made it possible for me to utilize the resources around me to get the things I wanted. I think the same is true for all of the technical elite of our current era. The danger is that we don’t realize what enabled us to achieve our status, instead believing it was our innate ability alone.

This incorrect view leads us to conclude that everyone has the same chance that we had. It leads us to blame those who are suffering for their own suffering. It leads to the idea that the poor are poor because they are lazy, that those convicted as criminals are evil, and that those who are in power deserve to be there.

Even within the open-source software world, the myth of the meritocracy is one example of this pervasive idea. It goes something like, “if we don’t see a person’s appearance, gender, real name, or class, and if contributions can be made by anyone freely without position or power, then surely the best ideas will rise to the top and everyone will be evaluated and judged only by their skill.”

What this concept fails to take into account is that an open-source project is a community of people, and all communities are bound by the same rules of privilege that exist in the “real world”. Contributing to a “free” project still means spending time, and it likely means spending money for a computer, special tools, and most importantly access to information. Does everyone have these resources available? Is everyone encouraged in their pursuits, supported by their families and communities?

If we treat “tech” as a meritocracy, then we might as well say that landscape painting is a meritocracy. After all, it’s just paint on canvas, and one need never see or know the identity of the person who painted a picture. But of course, amazing painters are not born, they are made through training and practice. This is not to say that different people don’t have different innate abilities, but that those abilities are only a small part of what brings about success. The rest is the often-invisible support of thousands of other people who open the doors to the skill which we think we earn.

So how do we work to change these things? How can we make a difference? If there was an easy answer to those questions, we’d all know about it already. But I believe the first step is to examine our experiences and always look for the support from others, the little forgiveness, the gifts of time and money and information; in short, to look for our privilege as it manifests. Only then, I think, can we work to dismantle the invisible architecture that separates Us from Them.

(Photo by Nicholas Green on Unsplash)

Search for the Sage

My fourth D&D adventure crafted for the Automattic Grand Meetup, Search for the Sage is a one-shot game perfect for new and experienced players alike. It runs in about 3-4 hours. I had a lot of fun creating and running this one! Huge thanks to the many friends who played through this adventure and extra huge thanks to those who DMed it.

Here’s the teaser:

A town sinks slowly into the sea and only the power of an ancient sage can save it. But can the sage be found in time? There’s only one way to find out.

Would you like to try to find the sage yourself? Download the adventure here.

(Incredible formatting courtesy of The Homebrewery. Check them out!)

Photo by Jason Wong.

Declarative vs. Imperative: asking for soup vs. making soup

A little while ago I wrote a post about my concepts of declarative vs. imperative programming. I ended that article by saying, “I can’t wait to see what I’ll learn next.” Well, I’ve found another definition which has been very helpful to me lately. Also, I’m a little worried that it might actually be the opposite of my previous example. I guess that’s learning?

Declarative language describes what you want to happen, without necessarily explaining every step of the process to get there. “I want butternut squash soup.”

Imperative language describes every step toward making something happen. “I want a butternut squash that’s been cut in two, seeds removed, roasted, peeled, and blended with broth and spices.”

Of course, there’s quite a spectrum implied by those two words. How specific can we get in imperative language? “I want a butternut squash” already makes certain assumptions. How about, “I want an orange, long, vine grown winter squash”? This could go on all day. It really depends on the domain or the context in which your language will be used.

So back to programming. Most programming languages (at least the ones I’m familiar with) are decently imperative. With such a tool, you can use statements and conditions to tell the computer exactly what you want to happen and when.

On the other hand we have artifacts like HTML, the building-block of the World Wide Web. I know plenty of people who consider writing HTML to be using a programing language, and yet it actually falls much more on the declarative side of the spectrum. With HTML you describe what you want to happen to some content and each browser that reads that HTML must figure out how to do what you’ve asked. For example it may need to switch font weights if you’ve used a strong tag to wrap some text.

That said, declarative language relies on imperative language. Every declarative tool, like HTML, has been generated by humans wanting to simplify their work. They got tired of doing something repetitive and so they wrote a tool to convert it from a simpler form. Asking for soup is not very useful if no one in the room knows how to cook.

One more thought: writing HTML is declarative compared to, say, using JavaScript to edit the DOM. Yet there are other layers, like Markdown, which are in some ways even more declarative than HTML. It’s only in comparison that we can say that one thing is declarative and another is imperative, so always be on the lookout for other perspectives. And hey, that goes for the real world too.

Lightweight rendering of React to strings

For a recent project I needed to be able to render React components (or really, just React-like components) into plain HTML strings. Of course, React provides a mechanism to do this: renderToStaticMarkup in its ReactDOM library. But wow, that library is a really big dependency to import if I don’t want any of the DOM reconciliation stuff.

Also, it turns out I don’t even need React lifecycle events for my project. I don’t need component state either. I just want to render a bunch of stateless components with props and children. Something like this:

Well, maybe there’s a way to just import part of the rendering engine… but then I realized I had yet another requirement: I need to be able to modify the string version of every component as it is created. I can’t do that with React. I need a custom renderer.

Happily, with some experimentation I learned that it’s not that hard to create one! Below you can see my version of renderToString(). It accepts both stateless functional components and component classes.

Of course, the version below is a bit naive. I’m certain there’s many edge cases of rendering which it does not cover, and like I said above, it does not support state or lifecycle events at all. That said, it works very well for my own purposes and I learned a lot about how React components are put together in the doing!

The following also includes a full test suite to show how it works.