Why the PHP Conventions

If you want to understand the reasoning behind the recommended conventions, read on. Otherwise, you can just skip this and follow the conventions

Style

Modern programming languages generally share common notational or semantic constructs. (Wikipedia has interesting articles on the evolution of programming languages.) There is broad practical experience with the items in the style guide. While not the subject of objective testing, experience suggests certain coding styles are better for reading and comprehension.

I’m comfortable with the more dense coding style typically practiced for C. I have long experience coding in Java, C++, C and other languages all the way back to Fortran. But to improve readability, I made minor adjustments to my coding style primarily related to adding more whitespace (spaces and newlines). The ultimate goal of any style guide is for the ability for others to easy grasp your code. So I changed. Not for my benefit but for others that might read my code.

The style guides in PSR-1 and PSR-2 are purely subjective but helpful in getting a team to all use the same coding style. And once set up, some developer tools will even coach you to follow the style guides.

Structural

WordPress was created when PHP was a purely procedural language. So most of its actual conventions relate to doing procedural programming. I feel there are advantages to using PHP’s modern object-oriented language extensions. These extensions are mainly useful in regards to name scoping and conflicts. A name conflict happens when the same name is used to refer to different things. These can be different functions, variables or constants. This conflict usually happens because the different developers (such as for different plugins) don’t know of each other.

There is theoretical debate on the merits of object-oriented programming as opposed to functional programming (see Object-Oriented Criticism). Object-oriented (or OO) thinking is just a tool. Sometimes appropriate; sometimes not. And any tool can be misused. I find OO thinking helps me when I return to a piece of code after a period of time. It also helps force a separation of concerns architecture.

Before modern PHP that introduced namespaces, each developer was responsible for picking their own unique names. The convention developed of adding a few characters followed by a ‘_’ to the front of each name to make names unique. And the PHP Extension and Application Repository (PEAR) system took advantage of that convention to manage packages–collection of related code.

Modern PHP introduced namespace and use statements that changed the way unique names are formed. Subdequently the use of PEAR has given way to using a more modern tool Composer.

WordPress core code adopted the convention of prepending the word “class-”  to the file name.

 

Versioning

Something akin to the recommended conventions has been used by many for many years. For example, WordPress 3 is very different from WordPress 4 which is very different from WordPress 5. But to create an automatic tool, you need the precision of a formal specification and not rely on human interpretation. The convention provides the necessary precision while still allowing some flexibility.

Loading

Every large system has to solve the problem of automatic loading of code. Manual procedures don’t scale well and are very error-prone. Drawing inspiration from other language tools, Composer is a tool for dependency management that will also create efficient autoloaders.

PHP/WordPress Conventions

While you can always do things your own way, make your life much easier by following some basic conventions related to modern PHP coding. The larger PHP community, not just the WordPress community, developed these conventions. If you plan to release your PHP code through the WordPress.org repository, follow the conventions. This should help you breeze through code review.

The minimum version of PHP for WordPress is currently 5.6.20. If possible use a version 7 PHP (such as version 7.2.2) which is vastly improved and is much faster. Though the main WordPress code does not use modern PHP features, you can use them without worry. I’ve summarized the recommended conventions below. If you care, read more details about the “why”.

Styling

Write your PHP code using the style conventions of PSR-1 and PSR-2. Much of WordPress predates these coding standards so unfortunately don’t look at the WordPress code to see what you should be doing! Most of the style guides (especially PSR-2) relates to others reading your code. Ignore them and your peers, code reviewers and some development tools may complain.

But it is most important to be stylistically consistent across related code such as that produced by a team. WordPress continues to use obsolete style conventions to maintain consistency across its evolving code base. (In fact WordPress is very conservative in not advancing with newer technologies in part because of its huge installed base.)

So if you are adding code to WordPress, adopt its style and conventions. If you are starting new development, adopt these conventions.

Structuring

For new work, write class names in StudlyCaps (per PSR-1) and not with the ‘_’ or ‘-‘ seen all over WordPress. The ‘_’ worked well for now obsolete versions of PHP and with a now essentially obsolete PEAR (PHP Extension and Application Repository) system. Align the file names with the class names to allow autoloading to work. Note the file name must match the case of the class name. (Ignore the fact your file system may be case-insensitive.) This alignment generally means one class definition per file. This convention also makes it easier when editing to find the file that contains a given class. The WordPress convention of prepending class- for the file name of PHP class definitions is obsolete but still used extensively in core.

Use namespaces to avoid name conflicts as opposed to adding some unique characters to the class name. For example, WordPress code uses WP_ or wp_ to make its names unique.  This is not necessary with namespaces. Don’t forget the use statement to shorthand refer to the classes in that namespace. So rather than defining a class as class XYZ_MyClass (the old way), use namespace XYZ; class MyClass when defining and add use XYZ; in files that references MyClass. Or you could use the qualified name XYZ\MyClass if you prefer being verbose. And put all the files related to namespace XYZ in a folder namedXYZ.

These structural conventions may be the most important to follow when starting a new project because of the extensive changes needed if adopting them at a later time,

Versioning

Use the Semantic Versioning convention of X.Y.Z where X is the major version, Y is the minor version and Z is the patch number (e.g., bug fix release with no API change). If there is an API change not backwards compatible, increment X. If there is a significant API change that is backwards compatible (such as deprecating or add new), increment Y. This convention allows tools to automatically resolve dependencies. I append build metadata in an easily readable date/time form using a “+” following the patch number. (I use the common  YYYYMMDDHHMM format) This convention allows me to easily track builds rather than relying on memory.

Bootstrapping

For small projects, the easiest way to load code is to write a list of include or require statements in a bootstrap.php file. For bigger projects, follow the structural recommendations above to work with common PHP autoloaders.  (You need to pick one since WordPress doesn’t provide one.) These autoloaders automatically load your PHP classes from files. Or rather, when class MyClass is not known to PHP, it does a require of the file MyClass.php.

The most modern approach for automatic loading for large projects is to use Composer. Once set up, Composer will automatically resolve dependencies and create an efficient autoloader. However, Composer is an advanced topic not covered further.

Extending

You should plan up-front to allow others to extend your functionality. Being based on a procedural language, WordPress has defined a way of extending its functionality based on callback functions termed hooks. At many places, the WordPress code makes function calls to different hooks. Hooks come in 2 types–actions and filters. An action does something while a filter takes an input and returns a result. When registering a hook, the first argument is the name of the hook (as a string) and the second is the name of the callback routine (as a string).

For example, your code can add an action to the init hook.

add_action( 'init', 'mycode_init');

This hook is called after WordPress has finished loading but before any response is sent. Or your code can add a filter to the the_title hook to change the title of a post before it is displayed to the user.

add_filter( 'the_title', 'wporg_filter_title');

For best performance, you want to use the most specific hook you can find for the functionality you need to change. This helps improve compatibility and avoid conflicts. For example, the init hook is called for each page load. Find a more specific hook that is only called for your use case. So rather than using the init hook, you should use the wp_enqueue_scripts hook to load scripts and styles.

The WordPress-defined hooks are described in the Developer Documentation. Since WordPress is open-source, you can also look at the code if you can read PHP.

You should define your own hooks for places where you think others may want to change functionality. And document your hooks.

This is just a brief overview of hooks. If you plan to create or use hooks refer to the WordPress Documentation.