Search code examples
phparraysclassdynamic-data

$this->$array[$key] returning nothing when there is a value in place


I'm attempting to dynamically use a value in an array within an object.

In my particular case I have an array like this.

$this->customer = array(
     [dealerId] => 4
     [billFirstName] => Joe
     [billLastName] => Blo
     [billAddress1] => 1010s    
     [billAddress2] => 1020s
     [billCity] => Anytown
     [billState] => ST
     [billCountry] => USA
     [billPostalCode] => 11111
     [dEmail] => emailaddress
     [billPhone] => 8008008888
     [password] => password
     [distPrice] => 5
     [distCost] => 20);

$result = $this->keyCheck('dealerId', 'customer');

The method I'm using:

protected function keyCheck($key, $array, $type = false)
    {
      if(array_key_exists($key, $this->$array) && $this->$array[$key]):
        return $this->$array[$key];
      else:
        return $type;
      endif;
    }

The first check works (array_key_exists($key, $this->$array)). But the second check fails ($this->$array[$key]) even though there is a value held in that index of the array. I've proven that the array exists inside the keyCheck() method by using, print_r($this->$array); inside the method. And I know the value I'm looking for is available inside the method by using, print $this->$array['dealerId'];

Don't get hung up on the names, or the methodology I'm using, what I'm really interested in is finding out how to address a value held in an array that is dynamically addressed in this way.

It's probably so easy that I'll be slapping my head once it's revealed...


Solution

  • You are running into the dreaded treat string as an array trap, i.e.:

    $str = 'customer'; echo $str[0]; // prints c
    

    The $array[$key] portion of $this->$array[$key] is being interpreted as show me the nth index of string $array (if you pass customer it will try to access $this->c, which doesn't exist). Assign the array to a variable first. Here is an example:

    class A
    {
        public $customer = array('dealerId'=>4, 'billFirstName'=>'Joe');
    
        public function keyCheck($key, $arrayName, $type = false)
        {
            $array = $this->$arrayName;
            if(array_key_exists($key, $array) && $array[$key]) {
                return $array[$key];
            } else {
                return $type;
            }
        }
    }
    
    $a = new A();
    echo $a->keyCheck('billFirstName', 'customer'); // Joe
    

    Alternatively, you could use the complex syntax: $this->{$arrayName}[$key] as suggested in Artjom's answer.

    PHP 5.4 addresses this gotcha:

    [In PHP 5.4] Non-numeric string offsets - e.g. $a['foo'] where $a is a string - now return false on isset() and true on empty(), and produce a E_WARNING if you try to use them.

    This E_WARNING should help developers track down the cause much more quickly.