Dealing with spaghetti code in PHP: Using anonymous functions to extract pieces of template code

Recently I’ve been helping out a friend with trying to make sense of some code and how to modify it to work well with asynchronous calls to the backend. A bonus would be to be able to write it in a more modular and reusable way.

The code is a WordPress plugin that was written with very legacy approach – mix of business and frontend logic in one place. Data manipulations done in the middle of template code and such.

Basically what you’ve seen in PHP sites back in the early 2000s before all the awesome OOP additions to the language and bunch of mature frameworks.

The case I was chipping away on today was the following – you have a table that shows bunch of entries. We needed to add several filters to the table and make it work via AJAX to quickly refresh the UI, without reloading the whole WordPress Admin page.

Filtering the data was easy – a quick inline array_filter to filter the data before it was passed down to the template code (to keep the same code style this was also in the template file šŸ˜‡).

The problem came when we started working on making the table renderable over AJAX.

It’s in the middle of a bunch of other template and business code. If we wanted to limit the output via AJAX only to the table we had only a few ways to achieve that.

The first way would be to wrap the HTML before and after the table in HUGE if statements to make sure it’s not rendered.

Another way would be to extract the template in a separate file and to include it in the AJAX action that we would define in plugin’s code.

Anonymous functions to the rescue!

Thinking of how to deal with this in the easiest possible way, I tried defining a normal PHP function that would contain the table code, but there was a problem.

The code runs contained in a class method. There are references to $this in the table template. If we don’t want to change the code too much, we would want to pass $this as a function argument. Well that doesn’t quite work as you can’t pass $this as parameter šŸ¤·ā€ā™‚ļø.

I was a bit disappointed that we’ll have to rewrite bunch of stuff in the template and there were quite a few references that we wanted to be aware of, so it keeps working.

Then I remembered that the site doesn’t run on PHP5.2, but PHP7 and anonymous functions would be supported.

And they have the nifty feature where you can define what variables from the calling scope will be passed down to the function when it’s called. For example:

$table_function = function() use ( $pages, $current_page, $items ) {
    // ... Table render code

This will allow you to directly reference $pages or $items in the function body.

The awesome feature here is that you can also pass $this as a variable in the function scope!

Now we were able to fully extract the table rendering code in a separate function that we can call in isolation during the AJAX call!

Of course one must be very careful about the variables used inside the function body as they have to be defined, so be careful where the AJAX function can be called.

For us, this would mean that we will add a tiny action in the main class that would still require the file, but we’ll have more control on disabling all the other outputs that will happen.

By Biser Perchinkov

Look, a coder!

One reply on “Dealing with spaghetti code in PHP: Using anonymous functions to extract pieces of template code”

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s