extract()有什么问题?

bar*_*oon 33 php arrays extract

我最近在一些最糟糕的PHP实践中阅读了这个主题.在第二个答案中,有一个关于使用的小型讨论extract(),我只是想知道所有的愤怒是什么.

我个人用它砍了给定阵列,如$_GET$_POST在那里我后来消毒变量,因为他们已经命名的便利,为我.

这是不好的做法吗?这有什么风险?您对使用extract()有何看法?

nic*_*ckf 64

我发现这只是一种不好的做法,因为它可能导致许多变量,未来的维护者(或者你自己在几周内)不知道他们来自哪里.考虑这种情况:

extract($someArray); // could be $_POST or anything

/* snip a dozen or more lines */

echo $someVariable;
Run Code Online (Sandbox Code Playgroud)

$someVariable来自哪里?谁能说出来?

我没有看到这个问题,从他们开始在阵列中访问的变量,所以你真的需要展示一个良好的情况下,使用extract()我认为这是值得的.如果您真的担心输入一些额外的字符,那么就这样做:

$a = $someLongNameOfTheVariableArrayIDidntWantToType;

$a['myVariable'];
Run Code Online (Sandbox Code Playgroud)

我认为这里关于它的安全方面的评论有些过分夸大了.该函数可以采用第二个参数,实际上可以很好地控制新创建的变量,包括不覆盖任何现有变量(EXTR_SKIP),仅覆盖现有变量(因此可以创建白名单)(EXTR_IF_EXISTS),或者为变量添加前缀(EXTR_PREFIX_ALL).


dr *_*ter 38

来吧吧.人们责怪工具而不是用户.

这就像是在讨论,unlink()因为你可以用它删除文件.extract()是一个像任何其他功能,明智和负责任地使用它.但是不要声称它本身是坏事,那只是无知.

  • 不幸的是,有时明智地使用某些东西的唯一方法就是不使用它. (13认同)
  • @DanLugg,有时是使用建议的唯一方法*"有时唯一的方法是明智地使用它是不使用它"*明智的是不使用它. (5认同)
  • @DanLugg,尝试以这种方式“修复”遗留代码是**极其危险的**,尤其是当它们不是由您编写时。事实上,我上面的解决方案是“修复”遗留代码的最干净的方法。我们所需要的只是在该函数之上使用“extract”的额外构面模式。不仅最干净,而且最便宜(例如,每月 2000 美元降至每小时 10 美元),而且万无一失。是否还有比我上面提到的解决方案更清洁**或更便宜**或更防故障的替代解决方案? (2认同)

ste*_*efs 17

风险在于:不信任来自用户的数据,并提取到当前符号表中意味着,您的变量可能会被用户提供的内容覆盖.

<?php
    $systemCall = 'ls -lh';
    $i = 0;

    extract($_GET);

    system($systemCall);

    do {
        print_r($data[$i];
        $i++;
    } while ($i != 3);

?>
Run Code Online (Sandbox Code Playgroud)

(一个荒谬的例子)

但现在是猜测或知道代码调用的恶意用户:

yourscript.php?i=10&systemCall=rm%20-rf
Run Code Online (Sandbox Code Playgroud)

代替

yourscript.php?data[]=a&data[]=b&data[]=c
Run Code Online (Sandbox Code Playgroud)

现在,$ systemCall和$ i被覆盖,导致您的脚本首先删除您的数据然后挂起.

  • 你可以使用EXTR_SKIP来避免这种情况. (4认同)

Jam*_*mol 9

没有什么问题.否则就不会实施.当您向视图传递(赋值)变量时,许多(MVC)框架都会使用它.你只需要仔细使用它.在将这些数组传递给extract()之前清理它们并确保它不会覆盖您的变量.别忘了这个函数还接受了一些参数!如果发生碰撞,使用第二个和第三个参数可以控制行为.您可以覆盖,跳过或添加前缀. http://www.php.net/extract

  • "它没有任何问题.否则就无法实现.".......... [`goto`](http://us1.php.net/goto),[魔术引号](http ://www.php.net/manual/en/security.magicquotes.php). (14认同)

Sea*_*ney 6

如果不小心使用,可能会使你工作的其他人感到困惑:

<?php

    $array = array('huh' => 'var_dump', 'whatThe' => 'It\'s tricky!', 'iDontGetIt' => 'This Extract Function');
    extract($array);
    $huh($whatThe, $iDontGetIt);


?>
Run Code Online (Sandbox Code Playgroud)

产量:

string(12) "It's tricky!"
string(21) "This Extract Function"
Run Code Online (Sandbox Code Playgroud)

在混淆中使用会很有用.但我无法克服"变量来自哪里?" 我遇到的问题.


kar*_*m79 5

我想很多人不推荐使用它的原因是提取$_GET$_POST(甚至$_REQUEST)超全局变量在全局命名空间中注册变量与这些数组中的每个键同名,这基本上是模拟 REGISTER_GLOBALS = 1。


小智 5

人们对提取物全部掌握,因为它有可能被误用.做任何类似提取($ _ POST)的事情在任何情况下都不是一个好主意,即使你知道你在做什么.但是,当您执行诸如将变量暴露给视图模板或类似的东西时,它确实具有它的用途.基本上,只有当你非常确定你有充分的理由这样做时才使用它,并且如果你想要把像$ _POST这样疯狂的东西传递给它,那么就要明白如何使用extract类型参数.