Website membership errors after php 8 upgrade

By theclicklab - February 14, 2022

Website Membership1.13
CMS: 3.55

Hi there, Getting some warnings after upgrading to php 8:

Issue #1 - related to membership plugin

E_WARNING: Trying to access array offset on value of type bool (line 12)

The code:
if ($CURRENT_USER['member_approved'] == 1 && $CURRENT_USER['private_yacht_access'] == 1 ) {

Issue #2 - general php warning

#19595 - E_WARNING: Trying to access array offset on value of type null

In this block of code (see comments for where errors occuring)

<?php foreach ($yachtsRecords as $record): ?>

  <?php if ($record['yachtfolio_link_new']) {

    $yachtfolio_num = $record['yachtfolio_link_new'];
    list($link_redirectsRecords, $link_redirectsMetaData) = getRecords(array(
      'tableName'   => 'link_redirects',
      'where'       => "`num` = '". mysql_escape($yachtfolio_num) ."'",
      'loadUploads' => false,
      'allowSearch' => false,
      'limit'       => '1',
    ));
    $link_redirectsRecord = @$link_redirectsRecords[0];

      if ($link_redirectsRecord['link_destination']) {
        $linky = $link_redirectsRecord['link_destination']; // ERROR ON THIS LINE
      } else {
        $linky = $link_redirectsRecord['yachtfolio_link_destination'] . $settingsRecord['yachtfolio_id']; // ERROR ON THIS LINE
      }

    $linky_target = "_blank";

  } elseif ($record['yachtfolio_link']) {
    $linky = $record['yachtfolio_link'] . $settingsRecord['yachtfolio_id'];
    $linky_target = "_blank";
  
  } else {

    if ($yacht_typeRecord['num']==8) {
      $link = $record['_link'];
      $linky = strtolower(str_replace("yacht.php", "for-sale.php", $link));
      $linky_target = "_self";
    } else {
      $linky = strtolower($record['_link']);
      $linky_target = "_self";
    }

  }  
?>

By daniel - February 15, 2022

Hi theclicklab,

The broad reason for these errors is that in PHP 8 it throws an error if you try to use a variable as an array when it's not an array. In the first case, $CURRENT_USER can be false if a user is not logged in, and in the second case, $link_redirectsRecord will be null if nothing is returned by getRecords(). 

For issue #1, just making sure that $CURRENT_USER isn't empty should be sufficient, like this:

if (!empty( $CURRENT_USER ) && $CURRENT_USER['member_approved'] == 1 && $CURRENT_USER['private_yacht_access'] == 1 ) {

(This works because PHP won't evaluate the right side of an "&&" if the left side is false. So if $CURRENT_USER is empty, it doesn't "see" the rest of the if statement)

For issue #2, I'd suggest checking that the record exists before using it (this is a good practice to follow generally), something like this:

if (!empty( $link_redirectsRecord )) {      
  if ($link_redirectsRecord['link_destination']) {
    $linky = $link_redirectsRecord['link_destination']; // ERROR ON THIS LINE
  } else {
    $linky = $link_redirectsRecord['yachtfolio_link_destination'] . $settingsRecord['yachtfolio_id']; // ERROR ON THIS LINE
  }
}
else {
// some fallback here
}

Let me know if this helps solve the issue, or if you have any other questions!

Thanks,

Daniel
Technical Lead
interactivetools.com

By theclicklab - February 16, 2022

Thanks Daniel, was able to resolve everything with your examples. Much appreciated :)