4

I have an array $AR
I have a string "set[0][p1]"

When given this string, I need the best way to access the array at $AR['set'][0]['p1']

I have total control on that string, so I need not to worry from injections and stuff, and I can be sure it will be well formatted. There is no way I can put the p1 inside ' to be "set[0]['p1']"

2
  • Do you "control" that string? I.e. is it guaranteed to be "well-formed" and not to contain any malicious code? Commented Feb 12, 2010 at 15:27
  • This question is actually a rather fascinating one, and I'm totally planning on stealing it to make it an "interview question". Commented Feb 12, 2010 at 17:40

4 Answers 4

3

Check parse_str():

parse_str('set[0][p1]', $AR);

Oh, you want to access the index of the array... Here is my take:

getValue($AR, array('set', 0, 'p1'));

Or if you really must use the original string representation:

parse_str('set[0][p1]', $keys);
getValue($AR, $keys);

Disclaimer: I haven't tested this, you might need to use array_keys() somewhere.


And the helper function:

function getValue($array, $key, $default = false)
{
    if (is_array($array) === true)
    {
        settype($key, 'array');

        foreach ($key as $value)
        {
            if (array_key_exists($value, $array) === false)
            {
                return $default;
            }

            $array = $array[$value];
        }

        return $array;
    }

    return $default;
}

I would avoid regexing your way into this problem.

Sign up to request clarification or add additional context in comments.

3 Comments

@Felix: Yeah, I just realized that. Sorry! =o
With the current version the "magic part" would be to get from "set[0][p1]" to array(set,0,p1) if the op wants to stick to the original plan ;)
parseString will give you Array([set] => Array([0] => Array([p1]=>))), not a flat array. I would say the easiest way is to use preg_split (like in my answer ;))
3

My try, which should be able to deal with an arbitrary amount of []s in the string:

To split the string you can use preg_split.

$parts = preg_split('%\[?(\w+)\]?%', $string, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

(More) complete code:

function get_value($string, $array) {
    $parts = preg_split('%\[?(\w+)\]?%', $string, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

    foreach($parts as $part) {
        $array = $array[$part];
    }

    return $array;
}

$array = array('set'=>array(array('p1'=>'foo')));
$string = "set[0][p1]";

echo get_value($string, $array); // echoes 'foo'

I leave the error handling to you ;)

Comments

2

Perhaps this is crazy, but have you considered extract? It may not be the fastest solution, but it has the novelty of needing minimal code.

extract( $AR );
$target = eval("\$set[0]['p1']");

The major difference (as far as input is concerned) is that you would need to pre-pend '$' to the string, and make sure that the brackets have quote marks inside.

The major benefit is that it becomes extraordinarily obvious what you're trying to accomplish, and you're using two native PHP functions. Both of these mean that the solution would be far more "readable" by those unfamiliar with your system.

Oh, and you're only using two lines of code.

Comments

0

You need something like. I'm not 100% about the "[" and "]" brackets as I've never had to run a regex on them before... if it's wrong can someone correct me??

foreach(preg_split('/[\[\]]/', "set[0][p1]") as $aValue) {
    $AR[$aValue[0]][$aValue[1]][$aValue[2]] = '?';
}

1 Comment

Your regex will give this: Array([0] => set,[1] => 0,[2] =>,[3] => p1,[4] =>)

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.