extract()如何在当前作用域中创建变量?

时间:2014-10-07 19:43:19

标签: php variables extract

我很好奇,PHP的功能extract是如何工作的?我想做一个略微修改的版本。我希望我的函数在从数组的键中从snake表示法提取到camelCase时生成变量名,例如:

现在提取这样做:

$array = ['foo_bar' => 'baz'];
extract($array);
// $foo_bar = 'baz';

我想要的是:

camelExtract($array);
// $fooBar = 'baz';

现在我当然可以首先使用数组,但如果可以在单个函数中完成,那就太好了。

编辑:

似乎有些人误解了我的问题。是的,我可以这样做:

function camelExtract($array)
{
    $array = ['foo_bar' => 'baz'];
    $camelCased = [];
    foreach($array as $key => $val)
    {
        $camelCased[camelcase($key)] = $val;
    }
    extract($camelCased);
    // $fooBar = 'baz';


    // I can't "return" the extracted variables here 
    // .. now $fooBar is only available in this scope
}

camelExtract($array);
// Not here

但正如我所说,那么$ fooBar只能在该范围内可见。

我想我可以做extract(camelCaseArray($array));这样的事情。

4 个答案:

答案 0 :(得分:4)

这应该有效: -

function camel(array $arr)
{
    foreach($arr as $a => $b)
    {
    $a  = lcfirst(str_replace(" ", "", ucwords(str_replace("_", " ", $a))));
    $GLOBALS[$a] = $b;
    }
}

答案 1 :(得分:2)

您可以(谨慎地)使用variable variables

function camelExtract($vals = array()) {
    foreach ($vals as $key => $v) {
        $splitVar = explode('_', $key);
        $first = true;
        foreach ($splitVar as &$word) {
            if (!$first) {
                $word = ucfirst($word);
            }
            $first = false;
        }
        $key = implode('', $splitVar);
        global ${$key};
        ${$key} = $v;
    }
}

现在已经过测试,并且按预期运行。 This condensed answer(在它解决了小写的第一个单词之后)也很有效,并且更加浓缩 - 我只是一步一步“了解骆驼是如何完成的。”

答案 2 :(得分:1)

extract,从调用函数中修改 callees 本地符号表是不可思议的。没有使用它就无法在普通PHP中执行等效的操作。

使用John Conde建议在对提供的数组键执行转换后使用extra ,可以解决最终任务。虽然我的建议是完全避免类似提取行为。然后该方法看起来类似于

extract(camelcase_keys($arr));

这样的代码包装在一个函数中,以便从符号表的范围执行extract来导入变量。


extract行为变量变量(在被调用的函数中)不同,不同,使用$ GLOBALS,因为它会改变被调用者(和< em> only callees)符号表,如seen in this demo

function extract_container () {
    extract(array("foo" => "bar"));
    return $foo;
}

echo "Extract: " . extract_container() . "\n";  // "bar" =>
echo "Current: " . $foo . "\n";                 //       => {no $foo in scope}
echo "Global:  " . $GLOBALS['foo'] . "\n";      //       => {no 'foo' in GLOBALS}

extract的C实现可以在ext/standard/array.c中找到。这种行为是允许的,因为本机函数为自己创建一个新的/本地PHP符号表;因此,允许(通常)修改调用PHP上下文的符号表。

答案 3 :(得分:1)

    <?php
    $arr = array('foo_bar'=>'smth');
    function camelExtract($arr) {
        foreach($arr as $k=>$v) {
            $newName = lcfirst(str_replace(" ","",ucwords(str_replace("_"," ",$k))));
            global $$newName;
            $$newName = $v; 
            //var_dump($newName,$$newName);
        }
    }
    camelExtract($arr);
    ?>

或者就像(你建议的那样,最好是模仿原始提取物)

$camelArray[lcfirst(str_replace(" ","",ucwords(str_replace("_"," ",$k))))] = $v;

并在生成的camelArray上提取