Upping PHP Requirements in Your WordPress Themes and Plugins

There has been talk for a while now about the PHP requirements of WordPress. WordPress still supports PHP 5.2.4, however, PHP 5.2 was deprecated on January 6, 2011, over 4 years ago as of the time of this writing. PHP 5.3 was deprecated August 14, 2014. Why is WordPress continuing to support such antiquated versions of PHP?

The main reason is backwards compatibility, and the millions of sites that rely on WordPress. The statistics of WordPress as of this writing, show that 16% of WordPress sites are still using PHP 5.2, another 38% are on PHP 5.3. Knowing that over 54% of WordPress installations are on deprecated PHP versions should depress you a little.

So what’s a web developer to do? There has been some hope, as WordPress now suggests a minimum of PHP 5.4 in it’s requirements. Matt Mullenwag on his State of the Word 2014 talk mentions at ~24:20 that they would be working with hosting companies to get their versions of PHP updated to at least PHP 5.5

However, we feel that we can help as well. If we as developers, going forward, only support current versions of PHP, this could very well help in the push to get hosts and their users off of deprecated versions of PHP, and onto faster, more secure hosting. In this article, we’ll show you some cool things you can do with PHP if you have been supporting PHP 5.2 to go along with minimum WordPress requirements.

Short Array Syntax

This is a feature that was introduced in PHP 5.4. It’s a simple update, but one that I personally really enjoy. Instead of using array(), you can use brackets. In the WordPress context, this can save you some space, so for instance, a WP_Query might look like this:

$new_query = new WP_Query(array(
  'post_type'      => 'movies',
  'posts_per_page' => 5,
  'tax_query'      => array(
    array(
      'taxonomy' => 'genres',
      'field'    => 'slug',
      'terms'    => 'action'
    )
  )
));

The short array syntax makes looks like this:

$new_query = new WP_Query([
  'post_type'      => 'movies',
  'posts_per_page' => 5,
  'tax_query'      => [
    [
      'taxonomy' => 'genres',
      'field'    => 'slug',
      'terms'    => 'action'
    ]
  ]
]);

If you’re familiar with JavaScript, it uses the same array syntax. I find this especially beneficial if the array is short enough to be on one line, it looks even cleaner when only using brackets rather than the entire array word.


Anonymous Functions

As of PHP 5.3, we have access to anonymous functions. An anonymous function is simply a function without a name. We always create functions with names:

function my_cool_function() { }

However, in PHP we don’t necessarily need a name on a function:

function() { }

Why would we need this? There are many instances when working with WordPress where we use a function exactly in one place. Passing these function names to hooks and filters. Normally that looks like this:

function custom_excerpt_length() {
  return 20;
}
add_filter('excerpt_length', 'custom_excerpt_length');

However, this is the one and only place we will be using custom_excerpt_length. So…. why even give it a name? Here’s what it looks like when we pass an anonymous function:

add_filter('excerpt_length', function() {
  return 20;
});

Keep in mind that if you expect to be using a function in more than one place, then you should definitely add a name to it so it can be called. Or another option is to assign a function to a variable, which you may be familiar with if you’ve written JavaScript.

$length = function() {
  return 20;
};
add_filter('excerpt_length', $length);

Short Echo Syntax

As of PHP 5.4.0, short echo syntax is permanently enabled, while previously short_open_tag had to be enabled within the PHP configuration.

Short echo syntax is simple. Normally we echo this way:

<?php $categories = get_categories(); ?>
...
<?php foreach ($categories as $category) : ?>
    <?php echo $category->name; ?>
<?php endforeach; ?>

With the short echo syntax, this can be shortened:

<?php $categories = get_categories(); ?>
...
<?php foreach ($categories as $category) : ?>
    <?= $category->name; ?>
<?php endforeach; ?>

Simple.


Namespaces

For many WordPress developers, namespaces may be a foreign idea, since they are nonexistant in WordPress core and most plugins/themes. Namespaces were introduced in PHP 5.3.

What are namespaces?

