PHP - 提取关联数组

4
我将尝试提取一个混合的关联数组,例如:
<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>
< p > $data 数组可以是纯数字的、纯关联的或两者都有。如果数组元素缺少索引,则应该与变量相同。


@Andrew,不是的。数组有时只能关联或数字。它们可以混合到任何级别。 - tika
$ball$cat 在作用域中已经被定义(在 extract 之前),因此它们仍然存在。这就是为什么它们在函数中无法工作的原因。当运行 extract 时,数组没有索引可以分配给变量。 - Twisty
RTFM -> extract 通过使用键作为变量名和值作为...嗯...值来创建变量。在您的第一个片段中,碰巧$cat$ball的值与数组中的键01相同,但是extract实际上跳过了数字索引。 - Elias Van Ootegem
如果不是作用域的问题,那么这意味着你的数据不能用于 extract()。迭代数组并手动收集数据到变量中,而不是使用 extract() 来确保你获得值。 - Twisty
@tika 为什么必须要数字键?难道不能强制数组按照你的意愿来排列吗?如果名字不在键中,你怎么知道 $data[0] 是 $ball 的值?如果对 $data 没有控制权,你可能需要获取一个映射数组,说明期望的变量顺序是什么...例如,“第一个值是APPLE,第二个是BALL,第三个是CAT”...然后使用这个映射数组手动提取数据... - Random
2个回答

7
在您的函数中,这并不起作用,因为$ball和$cat在函数范围内未定义。extract()函数只会为具有键的数组值分配变量。而$apple存在键,因此可以在函数中输出它,但$ball和$cat将未定义。
这是因为要使extract()知道如何命名变量,必须在数组中有键。
要做到这一点,您需要每次手动指定数组中的键:
$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;

或者你需要检查$ball和$cat变量是否为数组。如果它们是数组,你可以使用数组中的键(key)来命名extract()创建的变量。您需要动态确定变量是否已经具有键(是一个数组),或者这已经足够了吗?
编辑: 不应该使用extract()来完成此操作。实际上,你应该创建一个类并将这些数据存储在类内部。然后,加载类将为您提供这些信息。extract()是一个危险而混乱的工具。

好的习惯是取消变量,以便了解发生了什么...!如果$data中没有"ball"和"cat"键,这段代码将无法工作! - Random
@tika 你明白为什么从一个没有包含单词“ball”的数组中永远无法获取变量$ball吗?如果数据是混合的,我们需要查看数据以确定如何添加该键。必须添加该键才能使提取工作正常。因此,如果键与$ball变量一起出现,我们需要查看它将如何格式化以正确将其添加到$data数组中,以便为我们提供“ball”键。使用is_array()检查您的变量,并根据返回值手动添加键或使用变量中的键。 - Mikel Bitson
@MikelBitson,哦,是的。我现在明白了。这很“不可能”。 - tika
@tika 如果你想在变量只是数字时始终使用变量名,那并不是不可能的。你可以通过检查变量是否为数字(is_numeric())来手动添加键。无论哪种方式,键都必须存在。 - Mikel Bitson
如果您绝对不能更改bar()函数,那么您能否假设它们添加到数组中的顺序始终相同?在这种情况下,您可以在函数中创建一个引用数组,并根据顺序手动假定键。如果排序可能会更改,则这不是一个选项,您无法提取变量名而不添加它。这可以像Twisty在他的答案中指出的那样完成-只需引用数组中的索引并创建自己的变量即可。 - Mikel Bitson
显示剩余4条评论

0

另一种答案。重点仍然是相同的,如果您有一个混合内容的数组,请不要使用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]);
}

你可以在这里看到陷阱。如果数据的索引数量多了或少了,或者顺序不正确,你将会得到一个失败的索引或错误的值。


问题是我不知道接下来会出现什么,苹果、球、飞机... :( - tika
有什么方法可以格式化数据吗?数据以什么形式呈现给你? - Twisty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接