Php extract()如何在当前范围内创建变量?

Php extract()如何在当前范围内创建变量?,php,variables,extract,Php,Variables,Extract,我很好奇,PHP函数是如何工作的?我想做一个稍微修改的版本。我想让我的函数在从snake notation到camelCase的数组键中提取时生成变量名,例如: 现在,extract执行以下操作: $array = ['foo_bar' => 'baz']; extract($array); // $foo_bar = 'baz'; 我想要的是: camelExtract($array); // $fooBar = 'baz'; 现在我当然可以首先对数组进行camelCase,但是如果

我很好奇,PHP函数是如何工作的?我想做一个稍微修改的版本。我想让我的函数在从snake notation到camelCase的数组键中提取时生成变量名,例如:

现在,extract执行以下操作:

$array = ['foo_bar' => 'baz'];
extract($array);
// $foo_bar = 'baz';
我想要的是:

camelExtract($array);
// $fooBar = 'baz';
现在我当然可以首先对数组进行camelCase,但是如果可以在单个函数中完成这项工作,那就太好了

编辑:

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

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))这样就行了

这应该有效:-

function camel(array $arr)
{
    foreach($arr as $a => $b)
    {
    $a  = lcfirst(str_replace(" ", "", ucwords(str_replace("_", " ", $a))));
    $GLOBALS[$a] = $b;
    }
}
,并且从被调用函数中修改被调用方的本地符号表非常神奇。如果不使用它,就无法在普通PHP中执行等效操作

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

extract(camelcase_keys($arr));
其中,此类代码未包装在函数中,以便从要导入变量的符号表的范围中执行
extract


提取
行为与变量(在被调用函数中)不同,也与使用$GLOBALS不同,因为它变异了被调用方(仅被调用方)符号表,如所示:

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

您可以(谨慎地)使用:

现在已经对其进行了测试,其功能与预期一致。(在它提到小写字母的第一个单词后)也很有效,而且更加简洁——我的工作只是“一步一步”地完成骆驼的工作

    <?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上进行提取

因此,请创建自己的函数来执行此操作。这并不是什么神奇的事情,它的代码通过循环camcel case启动您的函数。数组kets然后在末尾调用extart()。就这些,我想我明白你的意思了。extract()的唯一性在于它能够以某种方式获得当前作用域的句柄,并在没有显式赋值的情况下对其进行操作。很抱歉,我不知道还有任何其他函数可以做到这一点,也不知道如何将您自己的函数连接到该功能,而不将其包装为extract。有相关的get_defined_vars和compact,但我认为它们对您没有帮助。我的意思是,我认为让变量神奇地出现在您的范围内,无论是提取还是其他方式,对于可维护性来说可能不是一个好主意,但关于摘录的独特性,这是一个有趣的观点。除了另一个答案,没有办法。这就是我所想的,在我看来,唯一理解这个问题的人被修改了。奇怪的是,这里似乎有可能出现变量。但是,您是否仍然需要指出,这些变量仅在cameleextract范围内可见?如果使用extract,则情况并非如此。在调用它的范围内创建新变量。不是它自己的作用域。@Matthijn我已经做了一次编辑,使用
全局
声明解决了这个问题,这可能确实有效,但据我所知,extract不会污染全局作用域。但这是一个紧密的复制,具有全局作用域污染。是的,但这里的新变量仅在camelExtract函数作用域中可用。Extract在调用它的作用域中创建这些变量。在这里,它们在当前作用域之外可用。但我不认为这是全球范围内的项目。效果(大部分)是一样的。但是现在,即使调用“camel”的方法完成了,这些变量也会“浮动”。如果您希望它是这样的,您可以使用以下命令:-
函数camel(数组$arr){foreach($arr as$a=>$b){$a=lcfirst(str_replace(“,”,ucwords(str_replace(“,”,“,$a));${$a}=$b;}
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;
    }
}
    <?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;