1

The goal is to pass a specific array element through custom_format().

Example: If $hierarchy = '4:0:2', then $data[4][0][2] = custom_format($data[4][0][2]).

Does anyone know how to replicate the following code without relying on eval()?

Current code:

$hierarchy = '4:0:2';
$hierarchy = str_replace(':', '][', $hierarchy);
eval("\$data[$hierarchy] = custom_format(\$data[$hierarchy]);");

Thanks in advance.

3
  • See the code from this answer to retrieve the value from multidimensional array. It uses dot-separated keys (e.g: 4.0.2), but you can easily change it to :. Commented Jun 27, 2012 at 15:02
  • That example will only retrieve a value. I'm trying to actually replace a specific value within a multidimensional array. Commented Jun 27, 2012 at 15:07
  • Thanks for the help guys. It looks like this thread also has some relevant answers: stackoverflow.com/questions/7851590/… Commented Jun 27, 2012 at 16:14

2 Answers 2

2

An overly verbose yet elegant option is the following:

class MyArray implements ArrayAccess {
    public function offsetExists($offset) {
        if(!is_array($offset))
            $offset = explode(':', $value);
        $key = array_shift($offset);
        if($key !== NULL) {
            if($this->$key InstanceOf MyArray) {
                return(isset($this->$key[$offset]));
            }
        }
    }
    public function offsetGet($offset) {
        if(!is_array($offset))
            $offset = explode(':', $value);
        $key = array_shift($offset);
        if($key !== NULL) {
            if($this->$key InstanceOf MyArray) {
                return($this->$key[$offset]);
            }
        }
    }
    public function offsetSet($offset, $value) {
        if(!is_array($offset))
            $offset = explode(':', $value);
        $key = array_shift($offset);
        if($key !== NULL) {
            if(!($this->$key InstanceOf MyArray)) {
                $this->$key = new MyArray;
            }
            $this->$key[$offset] = $value;
        }
    }
    public function offsetUnset($offset) {
        if(!is_array($offset))
            $offset = explode(':', $value);
        $key = array_shift($offset);
        if($key !== NULL) {
            if($this->$key InstanceOf MyArray) {
                return(unset($this->$key[$offset]));
            }
            if(count($offset) == 0) {
                return(unset($this->$key));
            }
        }
    }
}

This does imply using MyArray everywhere you need this kind of array behaviour and perhaps creating a static method that recursively converts arrays and they array children into MyArray objects so that they will respond consistently to this behavior.

One concrete example is the need to change the offsetGet method, to check if $value is an array then to use the conversion function to convert it to a MyArray if you want to access its elements.

0

How about something like this:

<?php
$hierarchy = '4:0:2';
list($a,$b,$c) = explode(':',$hierarchy);
echo $data[$a][$b][$c];
?>
6
  • No, sorry I didn't clarify -- assume that $data can have more than 3 dimensions. Commented Jun 27, 2012 at 15:03
  • @Jamie actually assume that $data can have any number of dimensions. Commented Jun 27, 2012 at 15:19
  • In that case, I can't see any other way than to loop through each of your elements and do an IF on each one until all the keys match up, then do you replace when they all match. Not exactly efficient, but in all honesty, what are you going to do with the array if you don't know how many depths it has? Commented Jun 27, 2012 at 15:25
  • We know exactly what depth we need by the $hierarchy string. Commented Jun 27, 2012 at 15:35
  • @Matt What Jaimie meant was if we don't know the exact depth at compile time as opposed to run time. Commented Jun 27, 2012 at 15:36

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.