You can think of namespaces in the same way you think of sorting files on your computer into folders. You cannot save a file with the exact same name in the same folder. You can, however, save a file with the same name into a different folder.

You may have noticed that we face a similar issue when working with functions and classes in PHP. Have you ever named your function something generic, only to have your site load with a "Cannot redeclare function" error? We try to avoid that by adding an extra word onto our function names.

In order to avoid this naming collision, it has been common practice to prefix every function with a unique name. This is a form of namespacing. For instance, if your theme was named "Branch", you would probably prepend all your functions with that name. title() would be branch_title() in your theme.

Namespaces and WordPress

In PHP 5.3, true namespacing is available. This allows us to add the keyword namespace to a PHP file, placing all functions or classes declared within that file into that namespace. Following the previous example, this means that we can now have a function simply named title(), but keep it within a namespace. The function would then look something like this:

<?php

namespace Branch\Titles;

function title() {
  if (is_archive()) {
    return get_the_archive_title();
  } else {
    return get_the_title();
  }
}

How to use namespaced functions and classes

You may notice that if you simply try to call <?= title(); ?> you’ll receive a Call to undefined function title() fatal error. This is because we now need to use the full namespace. In order to use the title() function, you will need to use it this way: <?= Branch\Titles\title(); ?>

Benefits

Namespacing is simply another way to keep your functions and classes organized and free of naming collisions. You will also notice if you have ventured outside of WordPress land, that object-oriented frameworks make huge use of namespaces, not just for organization, but also for autoloading.

Gotchas

I know, you are probably thinking, "wtf dude, Branch\Titles\title() is SO much longer than branch_title(), this new way makes it so much more difficult." We hear ya, but thankfully there is a way to handle that, so that you don’t need to call a function or class by it’s full namespace every time you use it.

There is a new keyword that goes along with namespaces, called use. This keyword allows us to tell PHP to look into a namespace for each function call before throwing that fatal error if the function is not found. For example, if you wanted to use this title function in a page template, you could shorten the actual call by adding the use keyword to the beginning of the file:

<?php

use Branch\Titles;

...

<?= Titles\title(); ?>

If you are using a function or class in a hook or filter, it’s also relatively easy to make sure WordPress uses the correct namespace. Since you will most likely be using add_filter() or add_hook() in the same file as the function you are creating, you can simply pass the __NAMESPACE__ constant:

<?php

namespace Branch\Titles;

function title() {
  if (is_archive()) {
    return get_the_archive_title();
  } else {
    return get_the_title();
  }
}
add_filter('the_title', __NAMESPACE__ . '\\title');

Notice the double backslashes in the string of the function name. This is required as we are passing the full namespaced function name, and we need to escape the backslash.

Also you should keep in mind that when you have a namespace in a file, any classes will then be expected to be in that same namespace. That means if, for instance, you wanted to use WP_Query() in a namespaced function or class, you would need to make sure you are using the top level namespace and not the current namespace, IE:

<?php

namespace Branch\Titles;

...

$query = new WP_Query();

This will not work, because PHP will expect there to be a Branch\Titles\WP_Query class.

To get around this, again we can use the use keyword at the top, like so:

<?php

namespace Branch\Titles;

use WP_Query;

...

$query = new WP_Query();

Or, we can also give the full namespaced class, in this case, it would just be adding a backslash to WP_Query(), since it is in the global namespace:

<?php

namespace Branch\Titles;

...

$query = new \WP_Query();

This becomes more important as your theme or plugin grows, you may have multiple namespaces, depending on how you would like your functions and classes sorted.

Using namespaces in this way also allows us to avoid large function names like branch_header_background_color_css_option().


Pushing WordPress Forward

As developers, we want WordPress to continue to evolve, grow, and mature. Do your part in helping the process along. Supporting antiquated and insecure PHP versions shouldn’t be a goal of developers. Let’s up our PHP requirements to versions that are still supported.

Read the discussion on our Discourse

Get our latest updates & occasional tips on building better WordPress sites

Follow @rootswp on Twitter