4

I am trying to extract a mixed associative array like:

<pre>
        <?php


        bar();

        function bar(){
            $apple = 6;
            $ball = 2;
            $cat = 3;

            $data = ["apple" => 1, $ball,$cat];

            foo($data);
        }

        function foo($data){
            extract($data);
            echo "<br />apple:" . $apple;
            echo "<br />ball:" . $ball;
            echo "<br />cat:" .  $cat;
        }

        ?>
</pre>

The $data array can be only numeric, only associative or both. If element of array misses an index, it should be same as the variable.

5
  • @Andrew, No. Array can sometimes only associate or numeric. They are mixed to any level. Commented Nov 3, 2015 at 17:04
  • $ball and $cat are defined in scope (before extract) and thus they still exist. This is why they do not work in function. The Array has no index to assign to the variable when running extract. . Commented Nov 3, 2015 at 17:05
  • RTFM -> extract creates variables using the keys as variable names, and the values as... erm... values. In your first snippet, it just so happens that $cat and $ball have the same value as keys 0 and 1 in the array, but extract is actually skipping the numeric indexes Commented Nov 3, 2015 at 17:10
  • If it's not scope, that means your data is bad to use for extract(). Iterate your Array and collect the data manually into variable instead of using extract() to ensure you get the values. Commented Nov 3, 2015 at 17:11
  • @tika Why must there be numeric keys ? Can't you force the array to be as you wish ? How will you know that $data[0] is the value of $ball if the name is not in the key ? If you have no control on $data, you may have to get a mapping array, saying what is the variable order expected... in order to say "1st value is APPLE, 2nd will be BALL, and 3rd will be CAT"... and then use this mapping array to extract data manually... Commented Nov 3, 2015 at 17:22

2 Answers 2

7

This does not work in your function because $ball and $cat are not defined in the function scope. The extract() function will only assign the value to a variable if the value in the array has a key, which $apple does. This means that $apple will output in the function, but $ball and $cat would be undefined.

This happens because in order for extract() to know what to name the variable, there has to be a key in the array.

To do this, you either need to manually specify the keys in the array each time:

$apple = 6;
$ball = 2;
$cat = 3;
$data = ["apple" => $apple, "ball" => $ball, "cat" => $cat];

// Now, extracting from $data creates the variables we need...
// Unsetting the $apple, $ball, and $cat variables 
// allows us to see that extract is recreating them.
unset($apple, $ball, $cat);
extract($data);
echo $apple, $ball, $cat;

Or you need to check the $ball and $cat variables to see if they are arrays. If they are arrays, you could use their key in the array so that extract() knows what to name the variable it creates. Do you need to dynamically determine if a variable already has a key (is an array), or is this enough?

EDIT: This should not be done with extract(). Realistically, you should create a class and store this data within a class. Then, loading the class would give you this information. extract() is a dangerous and messy beast.

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

9 Comments

Good point to unset variables, to understand what happens... ! Without "ball" and "cat" keys in $data, this code wouldn't work !
@Random: Not unless you prefix the values you're extract-ing
@MikelBitson, the data is mixed array and will be.
@tika Do you understand why you'll never get a variable $ball out of an array that doesn't ever have the word "ball" in it? If the data is mixed, we need to see what format the data is coming in to determine how we can add that key. The key HAS* to be added for extract to work. So- if the key is coming with the $ball var we need to see how that will be formatted to correctly add it to the $data array in a way that will give us the "ball" key. Check your variable with is_array() and depending on the return, manually add the key or use the key from the variable.
@MikelBitson, Oh yeah. I now get it. It's quite impossible.
|
0

An alternate answer. The point is still the same, if you have an Array of mixed content, don't use extract().

function foo($data){
    extract($data);
    echo "<br />apple:" . (isset($apple)?$apple:$data[0]);
    echo "<br />ball:" . (isset($ball)?$ball:$data[1]);
    echo "<br />cat:" .  (isset($cat)?$cat:$data[2]);
}

You can see the pitfalls here. If data has more or less indexes, or the order is not correct, you will get a failed index or incorrect value.

2 Comments

Problem is I have no idea what is coming, apple, ball, plane ... :(
Any way to format the data? How is the data being presented to you?

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.