3

I want to pass a function the index value of an array – e.g [‘client_name’] – a first level value works because I can do

        $index = client_name;

        function arraything ($index) { return $this->arraytolookat[$index]; }

The question is… how do I do this, if it’s a multi nested array?

I tried the eval statement and apparently it doesn’t evaluate brackets well … So I tried this.

        $index = “[0][‘client_name’]”;

        Eval(“$this->arraytolookat$index”);

But it just fails… winges about a unexpected [ - any Ideas?

EDIT: I do not know how many levels this function may be required to go into, therefore I cannot just append a set amount of brackets at the end. Its not as simple as it looks ^^

EDIT 2: Basically - I have written a form validation tool and one of the functions returns correct post data - I wanted a simple method that when you enter the name of the form element - it would literally return teh POST data back to the element e.g getFormData("client_name") - however when a form gets more complex, it can go into arrays, I need to prepare for the possibility of getFormData("['$i']client_name") or somthing along those lines, stuff happens to the postdata in that class so that function must be used. I just want that function to take in a string not an array.

2
  • Whats the matter with function xy ($a, $b) { return $this->array[$a][$b]; }? Commented Mar 28, 2011 at 11:24
  • Sorry I should of said... I don't know how many levels down the function may be required to go. So I cannot assume the amount of brackets that may be needed. Commented Mar 28, 2011 at 11:26

5 Answers 5

10

You can pass an array of indexes to this function below. So if you would like to get $some_array[0]['client_name']['third_level_index'] then you can do this:

function get_array_value(array $array, array $indexes)
{
    if (count($array) == 0 || count($indexes) == 0) {
        return false;
    }

    $index = array_shift($indexes);
    if(!array_key_exists($index, $array)){
        return false;
    }

    $value = $array[$index];
    if (count($indexes) == 0) {
        return $value;
    }

    if(!is_array($value)) {
        return false;
    }

    return get_array_value($value, $indexes);
}

$some_array = array(/* nested array */);

$indexes = array(0, 'client_name', 'third_level_index');

$value = get_array_value($some_array, $indexes);
Sign up to request clarification or add additional context in comments.

2 Comments

Spot on. Never would of thought of that. Simples!
@Vic Imi Borbas What if need to write at that position? This is returning the value for some dynamically passed key. What if I need to modify the data at that key?
5
function arraything ($arrayOfIndexes) {
  $current = $this->array;
  foreach ($arrayOfIndexes as $curIndex) {
    $current = $current[$curIndex];
  }
  return $current;
}

$x = arraything (array(0, 'client_thing'));

There is no validation (e.g. for missing keys), but the idea should be clear.

5 Comments

you could add a validation like if(!is_array($current)){ return $current; }
Yes. And with array_key_exists() that should do the job. I omit it to make the code snippet more compact. :)
Sorry, I cant see how that will go down multiple levels? Is each array element part of the key index?
Thats just the iterative variant of Imi Borbas (see below) recursion. | You dont have one key index, you have multiple (because you want to go multiple levels down ;)). The parameter is an ordered array of the keys (see the example and compare it with your one from the question).
Thank you, I voted Lmi borbas as the answer becuase I can figure out what its doing in my head easier than your example - however if its doing exactly the same as your's then thank you for your help :-) I voted you up. Cheers
2

The get_array_value function works well. So I also wrote up a set_array_value function.

Here it goes:

function get_array_value($array, $indexes)
{
  if (count($indexes) == 1)
  {
    return $array[$indexes[0]];
  }

  $index = array_shift($indexes);
  return get_array_value($array[$index], $indexes);
}

function set_array_value(&$array, $indexes, &$value)
{
  if (count($indexes) == 1)
  {
    return $array[reset($indexes)] = $value;
  }

  $index = array_shift($indexes);
  return set_array_value($array[$index], $indexes, $value);
}

$some_array = array();
$some_array[0]['client_name']['id'] = 1;
$some_array[1]['client_name']['id'] = 2;

$indexes = array(0, 'client_name', 'id');
$value = get_array_value($some_array, $indexes);
print_r($value);

$id = 23;
set_array_value($some_array, $indexes, $id);
$value = get_array_value($some_array, $indexes);
print_r($value);

Hope it helps :-)

:Nirav

Comments

0
$first = arraything(0);

echo $first['client_name'];

It sounds like you are trying to overload too much onto that argument. Can it be rewritten to allow this in a neater fashion? You could return this directly...

$this->arraytolookat[0]['client_name'];

Some frameworks have a helper function to access array members with an operator such as . (in a string of course).

2 Comments

Sorry I should of said... I don't know how many levels down the function may be required to go.
Basically - I have written a form validation tool and one of the functions returns correct post data - I wanted a simple method that when you enter the name of the form element - it would literally return teh POST data back to the element e.g getFormData("client_name") - however when a form gets more complex, it can go into arrays, I need to prepare for the possibility of getFormData("['$i']client_name") or somthing along those lines, stuff happens to the postdata in that class so that function must be used.
0

have tried the foreach loop, i am not sure if its the best solution. goes something like this

foreach($array as $key => $value){
   arraything ($key);
}

or use the array_keys() function

2 Comments

welcome to StackOverflow. I've edited your answer to reflect the code parts better. You can roll it back if you so wish by clicking on 'edited x time ago'.
Im trying to achieve this method only using a string not an array.

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.