Advertisement
Plugins

Two Ways to Develop WordPress Plugins: Functional Programming

by

This part two of a series looking at two different programming styles (sometimes called programming paradigms) that you can use when writing WordPress plug-ins. In part one Tom McFarlin covered object-oriented programming. In this part we'll be looking at functional programming.

Because the experience level of readers varies, we’re going to be talking about programming at a high-level, so if you’re a beginner, then you should have no problem following along. If, however, you’re a more experienced developer, then you may find more useful information later in the article.


What Is Functional Programming?

Functional programming is probably the style with which you are most familiar - and almost universally - is the style used in the various WordPress code snippet websites floating around the internet. For this reason it can sometimes be viewed as 'entry level' programming: the style employed by beginners until they've learnt to master object-oriented programming. This is incredibly misleading, because while functional programming is much simpler, it is not in itself inferior.

Functional programming emphasises the evaluation of functions, and avoids the notion of states or objects as opposed to object-oriented programming which encourages thinking about code as acting on object(s), using methods to change those objects, or interact with them. Let's look at a very simple example comparing the two styles:

	// Functional method
	function add_two( $n ) {
		return $n +2;
	}

	$a = 2;
	$b = add_two( $a ); // $b = 4;


	// Object oriented method
	class Number {
		var $value = 0;

		function __construct( $a ) {
			$this->value = $a;
		}

		function add_two() {
			$this->value = $this->value +2;
		}
	}

	$a = new Number( 2 );
	echo $a->value; //Prints 2
	$a->add_two();
	echo $a->value; //Prints 4

This very simple example illustrates the fundamental difference in style of the two paradigms: functional programming focuses on passing arguments to, and receiving values from functions. There are no 'objects' that are being acted on, only parameters and return values. Conversely, the object-oriented approach assigns an object various properties (in our case a 'value') and methods act on those properties.


Functions: The Basics

Defining functions is very simple:

	function add( $number, $number2 = 1 ) {
		// Perform code acting on passed variables
		$sum = $number + $number2;

		// Optional, if needed you can return a value
		return $sum;
	}

Once the function is declared it can be used anywhere in your plug-in - in other words it has global scope.

	$a = 4;
	$b = 7;
	echo add( $a, $b ); // Prints 11
Functions must have unique names. Redeclaring a function will throw an error. Since your code will be running alongside other plug-ins, themes and WordPress itself you should never use generic names. Instead you should prefix your function names with something unique (like the name of your plug-in).

You may have noticed that in the definition of add, the second argument is set equal to 1. This sets a default value for $number2 (in this case, 1), and by doing so makes the argument optional. If the argument is not supplied, the value is taken to be the default value:

	echo add( 4 ); // Prints 5
	echo add( 4, 1 ); // Prints 5

On the other hand, no default value is provided for the first value, so omitting that argument will throw an error

	echo add(); // Throws an error as $number is not defined

You can also have a variable number of arguments. Inside the function we can use func_num_args() to get the number of arguments received, while func_get_arg() allows you access a particular passed variable, indexed from 0.

function sum() {
	// Get the number of arguments given to sum()
	$number_args = func_num_args();

	$sum = 0;

	if ( ! $number_args )
		return $sum;

	for ( $i = 0; $i < $number_args; $i++ ) {
		$sum += func_get_arg( $i );
	}

	return $sum;
}

echo sum( 1, 2,  3, 4 ); //Prints 10
echo sum( 1, 2 ); //Prints 3
echo sum(); //Prints 0

The above can be used in object methods too. Finally, by declaring a variable as `global` you can access the variable from inside a function.

	$a = 'Hello';
	$b = 'World';
	function hello_world() {
		// This is necessary to access $a and $b 
		// declared outside of the function scope.
		global $a, $b;
		$b = $a . ' ' . $b;
	}
	hello_world();
	echo $b; // Prints 'Hello World'
Using globals is generally discouraged. Particularly since two plug-ins using the same name for a global variable can cause either one or both plug-ins to break. If you must use a global variable, again ensure it's unique by prefixing with your plug-in's name.

Why Use Functional Programming?

Deciding which programming style to use comes down to judgement - and yes - personal preference. It is not more right or wrong to use functional over object-oriented programming, but more often than not there is one style which is better suited for what you're trying to achieve.

Sometimes object oriented programming simply isn't necessary, and only over complicates matters, or introduces superfluous code. An example might be the various 'utility' functions WordPress provides. These are generic functions which serve to perform a particular purpose. For example wp_trim_words( $text, $num_words ) simply trims the given string to a certain size (in words). It wouldn't add anything to define wp_trim_words() instead as a method belonging to some object, and would result in uglier code. With functional programming it takes one line.

One advantage of functional programming, particularly for beginners, is its simplicity. You do not have to worry about static, private or protected functions - they are all global. Neither does the notion of static variables exist. At the very basic level your function returns an output derived from what you've given it. For example, get_the_title( 7 ) will return the title for the post with ID 7.

Another advantage of functional programming is that functions are accessible globally. With object-oriented programs, in order to act on a specific object, you need to pass around that object. This can sometimes be tricky. To illustrate this let's take an example from part one:

class DemoPlugin {
	public function __construct() {
		add_action( 'wp_enqueue_scripts', array( $this, 'register_plugin_scripts' ) );
	}

