Autowiring of Non-Shared Services

With the Symfony framework, most objects are supposed to live in the Service Container. This facilitates an “autowire” of all the class constructors, plus a great deal of magic from the debug tools.

Most objects are supposed to be “shared” as well. This is Symfony’s substitute for the singleton pattern. It helps prevent duplication of “services”. However, services don’t always fit this pattern.

One of the Symfony configuration tutorials divides object classes into only two types. In that limited example, objects would have to be “services that do work” or “models that hold data”. Again, services don’t always fit into this pattern.

Continue reading Autowiring of Non-Shared Services

Forcing PHP to Sort Like MySQL

If you ever have to do a case-insensitive array sort in PHP, you will eventually notice that the results don’t match the MySQL latin1_swedish_ci collation. They just aren’t the same. The difference comes from a set of six characters that fall between the upper-case and lower-case alpha characters of ISO-8859-1.

Specifically, [ \ ] ^ _ ` are the troublemakers. A simple example would involve sorting the phrases “Hello” and “[Hello]”. In MySQL, “Hello” comes first. In PHP, “Hello” comes last.

If this is driving you crazy, all you will need to do is trick PHP into using an upper-case sort instead of a lower-case sort.

$strings = ['hello', '[Hello]', 'Hello'];
usort( $strings, 'mysql_simulator' );
var_dump( $strings );

function mysql_simulator( $a, $b ) {
return strcmp( strtoupper( $a ), strtoupper( $b ) );
}

I hope this will save you some of the research in solving that pesky little difference.

Cannot Use Dynamic Class Name

It seems I’ve discovered a new kind of PHP error that isn’t documented anywhere on the web yet. Here is a simple example and explanation to help correct your code.

class MyClass {}
$obj = new MyClass;
$test1 = MyClass::class;    // Right
$test2 = get_class( $obj ); // Right
$test3 = $obj::class;       // Wrong

That last line in my code sample produces the following error in PHP 7.4.

Fatal error: Cannot use ::class with dynamic class name in […][…] on line 5

This is the PHP way of saying that you have to switch to the get_class() function when retrieving the fully qualified class name of an object.

Note: An existing RFC proposes to change this behavior in PHP 8, so this particular error message might not exist in some future versions.

like_escape() is Deprecated in WordPress 4.0

Plugin authors and website developers who work with WordPress database queries should notice an important change coming in WordPress 4.0.

The function like_escape() is no longer used in WordPress core code.  It is still available as a deprecated function, so it still works in any existing plugins that rely on it.  However, a new and different function is available that should be used in all new code.

Deprecated means that anyone using code that calls like_escape() with WP_DEBUG enabled will see an error message.  If WP_DEBUG_LOG is also enabled, the error message will appear in the /wp-content/debug.log file.

Let’s look at an example of core code where I removed like_escape() and implemented the new function $wpdb->esc_like().

3.9 Old Style

$search_orderby_s = like_escape( esc_sql( $q['s'] ) );

$search_orderby .= "WHEN $wpdb->posts.post_title LIKE '%{$search_orderby_s}%' THEN 1 ";

What did this do?  It was an old snippet from /wp-includes/query.php that set up a search for post titles.  The input $q['s'] was escaped using two functions before it was added to the post_title LIKE expression.  Now let’s see how I replaced that snippet in the next version.

4.0 New Style

$like = '%' . $wpdb->esc_like( $q['s'] ) . '%';

$search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_title LIKE %s THEN 1 ", $like );

Continue reading like_escape() is Deprecated in WordPress 4.0

PHP Array Assignment and References

This is a quick explanation of some more referencing quirks in PHP.

Let’s say you need to store an array in a specific variable so that another variable can be freed up and overwritten with different information.  [To clarify, this array may be very large and copying it would be detrimental to performance in this particular application. For small arrays, copying and not referencing may be preferable.]

The operation for referencing the array with a new variable is quite simple:

$array_goes_here =& $need_to_free_up_this_var;

The code above will reference the array to prevent PHP from making an unnecessary copy of the whole thing.

Now here’s what you have to avoid:

$need_to_free_up_this_var = array(); /* wrong! */

Continue reading PHP Array Assignment and References