当前位置:  开发笔记 > 编程语言 > 正文

在PHP中模拟命名函数参数,有什么好主意?

如何解决《在PHP中模拟命名函数参数,有什么好主意?》经验,为你挑选了3个好方法。

如果我编写这样的函数,可以在PHP中模拟命名函数参数

function pythonic(array $kwargs)
{
    extract($kwargs);
    // .. rest of the function body
}

// if params are optional or default values are required
function pythonic(array $kwargs = array('name'=>'Jon skeet'))
{
    extract($kwargs);
    // .. rest of the function body
}

除了在IDE中失去intellisense之外,这种方法的其他可能缺点是什么?

编辑:

安全性:在这种情况下,安全性不应该是非问题,因为提取的变量仅限于功能范围吗?



1> nickf..:

我建议使用关联数组来传递命名参数,但是将它们保存在数组中而不提取它们.

function myFunc(array $args) {
    echo "Hi, " . $args['name'];
    // etc
}

这有几个原因.看一下这个函数,你可以清楚地看到我指的是传递给函数的一个参数.如果你提取它们,并且没有注意到extract()你(或下一个人)会在那里挠头,想知道这个$name"变量"来自哪里.即使你确实知道你正在提取局部变量的参数,它仍然是一定程度的猜谜游戏.

其次,它确保其他代码不会覆盖args.您可能已编写你的函数只能期待有命名参数$foo$bar,所以在你的其他代码,定义$baz = 8;,例如.稍后,您可能希望扩展您的函数以获取一个名为"baz"的新参数,但忘记更改其他变量,因此无论在参数中传递什么,$baz都将始终设置为8.

使用数组也有一些好处(这些同样适用于在数组中提取或保留的方法):您可以在每个函数的顶部设置一个变量$defaults:

function myFunc (array $args) {
    $default = array(
        "name" => "John Doe",
        "age" => "30"
    );
    // overwrite all the defaults with the arguments
    $args = array_merge($defaults, $args);
    // you *could* extract($args) here if you want

    echo "Name: " . $args['name'] . ", Age: " . $args['age'];
}

myFunc(array("age" => 25)); // "Name: John Doe, Age: 25"

您甚至可以删除$args没有相应$default值的所有项目.这样您就可以确切地知道您拥有哪些变量.


处理它的好方法.我很遗憾在写完之前没有读你的答案.

2> Mario..:

这是你可以做到的另一种方式.

/**
 * Constructor.
 * 
 * @named string 'algorithm'
 * @named string 'mode'
 * @named string 'key'
 */
public function __construct(array $parameter = array())
{
    $algorithm = 'tripledes';
    $mode = 'ecb';
    $key = null;
    extract($parameter, EXTR_IF_EXISTS);
    //...
}

使用此设置,您将获得默认参数,您不会丢失IDE中的智能感知,EXTR_IF_EXISTS只需提取已存在为变量的数组键即可使其安全.

(顺便说一下,从你提供的例子中创建默认值并不好,因为如果提供的param数组没有'name'索引,那么你的默认值就会丢失.)



3> Peter Bailey..:

根据我的经验,如果两件事之一成立,这种方法真的很有用

    无论什么减数原因,你的论证签名都很大.我最后以6为最高 - 不是出于任何具体原因,虽然看似正确 - 但我承认这个数字是任意的.

    您的所有或许多参数都是可选的,有时您只需要为第5个或某些此类事物设置值.这写起来很烦人someFunc( null, null, null, null, 1 );

如果其中任何一个对您来说都是正确的,那么使用关联数组伪装名称params可能是正确的实现.除了知道何时避免提取(或完全避免提取),我不能立即想到其他缺点.

话虽如此,这些问题通常也可以通过重构来解决.

推荐阅读
小妖694_807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有