Skip to content

Backgrounds

How-to Guides

Technical References

Code Review /

VIP notices

These are items that should be addressed, but it’s unlikely that code that goes live to production with them will cause a performance or security problem. They might be best practices that help code maintenance or help keep the error logs clean, etc.

Check for is_array(), !empty() or is_wp_error()

Before using a function that depends on an array, always check to make sure the arguments you are passing are arrays. If not, PHP will throw a warning.

For example, instead of

$tags = wp_list_pluck( get_the_terms( get_the_ID(), 'post_tag') , 'name');

do:

$tags_array = get_the_terms( get_the_ID(), 'post_tag');
//get_the_terms function returns array of term objects on success, false if there are no terms or the post does not exist, WP_Error on failure. Thus is_array is what we have to check against
if ( is_array( $tags_array ) ) {
    $tags = wp_list_pluck( $tags_array , 'name');
}

Here are some common functions/language constructs that are used without checking the parameters beforehand: foreach(), array_merge(), array_filter(), array_map(), array_unique(), wp_list_pluck()
Always check the values passed as parameters or cast the value as an array before using them.

Using in_array() without strict parameter

PHP handles type juggling. This also applies to in_array(), meaning that this:

in_array( 0, ['safe_value', 'another string']);

Will return true.

Inline resources

Inlining images, scripts or styles has been a common workaround for performance problems related to HTTP 1.x As more and more of the web is now served via newer protocols (SPDY, HTTP 2.0) these techniques are now detrimental as they cannot be cached and require to be sent every time with the parent resource.

Using == instead of ===

PHP handles type juggling. Meaning that this:

$var = 0;
if ( $var == 'safe_string' ){
    return true;
}

Will return true. Unless this is the behavior you want you should always use === over ==.

Other interesting things that are equal are:

  • (bool) true == 'string'
  • null == 0
  • 0 == '0SQLinjection'
  • 1 == '1XSS'
  • 0123 == 83 (here 0123 is parsed as an octal representation)
  • 0xF == 15 (here 0xF is parsed as a hexadecimal representation of a number)
  • 01 == '1string'
  • 0 == 'test'
  • 0 == ''

Using output buffering

Output buffering should be used only when truly necessary and should never be used in a context where it is called conditionally or across multiple functions/classes. If used it should always be in the same scope and not with conditionals.

Not defining post_status or post_type

By default the post_status of a query is set to publish for anonymous users on the front end. It is not set in any WP_ADMIN context including Ajax queries. Queries on the front end for logged in users will also contain an OR statement for private posts created by the logged in user, even if that user is not part of the site. This will reduce the effectiveness of MySQL indexes, specifically the type_status_date index.


The same is true for post_type. If you know that only a certain post_type will match the rest of the query (for example for a taxonomy, meta or just general query) adding the post_type as well as the post_status will help MySQL better utilize the indexes at its disposal.

Using closing PHP tags

All PHP files should omit the closing PHP tag to prevent an accidental output of whitespace and other characters, which can cause issues such as ‘Headers already sent‘ errors. This is part of the WordPress Coding Standards.

Use wp_json_encode() over json_encode()

wp_json_encode() will take care of making sure the string is valid UTF-8 while the regular function will return false if it encounters invalid UTF-8. It also supports backward compatibility for versions of PHP that do not accept all the parameters.

Caching large values in options

Memcache has a 1MB cache key limit, anything above does not get stored and will be directly read from the DB.

switch_to_blog()

For multisite instances, switch_to_blog() only switches the database context, not the code that would run for that site (e.g. different filters).

VIP requirements

Every theme should include a VIP attribution link, wp_head(), and wp_footer() calls.

Last updated: April 09, 2021