0

I recently upgraded to PHP 7.2 and i've been running some old legacy code for a stupid record keeping system. Basically it holds an array of contest_id's and the entries to each contest.

/*
@Use: Adds entries into the active contest for a given member.
@Param: $user_id - INT
@Param: $entries - INT
*/
function add_vip_entries($user_id, $entries) {
  $user_data = get_user_meta( $user_id, 'all_contests', true );
  $contest_id = get_active_contest();
  if ($contest_id !== 0) {
    if (isset($user_data['all_contests'][$contest_id]['entries'])) {
      $user_data['all_contests'][$contest_id]['entries'] = intval($user_data['all_contests'][$contest_id]['entries'] + $entries);
    } else {
      $user_data['all_contests'][$contest_id]['entries'] = $entries;
    }
    update_user_meta( $user_id, 'all_contests', $user_data );
  }
}

This used to work fine but now if it's the first time the user gain entries to a given contest I get the following error.

Uncaught exception 'Error' with message 'Cannot use string offset as an array'

And it triggers on this exact line:

$user_data['all_contests'][$contest_id]['entries'] = $entries;

How Can I replicate the behavior it had in PHP7.0? It used to simply push create the data structure or if it was a brand new contest push a new contest ID and set of entries. Now it errors. I tried to edit into this

$user_data = array('all_contests' => array($contest_id => array('entries' => $entries)));

But this causes an issue where if a new contest ID is introduced it will set the data structure to only contain the contest ID and entry pair being set.

5
  • What would an example value for both $user_data['all_contests'][$contest_id] and $entries be? Commented Apr 14, 2020 at 1:25
  • see stackoverflow.com/questions/1873970/… Commented Apr 14, 2020 at 1:26
  • @KalebW - an int something like 10318 and 25 Commented Apr 14, 2020 at 1:28
  • 2
    Most likely $user_data doesn't contain an array. Maybe you just need to check the type and initialize all_contests if it doesn't. Commented Apr 14, 2020 at 1:29
  • If $user_data['all_contests'][$contest_id] stores an integer, you cannot use a string offset to access its data, so using $user_data['all_contests'][$contest_id]['entries'] is invalid. Commented Apr 14, 2020 at 1:30

2 Answers 2

0

The issue here is that you can't successfully play with a STRING variable using ARRAY keys unless you are simply trying to return the Nth character of the string using $myString[n].

Repro:

$x = 'hello'
echo $x[1]; // returns 'e', i.e. the 1st char (0 based) of 'hello'
$x[4] = 'x';
echo $x; // returns 'hellx';

$x['my_key'] = 5; // Error illegal string offset

I.e. you can use array keys to access the character of a string (i.e. the string offset, but it will only allow you to use a valid offset within the length of the string. You can't use a random key on a variable already initialized as a string.

You need to make get_user_data return an array at all times. If it is empty, return [].

$user_data = get_user_meta( $user_id, 'all_contests', true ) ?: [];
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, I believe the typecasting behavior changed between versions. It would normally just turn that into an array but now I force an array and it will always work. Thank you so much!
0

maybe $user_data = array('all_contests' => array($contest_id));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.