PHP __set() Magic Method Conundrum

I am completely baffled by this one and hope one of my techie friends can help.

I’m using a PHP class with magic methods to set and get the properties of that class.    The idea is to use private properties in the class so that the PHP magic methods can take over and determine whether to update a WordPress user meta entry, blog entry, or standard option based on which proper of the class is being retrieved or stored.

Read More

Improving wp_delete_post in WordPress Core

One of the common processes that runs in Store Locator Plus is deleting locations.    For sites with a few dozen locations the process runs smoothly.  For sites with thousands of locations but deleting one or two at a time, not a big deal.   But for sites that are deleting tens-of-thousands of locations at a time the process becomes painfully slow.   A mere 2,500 locations can take up to a full minute to be removed on a fairly decent performance server.   That’s not the type of performance I like to see from our product.

After digging into the performance of the PHP stack initial indicators point to the custom post types as the primary culprit.   It turns out that deleting a single custom post type in the WP_Posts table runs through a dozen gyrations to delete the post.  Multiple filters are called, associated taxonomies are delete, taxonomy meta is deleted.  It is a TON of extra overhead.    But even with removing records from a half-dozen tables the data queries seem out-of-control.

Removing just 9 locations generates over 190 data queries.     If there is one thing that has not changed in decades of writing software it is that data queries are costly.  They may run on solid-state drives with advanced memory caching but doing 190 data queries is still far slower than nearly any other part of the application.
Read More

Should The WordPress PHP Version Be Updated?

WordPress LOVES backwards compatibility as can be witnessed by the minimum-allowed WordPress PHP version remaining at 5.2.4 a decade after its end-of-life date.  It  may be  one of the reasons they have continued to garner market share.  Don’t require people to do anything to improve their site and they’ll wallow in complacency.  It makes sense.  Inertia is a big thing to overcome.  If you are a business focused on writing content, selling widgets, or doing just about anything else other than managing websites, upgrading software is way at the bottom of the priority list.

This backwards compatibility is one of the reasons why WordPress continues to RECOMMEND PHP 7 for performance and security reasons but allows the minimum WordPress PHP version to remain 5.2.4 without breaking the core application.    It is the reason why so many plugins, including Store Locator Plus, continue to do some convoluted things to reach that PHP 5.2 audience and keep their potential market as big as possible.
Read More

wp_enqueue_scripts Deep Dive

While trying to figure out why the footer-loaded scripts in Store Locator Plus are not being output on some admin page, I went deep down the rabbit hole of the WordPress wp_enqueue_scripts function.   Here are my notes from an analysis of WordPress (5.0-alpha-42191) .

wp_enqueue_scripts

/Users/lancecleveland/vagrant-local/www/wpslp/public_html/wp-includes/functions.wp-scripts.php

This is a PHP inline function.

The local $wp_scripts variable is set as a copy of the global $wp_scripts variable which is an instantiation of the WP_Scripts class.
Read More

WordPress 4.8.2 Data Query Woes

Millions of websites across the Internet were automatically updated to WordPress 4.8.2 yesterday.    Thousands of those sites have key components that are no longer working.   Many of those sites will be looking for new plugins and themes unless new patches are made to make those themes and plugins 4.8.2 compatible.   WordPress 4.8.2 Data Query WoesWordPress 4.8.2 Data Query WoesWordPress 4.8.2 Data Query Woesn the meantime there are going to be a lot more partially broken websites online for the next month.

Unfortunately for my Store Locator Plus add ons, we build and test against the latest “nightly” builds which has been on WordPress 4.9 beta for a while.  Somehow the changes to the prepare method did not make it to that build on our test systems until 36 hours ago; that is about 3 hours AFTER we finished testing the latest 4.8.4 updates.  The very same locator updates that we published just over 30 hours ago.

What Changed?

WordPress changed a key component of the system architecture that is used by thousands of plugins, the database management interface.    The prepare() function of the WordPress Database class (WPDB) is used to manage data queries and replace placeholders with variables when performing searches.

As part of the WordPress 4.8.2 security update the ability to use a variety of different standardized printf formats, where a %d represents a number or a %s represents a string as a placeholder, was severely restricted.    As of 4.8.2 any plugin or theme that uses “undocumented’ or “unsupported” formats will no longer work.    To be more specific, any plugins or themes using the placeholders WordPress deems undocumented are not supported.

The officially supported placeholders are limited to:

Many plugins and themes use positional arguments like %1s or , as is the case in my Store Locator Plus Power add on, use the more accurate %u placeholder instead of %d.   These plugins and themes no longer work as of 4.8.2.

The Fix

Any plugin and theme that uses the wpdb->prepare() call, and they all should if they are processing data queries with variables being passed in, will need to change the string formats to use the 4 approved placeholders noted above.

Why %d and %u Are Important

In my case I elected to use the standard printf %u format which is an unsigned integer format.   The reason I chose this option is because the WordPress standard for data storage of keys in WordPress tables is the MySQL unsigned integer.

What’s he difference?   Both PHP and MySQL store 2 billion values in a signed integer and 4 billion in an unsigned integer.    That means you can have TWICE as many records in your database with unsigned integers but more importantly you avoid possible confusion.   Can you imagine telling someone “No, no, no, I meant record number NEGATIVE 1357 not POSITITVE 1357”?

WordPress decided that they would limit the standard prepare to the %d , signed integer format which is limited to 2 billion unique entries.  Granted that will cover nearly any real world WordPress install, but for the one site that hits record 2-billion-and-one there is likely to be trouble.

Today, I brought this up on the WP Core ticket system.   Maybe they’ll change it.  Maybe not.  In the meantime I’m replacing all %u references with %d because my client’s don’t care about technical merit but rather just want their sites to stay running.

 

Update:  on my PHP7 based system the “internal workings” of PHP don’t change how %d and %u are working.  That’s good news.

You can run this same sprintf() on your box to verify %d and %u are interchangeable, but for WPDB ALWAYS use %d.   Now to change a lot of code.

%d bloggers like this: