代码之家  ›  专栏  ›  技术社区  ›  StevieD

有没有一个方便的函数或PHP函数可以将关联数组值转换为单个变量?

php
  •  0
  • StevieD  · 技术社区  · 4 年前

    我发现自己经常想做的一件事是,根据数组中的键,将一个大型关联数组(通常来自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 )。

    此外,不管你能不能,这是否被认为是一种糟糕的做法?这在我看来有点古怪,而且你忽略了OOP的一些原则。如果是的话,你是用一个解决方案来修复大型关联数组的丑陋和混乱,还是只处理它?

    0 回复  |  直到 14 年前
        1
  •  22
  •   leepowers    14 年前

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

    http://us3.php.net/extract

    一个重要的附录:

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

    $myvar = 'abc';
    extract($_POST, EXTR_SKIP);  // $_POST['myvar'] won't overwrite $myvar.
    
        2
  •  1
  •   OZ_    14 年前

    这是一种糟糕的做法,用户只需在POST数组中传递密钥就可以重新定义任何变量,这很简单,也是register_globals的工作方式,这就是为什么5.3中不推荐使用这种功能,5.4中删除了这种功能。

    推荐文章