What is WP_DEBUG for and how do I use it?

PHP normally only displays fatal errors in the browser, or doesn’t load any page content and gives you a “White Screen of Death (WSOD)” if it has a fatal error before the page can load. A fatal error is one in which something is so wrong in the PHP code that it cannot make sense of it to gracefully fail in the background. If I forget to add chocolate chips when making cookies, I still have a perfectly tasty dough. If I forget to add baking soda though, I end up with a flat, gooey mess.

WordPress has a few features built in to make it easier to see PHP errors while you are testing. You’d want to activate these while developing a new site, theme, or plugin to ensure that you are seeing any PHP errors that come up.

As mentioned in the last post on PHP Illegal Strings, there are a few failure types in PHP including warnings, notices, and errors. Turning on WP_DEBUG will allow you to see those failure types so that you can fix them in your code.

Activating WP_DEBUG

If you have access to all of the files of your WordPress install, you’ll want to edit the wp-config.php file, which is located in the root directory, meaning the same folder that has the wp-admin, wp-content, and wp-includes folders. You’re going to go into that file and add the following line of code near the bottom of the file, but before the stop editing notice:

define( 'WP_DEBUG', true );

/* That's all, stop editing! Happy blogging. */

If that line already exists but says false, change that to true. There can be other lines of code above or below this, but as long as it’s above the comment to stop editing, it’s in the right spot.

What did we do?

We’ve now told WordPress that rather than hide PHP errors, we want them to display while viewing the site. WP_DEBUG is a PHP constant, which by convention are written in all caps. We’ve used the PHP define() function to set the value of that constant to a boolean true. Note that we didn’t surround the word true in quotes, otherwise PHP would read it as a string.

Using WP_DEBUG also allows us to see any deprecated functions that are running on our site. Deprecated functions exist in WordPress but are no longer the standard way to perform a particular tas. As an example, long ago in WordPress history you would get the ID of a category in WordPress with the function the_category_ID(), but now the function to do the same in a better way is get_the_category().

Using WP_DEBUG_LOG and WP_DEBUG_DISPLAY

There are some companions to WP_DEBUG that can be used to make it even more helpful. You may not always be able to easily see errors if they are loading behind content, or you may want to keep track of them over time to review later. Two other constants that are built into WordPress that can help are WP_DEBUG_LOG and WP_DEBUG_DISPLAY.

Using WP_DEBUG_LOG

Setting up WP_DEBUG_LOG allows you to save all of the debug errors that are getting displayed to a file in your WordPress install. That file gets saved to wp-content/debug.log by default. Whenever an error occurs that WP_DEBUG would display, it will also get saved to that file with a timestamp of when the error occured.

To turn on WP_DEBUG_LOG you’ll want to define the following constant:

define('WP_DEBUG_LOG', true);

You don’t have to worry about creating the debug.log file if it doesn’t already exist. WordPress will do this for you automatically as soon as it has an error to log. So hopefully not right away!

Changing WP_DEBUG_DISPLAY

By default, setting WP_DEBUG to true will display all errors on the screen in your browser, on both the visitor-facing frontend, and the admin-facing backend of your site. This is ok while you’re editing a site that isn’t live with other people using it, but you don’t really want those errors displaying to other site visitors. It will make the site look more broken than it is, and can even be a security concern.

If you want to use WP_DEBUG but don’t want to display errors to the screen, set the following constant:

define('WP_DEBUG_DISPLAY', false);

Again, if you don’t set that as false, it will default to true when debug is turned on. If you are setting it to false, you’re probably also setting WP_DEBUG_LOG to true, since otherwise you won’t see the errors on the screen or in a debug log.

If you want to passively log errors for review later on a live site, just in case any come up, you can combine the three definitions above to turn on debug mode, log errors, and stop them from displaying on the site. I recommend doing this if you don’t have anything else handling these error logs for you, which you’d probably know if you did.

// Enable WP_DEBUG mode
define('WP_DEBUG', true);
 
// Enable Debug logging to the /wp-content/debug.log file
define('WP_DEBUG_LOG', true);
 
// Disable display of errors and warnings 
define('WP_DEBUG_DISPLAY', false);

Continuing to Debug Your Site

