Using PHP Traits in WordPress development
This article is going to discuss, in fairly high level terms, PHP Traits and how you can use them to help your wordpress development.
As someone who started using PHP in about 2005 when version 4 was just being introduced, I think of Traits as being a very new addition to the language. When I started researching this article however I found they were actually introduced in Version 5.4!
The idea of a Trait is to create a portion of code which can be easily used in multiple places within a project. Just to illustrate the point I’ll explain how I recently needed to use a Trait and although it is not related to WordPress development it does explain their use.
I was developing a system which produces data to be fed into an AWS Sagemaker Machine learning system for a recommendation engine (yes I know that PHP is not the best language for that application but it is what I needed to use). Since the application was processing huge amounts of data I used caching wherever possible to speed up the process and limit the number of database calls I needed to make. One part of the process involved running some pre-cache statements before starting up a symfony service.
I had the pre-caching running well but I then needed to add a different data type to the recommendations and needed to use the pre-cache in another Symfony service. Normally, in this situation, I would pull the code responsible for that down into a base class and make sure both services derived from that class. Unfortunately, in this case it wasn’t easy to do that and PHP only allows single inheritance – you can’t inherit from multiple classes – so that option wasn’t available.
This is where the PHP Trait came in. By moving the code which did the pre-caching to a separate file and wrapping it in a Trait, I could use the functionality in both the original service and the new service without duplicating the code.
Using PHP Traits in WordPress
The interesting thing I worked out when using traits in the way described above is that any resources used by the function you define in the trait are best injected into the function.
For example, in the trait I just described I needed to run some SQL commands against a mysql instance and cache some data into a redis cache. So I needed to use a connection to the database and the redis instance itself. There are two way to do this
- Make sure that the code which is going to call the trait method has these resources available with the correct variable names etc
- Pass the parameters into the function
Obviously the second method is much more portable than the first.
But the other huge advantage of the second method is that it allows you to much more easily run unit tests against your code. I find WordPress notoriously difficult to write unit tests for because the database functions are embedded into so much code which means it would be both really easy to delete data you want to keep and also really difficult to mock the database connection.
If code you write for your plugins is partitioned into Traits it is relatively easy to add a unit test framework to them which injects in a test database instance making it safe to run.
The next part in this series will show a concrete example of using a Trait in a wordpress plugin.