1

I have index ponter, for example 5-1-key2-3.

And my array has its address:

array(
  '5'=>array(
     '1'=>array(
        'key2'=>array(
             '3'=>'here it is - 5-1-key2-3 key address'
         )
      )
   )
)

which equals to

$arr[5][1][key2][3]='here it is - 5-1-key2-3 key address';

I know I can build the recursive function to access this value.

But I'm curious is it possible to achieve this without recursion and building user's functions and/or loops.

Probably it can be done with variable variables feature in php.

3
  • Post your array values with expected output Commented May 14, 2015 at 12:46
  • you need multidimensional array dynamic accessor, check my answer Commented May 14, 2015 at 12:54
  • check my second answer Commented May 14, 2015 at 13:35

3 Answers 3

2

You can use this code

$keys = explode('-', '5-1-key2-3');

// start from the root of the array and progress through the elements
$temp = $arr;
foreach ($keys as $key_value)
{
    $temp = $temp[$key_value];
}

// this will give you $arr["5"]["1"]["key2"]["3"] element value
echo $temp;
Sign up to request clarification or add additional context in comments.

14 Comments

after I see your answer, I understand that I didnt understand the question in the first place :(
@Bob0t would you tell how you understood my question at first? =)
@talsibony would you tell how you understood my question at first? =)
I thought that you are asking if you can access it in some kind of looping but without a recursion which was like a change question :)
$a[a][b][c]='123'; $b='a["a"]["b"]["c"]'; echo ${$b}; //outputs nothing
|
1

modifications after I got better understanding of the question I think you can do it with eval:

<?php

function getArrValuesFromString($string, $arr) {
  $stringArr = '$arr[\'' . str_replace('-', "']['", $string) . '\']';

  eval("\$t = " . $stringArr . ";");
  return $t;
}

$arr[5][1]['key2'][3] = '1here it is - 5-1-key2-3 key address';
$string = '5-1-key2-3';
echo getArrValuesFromString($string, $arr); //1here it is - 5-1-key2-3 key address

3 Comments

quite horibble approach =)\
LOL yes eval can be evil.. but this solution will work, and since Yasen Zhelev took the nice approach I left with the ugly one...
array keys come from outside (post or get). Could be dangerous
1

EDIT :

Here is a way I deprecate so much, because of security, but if you are sure of what you are doing :

$key = 'a-b-c-d';
$array = <<your array>>;
$keys = explode('-', $key);
// we can surely do something better like checking for each one if its a string or int then adding or not the `'`
$final_key = "['".implode("']['", $keys)."']";
$result = eval("return \$array{$final_key};");

There is a class I wrote inspired from something I read on the web don't really remember where but anyway, this can helps you :

/**
 * Class MultidimensionalHelper
 *
 * Some help about multidimensional arrays
 * like dynamic array_key_exists, set, and get functions
 *
 * @package Core\Utils\Arrays
 */
class MultidimensionalHelper
{
    protected $keySeparator = '.';

    /**
     * @return string
     */
    public function keySeparator()
    {
        return $this->keySeparator;
    }

    /**
     * @param string $keySeparator
     */
    public function setKeySeparator($keySeparator)
    {
        $this->keySeparator = $keySeparator;
    }



    /**
     * Multidimensional array dynamic array_key_exists
     *
     * @param $key      String Needle
     * @param $array    Array  Haystack
     * @return bool     True if found, false either
     */
    public function exists($key, $array)
    {
        $keys = explode($this->keySeparator(), $key);

        $tmp = $array;

        foreach($keys as $k)
        {
            if(!array_key_exists($k, $tmp))
            {
                return false;
            }

            $tmp = $tmp[$k];
        }

        return true;
    }

    /**
     * Multidimensional array dynamic getter
     *
     *
     * @param $key      String  Needle
     * @param $array    Array   Haystack
     * @return mixed    Null if key not exists or the content of the key
     */
    public function get($key, $array)
    {
        $keys = explode($this->keySeparator(), $key);
        $lkey = array_pop($keys);

        $tmp = $array;

        foreach($keys as $k)
        {
            if(!isset($tmp[$k]))
            {
                return null;
            }

            $tmp = $tmp[$k];
        }

        return $tmp[$lkey];
    }

    /**
     * Multidimensional array dynamic setter
     *
     * @param String    $key
     * @param Mixed     $value
     * @param Array     $array  Array to modify
     * @param Bool      $return
     * @return Array    If $return is set to TRUE (bool), this function
     *                  returns the modified array instead of directly modifying it.
     */
    public function set($key, $value, &$array)
    {
        $keys = explode($this->keySeparator(), $key);
        $lkey = array_pop($keys);

        $tmp = &$array;

        foreach($keys as $k)
        {
            if(!isset($tmp[$k]) || !is_array($tmp[$k]))
            {
                $tmp[$k] = array();
            }

            $tmp = &$tmp[$k];
        }

        $tmp[$lkey] = $value;

        unset($tmp);
    }
}

Then use :

$MDH = new MultidimensionalHelper();

$MDH->setKeySeparator('-');

$arr = [ 
    'a' => [
        'b' => [
            'c' => 'good value',
        ],
        'c' => 'wrong value',
    ],
    'b' => [
        'c' => 'wrong value',
    ]
];

$key = 'a-b-c';
$val = $MDH->get($key, $arr);

var_dump($val);

Here is the content of the get function if you don't find it in Class code :

public function get($key, $array)
{
    $keys = explode($this->keySeparator(), $key);
    $lkey = array_pop($keys);

    $tmp = $array;

    foreach($keys as $k)
    {
        if(!isset($tmp[$k]))
        {
            return null;
        }

        $tmp = $tmp[$k];
    }

    return $tmp[$lkey];
}

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.