Using Modern PHP with WordPress: Part 3 – Composer

In this ongoing series, I am providing insight into how I built the Photogramappy plugin in WordPress using modern PHP approaches, standards, and techniques. In my last article, we looked at dependency injection and containers as a way to decouple classes and logic from each other.

In this article, I’d like to dive a bit into Composer, and how it brings package management to the project. The simplest way to explain it, is that it’s a list of PHP libraries needed for the project. This is done in a JSON file named composer.json.

You can see mine here.

In modern PHP, a library should contain it’s own composer.json it should have a “type” defined. In my case, I call it “wordpress-plugin”. In my main WordPress project, I have a different composer.json file that defines how WordPress is setup, what plugins should be installed, etc. Any plugins with type “wordpress-plugin” will be installed in my plugins directory, thanks to the composer/installers library.

So if the Photogramappy “library” is installed in my main project (it is), then composer will put it in the plugins directory where it should be. Easy, but a little out of scope for this piece. You might want to check out the excellent write-up on Composer-driven WordPress at

There are two areas of my plugin’s composer.json to highlight that really make this work. My plugin relies on a package called PHP-DI, which I discussed in the last article. It provides the mean to containerize classes, as demonstrated.

Another library I heavily depend on is Metabox Orchestra. I will discuss how I use it in my next article.

Finally, this project includes tests as well, but tests are not needed for the plugin to work. They are only needed in development to ensure the plugin actually works.

"require": {
    "php": ">=7.2",
    "php-di/php-di": "^6.0",
    "inpsyde/metabox-orchestra": "^0.4.1"
  "require-dev": {
    "wp-cli/wp-cli": "^1.5.1",
    "lucatume/function-mocker": "~1.0",
    "phpunit/phpunit": "^6",
    "php-http/httplug": "^1.1",
    "codeception/codeception": "^2.5",
    "vlucas/phpdotenv": "^2.5",
    "lucatume/wp-browser": "^2.2."

The “require” block is where libraries and requirements that allow the plugin to work are defined. Here we see that this plugin must use at least PHP 7.2, the php-di/php-di library and the inpsyde/metabox-orchestra library.

The “require-dev” block is not for libraries that would make the plugin work, but it is for libraries needed in development. While wp-cli/wp-cli is not required for development, I usually include it in my projects anyway because it’s handy to have for IDE autocompletion. The rest of the libraries here are a standard set of libraries needed for running tests.

By using Composer to manage dependencies, it makes it possible to ship a “lean” product without having to version control stuff that is version controlled elsewhere.

In the next article, I’ll discuss usage of the Metabox Orchestra library to quickly scaffold metaboxes in an Object-Oriented way.

  • Category: PHP