Make WordPress Core

Opened 7 months ago

Last modified 2 months ago

#61352 new defect (bug)

PHP deprecation warning in /wp-includes/general-template.php

Reported by: nexbridge's profile nexbridge Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.5.5
Component: General Keywords: has-patch
Focuses: Cc:

Description

I'm getting the following warning on what is currently the latest version of WordPress:

PHP Deprecated:  explode(): Passing null to parameter #2 ($string) of type string is deprecated in /wp-includes/general-template.php on line 1425

This is the line in question:

$title_array = apply_filters( 'wp_title_parts', explode( $t_sep, $title ) );

The PHP version is 8.2.

Attachments (1)

general-template.diff (600 bytes) - added by nexbridge 5 months ago.
Patch

Download all attachments as: .zip

Change History (9)

#1 @Tussendoor
7 months ago

We are experiencing the same problem. It occurs on a dynamic post which we are creating on runtime.

Ways to reproduce:

  1. Add a rewrite tag to be able to catch a custom query
    <?php
    add_rewrite_tag('%rewrite_tag_example%', '([^&]+)');
    
  1. Add a rewrite rule for the rewrite tag
    <?php
    add_rewrite_rule('basepage/([^/]*)/?', 'index.php?rewrite_tag_example=$matches[1]', 'top');
    
  1. Register a template with template_include
    <?php
    add_filter('template_include', 'registerFrontendTemplate', 9999);
    
  1. Add the registerFrontendTemplate function with a custom query to dynamically populate a template
    <?php
    /**
     * Register the template file
     *
     * @param string $template
     * @return string
     */
    function registerFrontendTemplate(string $template)
    {
        if (empty(get_query_var('rewrite_tag_example'))) {
            return $template;
        }
    
        // Add custom query here. To get data from a custom database table for 
        // example. Use the custom query variable to get postdata dynamically 
        // based on the request
    
        return locate_template('template/single.php');
    }
    
  1. Refresh the permalinks by navigating to the permalinks settings in the WordPress admin.
  1. Go to the generated frontend page: https:/example.com/basepage/test. With that URL the "rewrite_tag_example" query variable is filled with "test".
  1. On this page the <title> HTML-element will show the deprecation warning. This is because in wp-includes/general-template.php the wp_title function call the single_post_title function via:
    <?php
    // If there is a post.
    if ( is_single() || ( is_home() && ! is_front_page() ) || ( is_page() && ! is_front_page() ) ) {
        $title = single_post_title( '', false );
    }
    


And the single_post_title function returns null because of:

<?php
if ( ! isset( $_post->post_title ) ) {
   return;
}

Possible solution
We could make the single_post_title function return a string value. But this does not solve the problem for other possible occurances of this error that are possibly triggered by the wp_title function. So that requires changing the functions below to always return a string instead of string|void:

  • single_post_title
  • post_type_archive_title
  • single_term_title
  • single_term_title
  • post_type_archive_title

As the default value of $title is already an empty string (and not null) in the wp_title function we could try this for each occurance of those functions in wp_title:

<?php
// If there is a post.
if ( is_single() || ( is_home() && ! is_front_page() ) || ( is_page() && ! is_front_page() ) ) {
    $title ??= single_post_title( '', false );
}

The Null Coalescing Assignment operator (??=) does require PHP 7.4 tho.

Hope this helps! :)

#2 follow-up: @michaelreetz
7 months ago

Perhaps it would be better to just do the Null coalescing operator inside the explode.

<?php
/**
 * Filters the parts of the page title.
 *
 * @since 4.0.0
 *
 * @param string[] $title_array Array of parts of the page title.
 */
$title_array = apply_filters( 'wp_title_parts', explode( $t_sep, $title ?? '') ); 

This feels to me like what the code would have done in previous versions. And it would be compatible to php7.0.

#3 in reply to: ↑ 2 @Tussendoor
7 months ago

Replying to michaelreetz:

Yes that seems like a good approach!

#4 @nexbridge
6 months ago

  • Version changed from 6.5.3 to 6.5.5

Just to say that this is still happening in the latest version (6.5.5). I notice that the ticket status is currently "awaiting review" - how long does it normally take for a ticket to be reviewed?

#5 @nexbridge
5 months ago

Just to say that this is still happening in 6.6.1, however the line number has now changed to 1440.

@nexbridge
5 months ago

Patch

#6 @nexbridge
5 months ago

  • Keywords has-patch added

I've now added a patch as per the suggestion by @michaelreetz.

#7 @o----o
3 months ago

Same here.
The problem occurs at least in my case when on custom route where there is no "title" parameter as it is on default WP views.

WP Version 6.6.2

#8 @Beee
2 months ago

Still happening in 6.7.

When will this fix be applied ? This error is kind of annoying.

Note: See TracTickets for help on using tickets.