	public function register_plugin_scripts() {
		// Register plugin scripts
	}
}
$demo_plugin = new DemoPlugin();

When WordPress stores the register_plugin_scripts() method so that it can be called when the wp_enqueue_scripts action is triggered it does so by referencing not only the method, but also the object $demo_plugin. This is because the same method for different instances of an object are considered different methods - that is, $demo_plugin->register_plugin_scripts() and $copy_of_demo_plugin->register_plugin_scripts() are not the same. This may seem odd - but methods can behave differently for different instances of the same class, so we need to reference both method and instance.

But why does this matter? It makes it very difficult for a third party plug-in or theme to unhook that method, since to do so they would need to call:

	remove_action( 'wp_enqueue_scripts', array( $demo_plugin, 'register_plugin_scripts' ) );

But in general they won't have access to the $demo_plugin variable. (Note: if the method is declared static, then you can get around this).


Object-Oriented and Functional Programming in WordPress

Of course object-oriented programming has its advantages, as discussed in part one. As Tom also mentioned, it is unavoidable when using WordPress' widget API. Another common example is WP_Query(). Here an object oriented approach is clearly the best: you have an object (in this case a query), which has various properties (i.e. search criteria, pagination information, matching results) and you want to act on that query (parse it, generate and sanitise the corresponding SQL, and return the results).

WP_Query() demonstrates how powerful object-oriented programming can be when used correctly. After initiating the query:

$the_query = new WP_Query( array(...) );

Not only can you access the results, but other information too such as, pagination values: how many pages of results there are, which page is being viewed, the total number of results, and the 'type' of query, e.g. $the_query->is_search(), $the_query->is_single() etc. There is also the entire 'loop' infrastructure;

	if ( $the_query->have_posts() ) {
		echo '<ul>';
		while( $the_query->have_posts() ): $the_query->the_post();
			// The Loop
			echo '<li>' . get_the_title( $the_post->ID ) . '</li>';
		endwhile;
		echo '</ul>';
	}
	wp_reset_postdata();

Which hides all the internal juggling of results and globals behind a human-friendly API.

So what about get_posts()? This just serves as a wrapper for WP_Query(), and simply returns an array of posts matching the query. As such, you don't get the 'bells and whistles' of WP_Query(), but it is slightly more efficient. So whether you should use get_posts() or WP_Query() depends on your use case (for example, whether you require pagination or not), but it's also down to personal preference.

	$results = get_posts( array( ... ) );

	if ( $results ) {
		echo '<ul>';
		foreach( $results as $the_post ) {
			echo '<li>' . get_the_title( $the_post->ID ) . '</li>';
		}
		echo '</ul>';
	}

Summary

Hopefully these two articles have helped highlight the advantages and disadvantages of these programming styles. The take away point is that there is no right and wrong here, and each programmer will have their own personal preference. But some contexts lend themselves more readily to a certain programming style - and as such you should expect your plug-in to contain a mixture of both.

Related Posts
  • Code
    Theme Development
    Custom Controls in the Theme CustomizerTheme customizer custom control 400
    In the last article, we explored the advanced controls available in the Theme Customizer, and how to implement them. We’re going to look at how to create our own custom control, allowing you to choose which Category of Posts are displayed on the home page. To get started, download version 0.6.0 of our Theme Customizer Example.Read More…
  • Code
    WordPress
    Mastering WordPress Meta Data: Querying Posts and Users by Meta DataMetadata
    So far in this series you've learned how to access WordPress meta data, and work with the arrays in which they are returned. We don't just add custom fields to WordPress posts so we can display this information, but it also so we can sort by it. Now that you know how to retrieve and display meta data, it's time to learn how to customize the WordPress loop to return only posts with specific meta values.Read More…
  • Code
    Creative Coding
    Using WordPress for Web Application Development: Features: Custom Queries with WP_QueryApplication foundation 400
    We've been looking at how WordPress can be used as a foundation for application development, but one of the things that we've yet to cover that most modern frameworks offer is how to query the database to retrieve results for any given view. Specifically, we haven't talked about how to get information out of the database and insert it into our pages.Read More…
  • Code
    WordPress
    Mastering WordPress Meta Data: An Introduction To Meta DataMetadata
    Part of what makes WordPress a powerful CMS tool is the ability to use the wp_postmeta table to store custom fields. These custom fields may contain additional information such as SEO fields added by an SEO plugin, or may be used to display additional front-end content. By adding this additional information to fields you can create custom queries to organize the display of your content by.Read More…
  • Code
    Mobile Development
    C++ Succinctly: Resources Acquisition Is InitializationPreview image@2x
    This article is all about RAII or Resource Acquisition Is Initialization, a design pattern using C++ code to eliminate resource leaks.Read More…
  • Code
    Plugins
    Using HighCharts in WP-AdminHighcharts 400
    Charts are a great way to present data. They make data more digestible by making it visually appealing. In WordPress, there is no built-in method for getting posts and pages data in a graphical form. Although, there are certain plugins available which integrate Google Analytics with WordPress, but they are overkill if you want to get only a portion of that data. Also, nothing should keep you from learning new techniques and to dive straight into the subject is the best way to learn.Read More…