The settings above display PHP errors, but they don’t actually do anything to fix them. You’ll need to handle that yourself. Still, they provide an invaluable source of information to determine why something is broken on your site. This won’t show all types of errors that could occur, since not all broken page or feature problems are PHP related.

What it does do is give you a good footing to begin the fun part of debugging: digging into code and squashing bugs as you find them. In this case the old proverb is true: Knowledge is Power.

PHP v7.1 and v7.2 Illegal Strings

An update to Yoast SEO v11.1 came out yesterday, causing a few site errors relating to illegal strings in PHP. It made me dust off this post to provide some detail on what that PHP warning is, why it is happening, and how it can be fixed.


Last year I updated all existing client sites that I could to PHP version 7.2, to replace versions 5.6 and 7.0, both of which reached their end of security update lifespans in December of 2018. The current plan for WordPress v5.2 is to drop support for versions of PHP below 5.6, which is targeted to be released on 7 May. If this goes well, the minimum PHP version will be bumped to 7.0 later this year.

We’re only a few weeks away from this change, and a lot of hosts have been informing users that their version will change, or that they should opt-in to update when they can. One issue is that there are some things that work in earlier versions of PHP that will now throw warnings, notices, and errors in newer versions. One of the ones that I had to contend with on a few sites recently was the “Illegal string offset” warning.

Warning: Illegal String Offset

Here’s a few warnings that appeared on a development version of a site that I was upgrading (file path removed for readability):

__Warning:__ Illegal string offset 'menu' in [file location] on line 13
__Warning:__ Illegal string offset 'post_types' in [file location] on line 25
__Warning:__ Illegal string offset 'post_formats' in [file location] on line 36

I’m noting that it’s a development environment, because I had WP_DEBUG set to true in my wp-config.php file, which I don’t do on live, production environments. Basically, I ensure that on a live version of a site I don’t have PHP errors/warnings/notices displayed, even if there are some that would otherwise display.

I took a look at that file, which was a configuration file for the theme being used. The relevant lines from that file are below:

/*
 * Theme menu
 */
$theme['menu'] = array(
    THEMENAME,
    'Slideshow',
    'Sidebars',
    'Style',
    'Upload your fonts',
    //'Help'
);

/*
 * Post types
 */
$theme['post_types'] = array(
    'Posts',
    'Pages',
    'Works',
    'Testimonials',
);

/*
 * Post formats
 * aside, gallery, link, image, quote, status, video, audio, chat
 */
$theme['post_formats'] = array( 'gallery' );

Can you spot the issue? I didn’t immediately see it myself, as I saw things like $theme['menu'] and thought “how can that be read as a string? The braces clearly indicate that we’re setting an array key.

Explicitly Declaring an Array in PHP

What I didn’t realize was that we were missing something that’s necessary as of PHP v7.1.0: an explicit declaration of the variable $theme as an array. If you take a look at the PHP.net manual entry on PHP Array Syntax Modifying, you’ll see the following note:

Note: As of PHP 7.1.0, applying the empty index operator on a string throws a fatal error. Formerly, the string was silently converted to an array.

So there’s our issue, and with it, a lead on a solution: the theme never explicitly declared the variable $theme to be an array, and so it was assumed to be a string. Since it is no longer being silently converted, we have a warning being thrown.

Fixing the Illegal String Offset Warning

The solution in this case is to add a line to the start of that block of code where we explicitly declare our variable as an array. What that looks like is this:

$theme = array();

/*
 * Theme menu
 */
$theme['menu'] = array(
    THEMENAME,
    'Slideshow',
    'Sidebars',
    'Style',
    'Upload your fonts',
    //'Help'
);

By adding $theme = array();, we’re telling PHP, “yes, this is an array, please treat it as such.” It doesn’t have to try to guess what we mean, which newer versions of PHP no longer do anyway.

PHP v7.0+ also introduces strict typing, which is great for being even more explicit in your PHP coding. This makes the code more secure (people can’t put different data types in than you intend), and less liable to break (you will always know what type of data to expect). If you want to learn a bit more, Eric Mann wrote a short introductory post on the topic early last year.

PHP is getting better and better all the time, but this progress sometimes causes old code to break. While this is frustrating, it can also give you the opportunity to review old code with fresh eyes. It’s not always convenient to do this, but it can overall improve your site!

How to Remove the Genesis SEO Settings

