You Can Write Good PHP

by Madeleine Thompson, 2018–11–23

PHP deserves its bad reputation, but it is possible to write reliable, clear PHP.

Each of these, either I had to learn it the hard way, or I see people suffering unnecessarily because they don't do it.

  1. Use PHP 7 or later. This lets you use type annotations.
  2. Use type annotations on all arguments and return values. You'd be documenting what's valid in comments anyway, right? Save yourself the typing and make it enforceable.
  3. As part of your build process, run php -l to check the syntax of every .php file in your project.
  4. Every .php file should begin with declare(strict_types=1);. You want to get good errors if your type preconditions are violated.
  5. Use Composer. It makes dependency management much easier.
  6. Use the Composer autoloader instead of typing require_once everywhere. It forces you to use consistent naming, and it saves you the trouble of writing all the require_once boilerplate.
  7. Use PHP CodeSniffer to enforce a uniform style. I recommend phpcs --standard=PSR12, but which standard you use is less important than having one.
  8. Use PHPStan to find bugs before you even run your code. Run phpstan analyze at the highest -l level you can.
  9. Write unit tests in PHPUnit. No library file should be without unit tests. Having tests lets you code without fear of breaking something.
  10. If you're writing a webapp, write integration tests with Selenium.
  11. If you're writing a service, write integration tests for that, too.
  12. If you're writing or generating HTML, check its syntax in your tests. I use Python html5lib.

Things not to do, not even on your small side project:

  1. Don't construct HTML manually. Use an autoescaping template system like Mustache, or bad things will happen to you. I know this sounds silly, since PHP is a template system. It is an unsafe one. Use a proper template system.
  2. Don't let users put their HTML in your page, or bad things will happen to you. If you must, use HTML Purifier.
  3. Don't construct SQL manually. Use parameterized queries, or bad things will happen to you.
  4. Don't put passwords, API keys, or other secrets in your code. Use a key management service like AWS KMS instead. You don't want anyone who can read your code to be able to access your production service.