Strange PHP-related problem

On the same reseller hosting account, I have several different cPanel accounts.

I've created a few websites using the very same theme, and mostly the same choice of plugins.

However, one particular site, let's call it "A" gives a PHP error code.

"Undefined variable $custom_content in /home/blabla/public_html/wp-content/themes/generatepress_child/functions.php on line 51"

Other sites use the same theme and the same child-theme custom code.

They all run fine on PHP 7.4.
With PHP 8.0, site A starts reporting that problem.

Using exactly the same PHP configuration (extensions, version etc.).

Is it possible to have PHP configured differently by the hosting provider on a per-cPanel account level?
The only notable difference between website A and the others is the time when the cPanel account was created.

I still haven't tried completely deleting the cPanel account and re-creating it. Not sure if that makes sense to try.

BikeGremlin
Mostly harmless ™

Comments

  • AmitzAmitz OG
    edited September 15

    (edit: scratch that, I misunderstood your question)

    Amitz, a very stable genius (it's true!) and Grand Rectumfier of the official LESLOS® (LES League of Shitposters).
    Certified braindead since 1974 and still perfectly happy.

  • PHP 8 != PHP 7.4

    There are several changes from PHP 7.4 to PHP 8 .

    If a plugin or function uses something which is not working in PHP 8 but working in 7.4 then you might have that issue . Also, there are several PHP extensions, sometimes a plugin / theme / code uses a particular extension which may not be available on other PHP installation, then also you may get similar issue.

    Generally errors are hidden from public view, you need to look error logs closely to find exact issue.

    Thanked by (1)nickelodeon
  • edited September 15

    @Saahib said:
    PHP 8 != PHP 7.4

    There are several changes from PHP 7.4 to PHP 8 .

    If a plugin or function uses something which is not working in PHP 8 but working in 7.4 then you might have that issue . Also, there are several PHP extensions, sometimes a plugin / theme / code uses a particular extension which may not be available on other PHP installation, then also you may get similar issue.

    Generally errors are hidden from public view, you need to look error logs closely to find exact issue.

    Same setup - plugins, themes, custom code.
    One website has problems with PHP 8.0 - the others work fine.

    Well - no problems, all functions great in the frontend - but I get that PHP error in the error log.

    The function my custom code does is executed and shown in the frontend, as it should be. :(
    But error log shows a problem with that function. Only on that one site.

    Edit - just in case it helps, the "problematic" function code:

    This is the "problematic" code, if that is of any help:

    function wpb_last_updated_date( $content ) {
    $u_time = get_the_time('U');
    $u_modified_time = get_the_modified_time('U');
    if ($u_modified_time >= $u_time + 86400) {
    $updated_date = get_the_modified_time('d/m/Y');
    $custom_content .= '

    Updated: '. $updated_date . '.

    ';
    }
    $custom_content .= $content;
    return $custom_content;
    }

    add_filter( 'the_content', 'wpb_last_updated_date' );

    BikeGremlin
    Mostly harmless ™

  • @bikegremlin said:

    $custom_content .= '<p class="last-updated">Updated: '. $updated_date . '. </p>';

    Replace .= with =

    It's not an error, it's a notice, you are trying to append text to a variable which is not defined yet.

    You probably have a separate custom php.ini for other sites and not site A, and looks like PHP8 changed default error reporting

    Thanked by (2)kkrajk PHP_Backend
  • @vedran said:

    @bikegremlin said:

    $custom_content .= '<p class="last-updated">Updated: '. $updated_date . '. </p>';

    Replace .= with =

    It's not an error, it's a notice, you are trying to append text to a variable which is not defined yet.

    You probably have a separate custom php.ini for other sites and not site A, and looks like PHP8 changed default error reporting

    don't change .= to = unless you know for sure that this isn't inside a loop or that var might be prefilled elsewhere under some circumstances.

    apart from that @vedran is right and it's probably just a notice/warning and not a real error. you could wrap a check around it to see if that var is empty or not.

    for why this might be different the hint towards error reporting is one possibility at least. check if you have a .user.ini in your doc root that might set some individual php settings overriding the default php.ini and so on.

    Thanked by (2)vedran bikegremlin
  • @Falzo said:
    don't change .= to = unless you know for sure that this isn't inside a loop or that var might be prefilled elsewhere under some circumstances.

    Yes in general, in this case we know for sure since it's inside a user defined function (and it's not declared as global or static) so it's scope is local to that function and won't be available elsewhere. Of course assuming this is full unstripped function code

    Thanked by (1)bikegremlin
  • Thank you - I'll give it a try.

    Interesting (for me at least):

    The function does its job with no problems, even when that error gets reported in the root directory.

    When I install and activate a plugin called “Subscribe To Comments Reloaded,” the error report goes away!?!?!

    Likewise, if I don’t change anything, just set the PHP back to 7.4 – the error report goes away also.

    I’ve checked everything else – PHP extensions, configuration, asked the provider to confirm the 8.0 is running OK.

    I use the above-noted plugin on several websites – and they had no problems with the error.log appearing.
    That’s how I finally figured out the… strange situation.

    The error report appears with GeneratePress and with GeneratePress premium.
    It doesn’t happen with TwentyTwentyone. :)

    BikeGremlin
    Mostly harmless ™

  • Removing the dots in both places removes the error, but the function no longer works.
    Removing only the first one doesn't remove the error.

    What I mean:
    $custom_content .= '<p class

    and
    $custom_content .= $content;

    Those two .= replaced with just =

    BikeGremlin
    Mostly harmless ™

  • Why would you remove the second? :# Remove just the first one

  • edited September 15

    @vedran said:
    Why would you remove the second? :# Remove just the first one

    That didn't help with the error. :(
    Didn't hurt, nor take much time to poke a bit. :)

    Edit - PS:

    Removing only the first one reports the error at the line of the second one.

    However, removing the second dot prevents the function from doing its job.

    BikeGremlin
    Mostly harmless ™

  • @bikegremlin said:

    @vedran said:
    Why would you remove the second? :# Remove just the first one

    Removing only the first one reports the error at the line of the second one.

    However, removing the second dot prevents the function from doing its job.

    Because removing . on second command will not append previous string.

    A simple uptime dashboard using UptimeRobot API https://upy.duo.ovh
    Currently using VPS from BuyVM, GreenCloudVPS, Gullo's, Hetzner, HostHatch, InceptionHosting, LetBox, MaxKVM, MrVM, VirMach.

  • Ah, I missed the fact the first one is within if statement so it might or might not be set. And if not you get the error in the second one.

    At this point probably best to just initialize the variable at the beginning of the function (or anywhere before if statement)
    $custom_content = '';

    And you can add back that dot (or don't, won't make any difference)

    Thanked by (2)bikegremlin Falzo
  • @Falzo said: don't change .= to = unless ...

    told you so :-P ;-) ;-) ;-)

    Thanked by (3)bikegremlin vedran Ympker
  • A "Solomon's solution" - I've removed all the PHP and added this to the style.css:

    /* BEGIN updated date showing only */
    
    .posted-on .updated {
        display: inline-block;
    }
    
    .posted-on .updated + .entry-date {
        display: none;
    }
    
    .posted-on .updated:before {
        content: "Updated: ";
    }
    
    /* END updated date showing only */
    

    It doesn't show "updated: ..." on pages, but it does on posts.
    Which may even be a better option - pages are more-less evergreen so an "updated" date doesn't make too much sense there.

    Thanked by (2)Falzo vedran

    BikeGremlin
    Mostly harmless ™

  • I like that approach, especially if it makes you use one unneccessary plugin less.

    though, you could have set the error reporting differently instead as @vedran suggested in the beginning. would have made that warning go away as well :-P

  • johnkjohnk Hosting Provider
    edited September 15

    @bikegremlin said:
    Likewise, if I don’t change anything, just set the PHP back to 7.4 – the error report goes away also.

    The issue is in PHP 8.0, usage became more strict compared to 7.4. So, technically "improper" assignment like what you were doing throws a warning now. You can ignore it or just suppress it if it bothers you.

    As for your code:

    function wpb_last_updated_date( $content ) {
      $u_time = get_the_time('U');
      $u_modified_time = get_the_modified_time('U');
      if ($u_modified_time >= $u_time + 86400) {
        $updated_date = get_the_modified_time('d/m/Y');
        $content = "Updated: $updated_date." . $content;
      }
      return $content;
    }
    add_filter( 'the_content', 'wpb_last_updated_date' );
    

    Why not just simplify it? :)

    Thanked by (2)corbpie bikegremlin
  • This thread kinda reminded me why PHP gets so much hate in programming space.
    PHP notices/warnings are not always harmless, so please don't suppress/hide them by editing some .ini file. It's better to get our hands dirty and fix the issue.
    @johnk simplified one looks good, but don't forget the added line break :p . Also, your solution assumes that $content is plain string, but what if it can be a object too? PHP objects can contain magic method __toString() to behave same as string. This solution may break on that case.

    @bikegremlin , are you certain that the theme you're using officially supports PHP 8.0? If not, I wouldn't suggest upgrading PHP version. PHP 8.0 has some changes that won't be in error log but silently behave in different manner. Some can even corrupt your data without you knowing.
    So, I would contact theme devs to let them know about these issue and request them to upgrade their theme to PHP 8.0

  • johnkjohnk Hosting Provider

    @PHP_Backend said:
    @johnk simplified one looks good, but don't forget the added line break :p

    Nice catch!

    Also, your solution assumes that $content is plain string, but what if it can be a object too? PHP objects can contain magic method __toString() to behave same as string. This solution may break on that case.

    Yeah. Fortunately though, WP only passes a string in the the_content hook, so it won't be an issue.

    Thanked by (1)PHP_Backend
  • @johnk said: Yeah. Fortunately though, WP only passes a string in the the_content hook, so it won't be an issue.

    I have zero knowledge on WP, so thanks for letting me know.

    Thanked by (1)johnk
  • edited September 16

    unless the theme developer upgrades their entire theme's functions/code to php 8 compatible, please don't just use php 8 from php selector of cPanel or other panel, the reason is there are many changes made to php function working, few are deprecated, so what works on php 7.4 may not work on php 8 even if every setting/configuration is kept same.

    Thanked by (1)bikegremlin
  • edited September 16

    @PHP_Backend and @nickelodeon ... and the others who've contributed and helped:

    I am trying to do it all cautiously, by the book.
    Testing it first in a staging environment, staging on the production server, one production website, then the other production websites.

    WP, theme and plugins I use are allegedly PHP 8.0 compatible.
    The only error I saw was from my custom code - that's a fact.

    I'm writing a full report & analysis and will publish it, sending a copy to the "affected" theme, plugin developers, hosting provider tech. support (if another user reports the same problem), and, most importantly - here, so I can get help and possible corrections from the friendly LES experts and enthusiasts. :)

    Thanked by (1)PHP_Backend

    BikeGremlin
    Mostly harmless ™

  • Here's the full, thorough report:

    Strange WordPress PHP 8.0 error

    BikeGremlin
    Mostly harmless ™

  • @bikegremlin said:
    Here's the full, thorough report:

    Strange WordPress PHP 8.0 error

    it still is not an error and never has been ;-)
    only a warning. and yes, severity is a thing here...

    and that's also why it still worked on the frontend, no matter the warning being there

    Thanked by (1)bikegremlin
  • @Falzo said:

    @bikegremlin said:
    Here's the full, thorough report:

    Strange WordPress PHP 8.0 error

    it still is not an error and never has been ;-)
    only a warning. and yes, severity is a thing here...

    and that's also why it still worked on the frontend, no matter the warning being there

    From what I could gather - it's been a bad piece of code from the start.
    Just didn't get any warnings about it until now.
    And some themes and plugins seem to make those warnings disappear. :)

    Thanked by (1)Falzo

    BikeGremlin
    Mostly harmless ™

  • kkrajkkkrajk OG
    edited September 16

    @bikegremlin said: $custom_content .= 'Updated: '. $updated_date . '.';

    $custom_content = '<p class="last-updated">Updated: '. $updated_date . ' </p>';

    @bikegremlin said: $custom_content .= $content;

    $custom_content = $content;

    possible to check if this stops the warnings?

    Thanked by (1)bikegremlin
  • @kkrajk said:

    possible to check if this stops the warnings?

    I'd be happy to, just please post the complete, edited code (idiot friendly) :)

    Here's the faulty original:

    // BEGIN Last-updated display
    
    function wpb_last_updated_date( $content ) {
        $u_time = get_the_time('U'); 
        $u_modified_time = get_the_modified_time('U');
        if ($u_modified_time >= $u_time + 86400) { 
            $updated_date = get_the_modified_time('d/m/Y');
            $custom_content .= '<p class="last-updated">Updated: '. $updated_date .   '.  </p>';
        }
        $custom_content .= $content;
        return $custom_content;
    }
    add_filter( 'the_content', 'wpb_last_updated_date' );
    
    // END Last-updated display
    

    BikeGremlin
    Mostly harmless ™

  • // BEGIN Last-updated display
    
    function wpb_last_updated_date( $content ) {
        $u_time = get_the_time('U'); 
        $u_modified_time = get_the_modified_time('U');
        if ($u_modified_time >= $u_time + 86400) { 
            $updated_date = get_the_modified_time('d/m/Y');
            $custom_content = '<p class="last-updated">Updated: '. $updated_date . ' </p>';
        }
        $custom_content = $content;
        return $custom_content;
    }
    add_filter( 'the_content', 'wpb_last_updated_date' );
    
    // END Last-updated display
    
  • edited September 16

    @kkrajk said:
    // BEGIN Last-updated display

    function wpb_last_updated_date( $content ) {
    $u_time = get_the_time('U');
    $u_modified_time = get_the_modified_time('U');
    if ($u_modified_time >= $u_time + 86400) {
    $updated_date = get_the_modified_time('d/m/Y');
    $custom_content = '

    Updated: '. $updated_date . '

    ';

        }
        $custom_content = $content;
        return $custom_content;
    }
    add_filter( 'the_content', 'wpb_last_updated_date' );
    
    // END Last-updated display
    

    Oh, I had tried that - that way the function doesn't do the job (but the error code does disappear :) ).

    It is my understanding that the variable should be defined first as an empty string:

    $custom_content = ' ';

    Then it can be used (haven't tested it yet - used a CSS solution instead of PHP and it works better).

    Thanked by (3)kkrajk Falzo vedran

    BikeGremlin
    Mostly harmless ™

  • Mr_TomMr_Tom Hosting ProviderOG
    edited September 17

    @bikegremlin said: Here's the faulty original:

    Just set the variable to blank string before the if statement to remove the warning in PHP8

    As below

    function wpb_last_updated_date( $content ) {
        $u_time = get_the_time('U'); 
        $u_modified_time = get_the_modified_time('U');
        $custom_content = ''; // <-- ADD THIS LINE
        if ($u_modified_time >= $u_time + 86400) { 
            $updated_date = get_the_modified_time('d/m/Y');
            $custom_content .= '<p class="last-updated">Updated: '. $updated_date .   '.  </p>';
        }
        $custom_content .= $content;
        return $custom_content;
    }
    add_filter( 'the_content', 'wpb_last_updated_date' );
    
    Thanked by (2)bikegremlin Falzo

    VM Specialist - Custom, managed and storage VM solutions. | Latest Offers

Sign In or Register to comment.