2012-04-01 15 views
9

我发现自己常常想要做的一件事是将大型关联数组(通常是从POST请求(注册表单,例如,具有多个输入))转换为局部变量基于数组中的键。如果您经常使用数组中的值,那么您的代码会很快变得乱七八糟,变量名称和引号很长。根据密钥将大型关联数组转换为局部变量

为了防止这种情况的小关联数组,这是可以接受的,只是做这样的事情:

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

我不是逃避他们在这个例子中,保持一切,整洁越好,这样放松。

你也可以这样做:

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

但如果$ _POST数组是更大吗?然后,执行这两种方法变得单调乏味。为了解决这个问题,你可以像这样运行一个循环:

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

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

$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)局部变量。

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

回答

17

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

http://us3.php.net/extract

一个重要的补遗:

要知道,如果是作用于用户提供的变量名称的功能(如提供使用EXTR_SKIP选项extract()$_POST)以防止重新定义现有变量:

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

这正是我所需要的,谢谢。如果你使用'EXTR_SKIP'似乎很安全。如果你这么做了PHP这么多年,并且错过了这些基本功能,我很疯狂......我需要更多地阅读这本手册。 – 2012-04-01 23:47:53

+1

我在发现'extract()'之前编写了php 5年以上的版本。有很多晦涩而强大的内置函数。 – leepowers 2012-04-01 23:49:21

1

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