If you’re like me, you don’t do much for SEO on your site. If you’re a better marketer than me and also have tools that you use for SEO, you probably don’t use the built-in SEO tools with the Genesis Theme Framework.

The tools do their job and are already there if you want to use them, but they can be limiting, as well as duplicate work being done with any other SEO plugin that you may be using. You can choose not to use them, but they still take up some valuable space in your dashboard and while editing pages, and they can be a bit confusing if you’re handing the site off to someone else to manage.

WordPress Gutenberg post editor with Genesis SEO enabled
Look at all of that space devoted to an unused settings section!

Removing the Genesis SEO Settings

One of the many great things about Genesis is that it allows you to easily modify or remove various portions of it without having to directly edit the core files of the theme. This allows you to modify your child theme only, so that if you ever switch child themes or Genesis updates, your changes won’t break.

Place the following code in your functions.php file, or another file that loads on the dashboard.

// Remove Genesis SEO settings from post/page editor
remove_action( 'admin_menu', 'genesis_add_inpost_seo_box' );

// Remove Genesis SEO settings option page
remove_theme_support( 'genesis-seo-settings-menu' );

// Remove Genesis SEO settings from taxonomy editor
remove_action( 'admin_init', 'genesis_add_taxonomy_seo_options' );

The first line of code removes the SEO metabox in posts/pages/custom post types. The post editor is already looking cleaner!

WordPress block post editor without Genesis SEO settings section
Now there’s less distraction while writing a post!

The second line of code removes the SEO settings menu from the left sidebar in the dashboard. If we’re not using it at all, no reason to have the settings page!

Finally, the last line of code removes the SEO settings from taxonomies. That means that you won’t be able to access them on categories, tags, or any other custom taxonomies on the site.

And with that, we’re done! Three lines of code (plus a bit of spacing and comments to make it easier to read and remember what we did that for later), and we’ve removed access to the Genesis SEO settings. Again, this isn’t a knock on Genesis, but simply a way to clean up your site a bit if you’ve already invested in another SEO tool for WordPress.

When to use isset(), empty(), and is_null() in PHP

I’ll be honest: most of the posts that I write are either because I’ve solved a problem for a client, or because I solved a problem that Past-David created. This is one of those PD problems, where I wrote some code that stopped functioning. When I looked into it, it turns out that I was using the wrong function to test for a variable in PHP.

There are a variety of functions made to test the state and value of variables, including ones that can tell you if there is anything available to use at all. Three of these functions that are easy to mix up are isset(), empty(), and is_null().

Built-in Variable Testing Tools

All three of these functions are built into PHP, so they should always be available for your use when writing code. empty() and isset() are language constructs, while is_null() is a standard function. We’ll go over why that’s important later in the article.

Before I discuss the difference and show a few examples, here are the descriptions for empty(), isset(), and is_null() from the php.net manual.

empty()

empty ( mixed$var ) : bool

Determine whether a variable is considered to be empty. A variable is considered empty if it does not exist or if its value equals FALSEempty() does not generate a warning if the variable does not exist.

isset()

isset ( mixed$var [, mixed$... ] ) : bool

Determine if a variable is set and is not NULL.

If a variable has been unset with unset(), it will no longer be set. isset() will return FALSE if testing a variable that has been set to NULL. Also note that a null character (“\0”) is not equivalent to the PHP NULL constant.

If multiple parameters are supplied then isset() will return TRUE only if all of the parameters are set. Evaluation goes from left to right and stops as soon as an unset variable is encountered.

is_null()

is_null ( mixed$var ) : bool

Finds whether the given variable is NULL.

What’s the difference between these variable testing functions?

You can see from the above definitions that these three functions do similar, but not the same things. You’ve gotta determine if you’re trying to test for whether a variable is null, true or false, and whether the variable has been declared.

When to use empty()

If you are using empty() you can test if a variable is false, but also if the variable does not exist. This function is best used when you want to ensure both that the variable exists, and has a value that does not equal false. Note that PHP will treat empty strings, integers of 0, floats of 0.0, empty arrays, and the boolean value of false as false. So basically, only use empty() when you want to ensure that there is some actual value to the variable.

