1

I have the following code:

function filterUsers(array $setOfAllUsers) {
   if (empty($setOfAllUsers)) {
      return array(array(), array());
   }

   $activeUsers   = array();
   $inactiveUsers = array();
   foreach($setOfAllUsers as $userRow) {
       $var = ($userRow['IsActive'] ? '' : 'in') . 'activeUsers';

       $$var[$userRow['CID']]['Label'] = $userRow['UserLabel'];
       // Error happens here ---^

       $$var[$userRow['CID']]['UserList'][$userRow['UID']] = array(
           'FirstName' => $userRow['FName'],
           'LastName'  => $userRow['LName'],
           ... More data
       );
   }

   return array($activeUsers, $inactiveUsers);
}

I get the following error: Warning: Illegal string offset 'Label' in ...

How can I fix this? I tried defining Label part first like this: $$var[$userRow['CID']] = array(); $$var[$userRow['CID']]['Label'] = ''; but did not work.

To make things clear what I am trying to achieve is this:

if ($userRow['IsActive']) {
   $activeUsers[$userRow['CID']]['Label'] = $userRow['UserLabel'];

   $activeUsers[$userRow['CID']]['UserList'][$userRow['UID']] = array(
           'FirstName' => $userRow['FName'],
           'LastName'  => $userRow['LName'],
           ... More data
   );
} else {
   $inactiveUsers[$userRow['CID']]['Label'] = $userRow['UserLabel'];

   $inactiveUsers[$userRow['CID']]['UserList'][$userRow['UID']] = array(
           'FirstName' => $userRow['FName'],
           'LastName'  => $userRow['LName'],
           ... More data
   );
}

Instead of repeating above in if/else I wanted to achieve it using $$

GGio
  • 7,563
  • 11
  • 44
  • 81
  • How do you create `$setOfAllUsers` and what does that array look like. Example only please. – RiggsFolly Aug 14 '15 at 14:23
  • 1
    You have double dollar sign `$$var` in your loop variable. – marian0 Aug 14 '15 at 14:25
  • @RiggsFolly its a function so its being passed in, in some cases its retrieved from database in some cases its built on the fly – GGio Aug 14 '15 at 14:25
  • This error is often when you don't have array. In this case it's `$setOfAllUsers`. Please check it with var_dump – Kristiyan Aug 14 '15 at 14:25
  • @marian0 thats intentional since I want to access "variable of a variable" – GGio Aug 14 '15 at 14:25
  • Is $userRow['CID'] set? – Rachel Geller Aug 14 '15 at 14:25
  • @RachelGeller yes all data is set within, its saying undefined index on 'Label' which is not gotten from userrow – GGio Aug 14 '15 at 14:26
  • How do you think `$$var[$userRow['CID']]` means `${$var[$userRow['CID']]}` or `{$$var}[$userRow['CID']]`? – u_mulder Aug 14 '15 at 14:27
  • @u_mulder I am just trying to populate $activeUsers & $inactiveUsers arrays without doing same thing twice. I know there is other way of doing it I just wanted to know why cant I do it using $$. – GGio Aug 14 '15 at 14:29

4 Answers4

4

Try using ${$var} instead of $$var.

EDIT

From PHP Manual (http://php.net/manual/en/language.variables.variable.php):

In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second.

arbogastes
  • 1,308
  • 9
  • 10
3
function filterUsers(array $setOfAllUsers) {
   if (empty($setOfAllUsers)) {
      return array(array(), array());
   }

   $users = array(
     'inactiveUsers' => array(), 
     'activeUsers'   => array()
   );
   foreach($setOfAllUsers as $userRow) {
       $status = ($userRow['IsActive'] ? '' : 'in') . 'activeUsers';
       $users[$status][$userRow['CID']] = array();
       $users[$status][$userRow['CID']]['Label'] = $userRow['UserLabel'];

       $users[$status][$userRow['CID']]['UserList'] = array(
           $userRow['UID'] => array(
             'FirstName' => $userRow['FName'],
             'LastName'  => $userRow['LName'],
           )
       );
   }

   return $users;
}
Mihai Matei
  • 24,166
  • 5
  • 32
  • 50
  • 1
    Thank you, this seems like a cleaner version of what I am trying to do and wont confuse anyone :). I guess I forgot to make things simpler and not over complicate it. – GGio Aug 14 '15 at 14:36
0

Try the following:

$myUsers = $$var;
$myUsers[...][...] = ...;

The problem with using $$var[...][...] is that first $var[...][...] is evaluated and then it tries to find the variable named $$var[...][...].

John Bupit
  • 10,406
  • 8
  • 39
  • 75
  • I tried that, it returns empty since it does not modify the $activeUsers and $inactiveUsers arrays – GGio Aug 14 '15 at 14:31
  • Although this doesn't answer the original question using `$$`, but try that using `$myUsers = ($userRow['IsActive'] ? $activeUsers : $inactiveUsers);`. – John Bupit Aug 14 '15 at 14:35
0

Don't use var-vars like this. You run into a PHP syntax glitch. And even if there wasn't a syntax glitch, you shouldn't be using var-vars in the first place. They make for near-impossible-to-debug code.

$x = 'foo';
$foo = array();
$$x[0] = 1;
var_dump($x);  // string(3) "foo"
var_dump($foo); // array(0) { }
$$x[1][2] = 3;
PHP Notice:  Uninitialized string offset: 2 in php shell code on line 1

Note how the array didn't get modified by the $$x[0] assignment, and how the 2+ dimensional assigment causes "undefined string offset". Your var-var isn't being treated as an array - it's being treated as a STRING, and failing, because it's a syntax glitch. You can treat strings as arrays, but not using var vars:

$bar = 'baz';
$bar[1] = 'q';
echo $bar; // output: bqz

There appears to be NO way to use a var-var as an array, especially a multi-dimensional array.

Marc B
  • 356,200
  • 43
  • 426
  • 500