A WordPress local setup that catches mistakes before review does: LocalWP for the site, MailHog so test mail never reaches a real inbox, PHPCS and PHPCBF for the coding standards, and the handful of editor extensions that actually earn their place. This is the toolchain, the install commands, and the standards worth memorising.
Run phpcbf first, then phpcs; what remains is the short human list.
The site and the editor
LocalWP spins up a WordPress site in a few clicks, which is the whole reason to use it.
The editor extensions that matter for PHP work:
- PHP Intelephense -> completion and go-to-definition
- phpcs -> standards violations inline, as you type
- phpcbf -> fixes them
- PHP DocBlocker -> generates the docblock skeleton
- PHP Debug -> step debugging
Deliberately not the WordPress-specific extensions on day one. Core PHP first, then the framework on top of it. ๐งฑ
MailHog, so nothing escapes
MailHog starts two servers, an SMTP listener and a web panel. It accepts mail and shows it in the panel instead of delivering it.
SMTP : 1025
HTTP : 8025For mail sent through PHP’s own mail() rather than SMTP, install mhsendmail and point php.ini at it:
sendmail_path = "/path/to/go/bin/mhsendmail"Now a plugin that fires 400 password resets during a migration test fires them at you. ๐
PHPCS
PHPCS reports violations of a defined coding standard. On WordPress VIP it ships with the repo already configured. Everywhere else, install it globally through Composer:
composer global require "squizlabs/php_codesniffer=*"One file:
phpcs <filename>Everything under the current directory:
phpcs .PHPCBF
PHP Code Beautifier and Fixer, the other half of the same tool. It repairs every violation it knows how to repair:
phpcbf <filename>
phpcbf .Run phpcbf first, then phpcs, and what is left is the list of things that need a human. That is usually a much shorter list than the first run suggests. ๐งน
Mail sent through PHP's mail() needs mhsendmail set as sendmail_path in php.ini.
The standards worth memorising
The rules that come up in review over and over:
- opening and closing PHP tags go on lines of their own
- no short tags, so no
<? ?> - single quotes unless the string is interpolating something
- lowercase for variables, functions, actions and filters. No camelCase
- class files are named
class-{class_name}.php - braces always, even where the language does not need them. No inline control structures
- long array syntax,
array() - spaces inside parentheses, because it makes the logic readable:
function( $param1, $param2 );
if ( ! empty( $string ) ) {
}- validate and sanitise everything. Never trust input
That last one is not a formatting rule sitting in a formatting list by accident. It is the only one where getting it wrong is a security bug rather than a review comment. ๐
Git, and the merge conflict
The commands that cover most days:
git init-> start a repositorygit config-> setuser.nameanduser.emailgit branch <name>-> create a branchgit checkout <branch>-> switch to itgit clone-> copy a remote repositorygit add .-> stage everythinggit commit -m "message"-> commit the staged changesgit diff-> what is not staged yetgit status-> what is going to be committedgit log-> history of the current branchgit push <remote> <branch>-> send it upgit pull-> fetch and merge
A merge conflict happens when two branches change the same line, or when one deletes a file the other edited. Git will not guess which side wins, so it stops and asks:
git log --mergeThat prints a log limited to the commits involved in the conflict, which is a faster way in than reading the file and hoping. ๐
The fork and pull request flow
- fork the official repository, which gives you a server-side copy
- clone your copy locally
- add a remote pointing at the official repository
- branch, change, commit
- push the branch to your own copy
- open a pull request from that branch against the official repository
- it gets reviewed, approved and merged
GitHub Actions
Workflows are event driven, defined in .yml under the repository:
name: GitHub Actions Demo
on: [push]
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
- run: ls ${{ github.workspace }}on-> the event that triggers the runname-> what the workflow is calledjobs-> the units of workruns-on-> the runner platformsteps-> executed in order
The obvious first workflow is the one that runs phpcs on every push, so the standards above stop being something anyone has to remember. wp scaffold plugin-tests will even write you a CI config to start from. ๐ค
What this does not cover
Xdebug configuration, wp-env and Docker-based setups, and the WordPress-specific PHPCS ruleset, which is a separate install from the standard above and is the one you actually want on a WordPress project. ๐ง
