基于键将大关联数组转换为局部变量

时间:2012-04-01 23:30:41

标签: php arrays oop

我发现自己经常要做的一件事是将一个大的关联数组转换为基于数组中的键的局部变量,通常是从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(),这样它可以从父类继承,但是创建相对于子类的局部变量({{1而不是$username)。

此外,无论你能否,这被认为是不好的做法?对我来说这似乎有些苛刻,你忽略了OOP的一些原则。如果是,你是否使用解决方案来修复大型关联数组的丑陋和混乱,或者你只是处理它?<​​/ p>

2 个答案:

答案 0 :(得分:17)

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

http://us3.php.net/extract

一个重要的附录:

如果函数对用户提供的变量名称(例如由EXTR_SKIP提供)起作用,请确保对extract()使用$_POST选项,以防止重新定义现有变量:< / p>

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

答案 1 :(得分:1)

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