【问题标题】:Converting large associative arrays into local variables, based on key基于键将大型关联数组转换为局部变量
【发布时间】:2012-04-15 16:35:46
【问题描述】:

我发现自己经常想做的一件事是将大型关联数组,通常从 POST 请求(例如,具有许多输入的注册表单)转换为基于数组中的键的局部变量。如果您经常使用数组中的值,您的代码很快就会充满长变量名和引号。

为了防止小型关联数组出现这种情况,可以这样做:

$username = $_POST['username'];
$password = $_POST['password'];

我不会为了这个例子而逃避它们,以保持一切尽可能整洁,所以请放松。

您也可以这样做:

list($username, $password) = $_POST;

但是如果 $_POST 数组更大怎么办?那么这两种方法都做起来很乏味。要解决这个问题,您可以运行如下循环:

foreach($arr as $key => $value)
{
    ${$key} = $value;
}

这个方法的问题是它分配了局部变量。如果可以在运行此循环的父类中调用函数并且可以在调用类中访问这些局部变量,那就太好了。想象一个 MVC 设置,其中每个控制器都派生自 Controller 类,模型也是如此。这样做会很好:

$this->localize($_POST);
doWhatever($username) // $username works! Assuming $_POST['username'] is defined

创建这样的方法会导致局部变量只保留在父类中localize() 函数的范围内,所以这不起作用。我一直在做的是通过一项修改运行相同的循环:

foreach($arr as $key => $value)
{
    $this->{$key} = $value;
}

这一切正常,但并不能真正解决最初的问题。它没有被括号和引号弄乱的代码,而是到处都是$this->,更不用说它正在分配从未在类中正式定义过的变量。

最后,我的问题是:是否可以创建一个函数,例如我描述的localize(),以便它可以从父类继承但创建相对于子类的局部变量($username 而不是$this->username)。

另外,不管你能不能,这是否被认为是不好的做法?对我来说这似乎有点 hacky,而且你忽略了 OOP 的一些原则。如果是,您是使用解决方案来解决大型关联数组的丑陋和混乱,还是只处理它?

【问题讨论】:

    标签: php arrays oop


    【解决方案1】:

    这是一种不好的做法,用户只需在 POST 数组中传递密钥就可以重新定义任何变量,这非常简单,这就是 register_globals 的工作原理,这就是为什么此功能在 5.3 中被弃用并在 5.4 中被删除的原因。

    【讨论】:

      【解决方案2】:

      PHP extract 函数正是这样做的。将哈希提取到本地命名空间中:

      http://us3.php.net/extract

      一个重要的附录:

      如果函数作用于用户提供的变量名(例如$_POST 提供的),请务必对extract() 使用EXTR_SKIP 选项,以防止重新定义现有变量:

      $myvar = 'abc';
      extract($_POST, EXTR_SKIP);  // $_POST['myvar'] won't overwrite $myvar.
      

      【讨论】:

      • 这正是我所需要的,谢谢。如果您使用EXTR_SKIP,这似乎很安全。做 PHP 这么多年却错过了这些基本功能,真是太疯狂了……我需要开始更多地阅读手册。
      • 在我发现 extract() 之前,我已经编写了 5 年以上的 php 代码。有很多不起眼但功能强大的内置函数。
      猜你喜欢
      • 2014-10-19
      • 2020-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-11
      • 2016-07-21
      相关资源
      最近更新 更多