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.
- Use PHP 7 or later. This lets you use type annotations.
- 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.
- As part of your build process, run
php -l
to check the syntax of every.php
file in your project. - Every
.php
file should begin withdeclare(strict_types=1);
. You want to get good errors if your type preconditions are violated. - Use Composer. It makes dependency management much easier.
- 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 therequire_once
boilerplate. - Use PHP CodeSniffer to
enforce a uniform style. I recommend
phpcs --standard=PSR12
, but which standard you use is less important than having one. - Use PHPStan to find bugs before you
even run your code. Run
phpstan analyze
at the highest-l
level you can. - Write unit tests in PHPUnit. No library file should be without unit tests. Having tests lets you code without fear of breaking something.
- If you're writing a webapp, write integration tests with Selenium.
- If you're writing a service, write integration tests for that, too.
- 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:
- 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.
- Don't let users put their HTML in your page, or bad things will happen to you. If you must, use HTML Purifier.
- Don't construct SQL manually. Use parameterized queries, or bad things will happen to you.
- 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.