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.

Jonathan Tizard
  • 229
  • 1
  • 4
  • 15
  • Whats the matter with `function xy ($a, $b) { return $this->array[$a][$b]; }`? – KingCrunch Mar 28 '11 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. – Jonathan Tizard Mar 28 '11 at 11:26

5 Answers5

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);
Mohamed E.
  • 333
  • 4
  • 8
Imi Borbas
  • 3,683
  • 1
  • 19
  • 16
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.

KingCrunch
  • 128,817
  • 21
  • 151
  • 173
  • you could add a validation like if(!is_array($current)){ return $current; } – mjspier Mar 28 '11 at 11:38
  • Yes. And with `array_key_exists()` that should do the job. I omit it to make the code snippet more compact. :) – KingCrunch Mar 28 '11 at 11:51
  • Sorry, I cant see how that will go down multiple levels? Is each array element part of the key index? – Jonathan Tizard Mar 28 '11 at 12:07
  • 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). – KingCrunch Mar 28 '11 at 12:11
  • 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 – Jonathan Tizard Mar 28 '11 at 13:29
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

Per Quested Aronsson
  • 11,380
  • 8
  • 54
  • 76
Nirav Mehta
  • 193
  • 1
  • 3
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).

alex
  • 479,566
  • 201
  • 878
  • 984
  • Sorry I should of said... I don't know how many levels down the function may be required to go. – Jonathan Tizard Mar 28 '11 at 11:26
  • 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. – Jonathan Tizard Mar 28 '11 at 11:33
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

Decent Dabbler
  • 22,532
  • 8
  • 74
  • 106
Opad
  • 96
  • 1
  • 5