Since you don’t have to declare variables before using them in PHP, you can get in a position where you are trying to perform actions or run other tests on a variable that hasn’t yet been declared. While it’s best practice to declare your variables before use for this and other reasons, this gotcha is one of the reasons that empty() is used differently from isset().

When to use isset()

If you are using isset(), you can test specifically if the variable has been declared already, and that the value is not null. So as long as you have a declared variable that has a value set and is not of the value NULL, you’ll return true when you test it with isset(). This would be a good condition to check before doing other checks to perform actions on a variable:

// Declaring our variable
$variable = 'Some String';

// Testing that our variable exists, then testing the value
if ( isset( $variable ) && $variable !== 'Some Other String' ) {
    echo 'This code evaluates since both of the above are true';
}

In the above example, we’ve declared our variable as a string, then tested if the variable is set (it is), and if it is not equal to a different string (it is not). Since both of those tests are true, we would then echo out the sentence in that conditional statement.

Should you use is_null()?

Finally, is_null() works in a similar manner to isset() as its opposite, with one key difference: the variable must be declared to return true, provided that it is declared without any value, or is declared specifically as NULL.

I said above that isset() tests whether a variable has been set or not, which is true, but it can handle no variable being set and providing an output of false. That is helpful if somewhere else in the code the unset() construct has been used to remove a variable from scope entirely.

In contrast, is_null() would not only not properly evaluate, it would also return a notice due to its inability to evaluate. Usually that’ll look something like this:

Notice:  Undefined variable: variable in /directory/to/code.php on line X

Since isset() is both a language construction, and can handle variables that aren’t declared, I’d generally recommend it over using is_null() in any situation. If you need to use is_null(), I might suggest finding a way to rewrite your code instead.

Language Construct vs. Built-In Function

I mentioned before that isset() and empty() are both language constructs in PHP, where is_null() is a built in function. Language constructs are reserved keywords that can evaluate whatever follows them in a specific manner. That means that it already knows what to do without having to find the definition of the construct like it would a function.

The main things to keep in mind between the two when evaluating your code is that language constructs in PHP are slightly faster (but honestly not enough to worry about for speed optimization), they can’t be used in variable functions, and they don’t throw any errors when evaluating variables that don’t exist.

Many times I see warnings and notices because a variable hasn’t been declared, and no one has confirmed that the variable already exists before trying to do some other conditional check with it. Using isset() and empty() can go a long way to avoiding those errors.

Examples of output of these three functions

The following table has been taken directly from a demo created by Virendra Chandak on his personal site. You can view the demo here.

Value of variable ($var)isset($var)empty($var)is_null($var)
“” (an empty string)bool(true)bool(true)bool(false)
” ” (space)bool(true)bool(false)bool(false)
FALSEbool(true)bool(true)bool(false)
TRUEbool(true)bool(false)bool(false)
array() (an empty array)bool(true)bool(true)bool(false)
NULLbool(false)bool(true)bool(true)
“0” (0 as a string)bool(true)bool(true)bool(false)
0 (0 as an integer)bool(true)bool(true)bool(false)
0.0 (0 as a float)bool(true)bool(true)bool(false)
var $var; (a variable declared, but without a value)bool(false)bool(true)bool(true)
NULL byte (“\ 0”)bool(true)bool(false)bool(false)

Setting up a Custom Palette in Gutenberg

While there’s been a lot written about the new editing experience that came out with WordPress v5.0 last month, I want to give a reminder of some of the neat features for end users. One of the best things about the new editor is that a theme or plugin can add or remove features from the editor with simple hooks, allowing you to craft an experience that fits your needs.

As an example, I have taken a few client sites that have embraced the new editor, and used their style guides to add their branding colors, fonts, and variants into the page editor. Now, when they want to add a block of content with a colored background or change the color of a button on a page, they have their palette of brand-approved colors already set to use. No need to remember hex codes or anything confusing!

Sounds great! How do I set up a custom color palette?

Default WordPress Editor Color Palette
Notice that the editor will warn you if your background and text colors aren’t high contrast. This makes it a bit easier to keep your content accessible!

By default the editor will have a palette of 11 colors, plus a color picker to get a different color. You can swap to a palette of your own by adding some code to your theme. Place the following in your functions.php file or where appropriate based on your structure. Next, we’ll modify it to fit our needs.

