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.
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.
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 ) ?: [];