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

Php 基于键将大型关联数组转换为局部变量,php,arrays,oop,Php,Arrays,Oop,我发现自己经常想做的一件事是将一个大的关联数组(通常是从POST请求(例如,具有许多输入的注册表单)转换为基于数组键的局部变量。如果经常使用数组中的值,代码很快就会被长变量名和引号弄得乱七八糟 为了防止小型关联数组出现这种情况,可以只执行以下操作: $username = $_POST['username']; $password = $_POST['password']; foreach($arr as $key => $value) { ${$key} = $value; }

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

为了防止小型关联数组出现这种情况,可以只执行以下操作:

$username = $_POST['username'];
$password = $_POST['password'];
foreach($arr as $key => $value)
{
    ${$key} = $value;
}
在这个例子中,我并不是为了让一切尽可能的整洁而逃避他们,所以放松点

您也可以这样做:

list($username, $password) = $_POST;
但是如果$u POST数组更大怎么办?然后,这两种方法都会变得单调乏味。要解决此问题,可以运行如下循环:

$username = $_POST['username'];
$password = $_POST['password'];
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


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

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

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

一项重要的增编:

如果函数作用于用户提供的变量名(如由
$\u POST提供的变量名),请确保使用
EXTR\u SKIP
选项来执行
extract()
,以防止重新定义现有变量:

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

这正是我需要的,谢谢。如果使用
EXTR\u SKIP
,似乎非常安全。你这么多年来一直在做PHP,却错过了这些基本功能,这真是太疯狂了。。。我需要开始更多地阅读手册。在我发现
extract()
之前,我已经编写了5年多的php代码。有很多模糊但强大的内置函数。