This code came directly from the Gutenberg Theme Support Handbook, a good resource for all WordPress developers.

function mytheme_setup_theme_supported_features() {
    add_theme_support( 'editor-color-palette', array(
        array(
            'name' => __( 'strong magenta', 'themeLangDomain' ),
            'slug' => 'strong-magenta',
            'color' => '#a156b4',
        ),
        array(
            'name' => __( 'light grayish magenta', 'themeLangDomain' ),
            'slug' => 'light-grayish-magenta',
            'color' => '#d0a5db',
        ),
        array(
            'name' => __( 'very light gray', 'themeLangDomain' ),
            'slug' => 'very-light-gray',
            'color' => '#eee',
        ),
        array(
            'name' => __( 'very dark gray', 'themeLangDomain' ),
            'slug' => 'very-dark-gray',
            'color' => '#444',
        ),
    ) );
}

add_action( 'after_setup_theme', 'mytheme_setup_theme_supported_features' );

There’s a lot of code there, but not a lot to break down. First, remember that after_setup_theme is a hook, on which you add the function mytheme_setup_theme_supported_features that you’re creating. In that function we’re using add_theme_support, a built in WordPress function, where we’re using editor-color-palette to set our palette up.

We’re adding an array of colors, and each element of that array is itself an array. Within those nested arrays we have the name of the color, which we’re making translatable with the __() function, and setting the textdomain of our theme. Change themeLangDomain to whatever matches your theme. This name is a descriptor for when you hover over it in the palette.

The slug is a string of how you’ll refer to the color elsewhere in your code. The color is the hexadecimal value of the color that you want in your palette. With the above code, you’ve got a new editor palette with four colors that you’ve set, along with the color picker.

Our custom WordPress editor color palette
Our four custom colors now appear, along with the color picker

Adding to Our Palette

There are a few more features of the editor color palette that I’d like to show off, including targeting blocks in CSS, Customizer set colors, and removing the color picker.

Using our Color Palette Selections in CSS

If you’re editing text with the color palette you shouldn’t have to make any other changes. But what if you want to use the color selection in something a bit more customized, or in your own block type?

The slug that we added to our colors in the example above lets us target for both background and text colors. We don’t even need to use the color set in the editor, but something custom to our needs. For example, you may want a specific background or text color when you use the strong magenta color. In that case, here’s the CSS that can target the classes added when we use that color:

.has-strong-magenta-background-color {
    background-color: #313131;
}

.has-strong-magenta-color {
    color: #f78da7;
}

Setting a Color Palette with the Customizer

The twentynineteen theme that comes with WordPress has a custom palette that includes colors that can be set in the Customizer. This means that you can set your own primary and secondary color from the WordPress dashboard, without changing code!

array(
		'name'  => __( 'Primary', 'twentynineteen' ),
		'slug'  => 'primary',
		'color' => twentynineteen_hsl_hex( 'default' === get_theme_mod( 'primary_color' ) ? 199 : get_theme_mod( 'primary_color_hue', 199 ), 100, 33 ),
	),
	array(
		'name'  => __( 'Secondary', 'twentynineteen' ),
		'slug'  => 'secondary',
		'color' => twentynineteen_hsl_hex( 'default' === get_theme_mod( 'primary_color' ) ? 199 : get_theme_mod( 'primary_color_hue', 199 ), 100, 23 ),
	),

The new color is now set as the output of a function that will get a theme mod, if you’ve modified the color. If not, it’ll return the default, ensuring that there’s always a color set.

The WordPress customizer with a primary color selection

Removing the Color Picker

You can also do things like disable the color picker, to ensure that users can only use the colors that you have preset for them. Doing so requires just one line of code in your functions file:

add_theme_support( 'disable-custom-colors' );

With that single line we’ve made it so the beautiful design that we’ve worked so hard to craft and the branding style guide that we have had to constantly review will always be set the way that we want.

Wrapping Up

As you can see, there’s a lot that you can do to change how users edit content in the Gutenberg editor, without having to add a tremendous amount of code.

This is only the beginning, and even more developer and user friendly features like this already exist or are coming to the editor and the rest of WordPress. I’m excited for the new opportunities this gives to all stakeholders of a site, from designers and developers, to admins and editors, all the way to customers and visitors. Let’s keep making WordPress better for everyone!