2009-06-15 69 views
11

偶尔我会用一个输入写一个PHP函数,一个包含所有函数输入的关联数组。这有好处,例如不必记住正确的输入顺序,但我也注意到它使得对大型代码库的实现更容易得多;当我需要添加另一个变量,并且该变量必须通过4个或5个预先存在的函数时,当我可以将它粘贴到数组中并传递时,它会更容易。使用关联数组作为php函数的输入

我的问题是,这样做有缺点吗?

我很少看到函数用这种方式写在例子中,或者在我使用的开源中,这使我相信可能存在一个缺点。如果不是是不这样做的原因,那么为什么不用这种方式编写所有函数呢?

UPDATE

感谢您的答案。它看起来像两大问题最为突出:

代码的可读性 - 不可能知道什么变量进入一个功能,他们是为了什么

变蠕变 - 可能进行大规模的阵列反弹拉闸从一个功能到另一个功能;不应该将参数传递给不需要它们的函数

哪些都是我没有想到的伟大点。

看来一般的要点是代码在哪里这是一个问题,应该可能转换为一个类。不幸的是,在这个特定的项目中,这样的重构已经超出了范围,但我也认为比尔卡尔文的解决方案非常好 - 通过一系列可选变量

+0

出于兴趣你可以发布你会写一个例子功能? :) – 2009-06-15 17:08:30

+0

@沙迪 - 更像“出于病态的好奇心”? :) – 2009-06-15 17:20:51

+1

所以不是 功能myFunc的($ VAR1,$ VAR2,$ VAR3,$ VAR4 ...){} 你必须 功能myFunc的($ params)方法{} ,然后通过参考$ params ['var1']等 – thekevinscott 2009-06-15 17:39:12

回答

12

为什么不用这种方式写所有函数?

对于这个问题,为什么不完全忘记参数,并且对所有东西都使用全局变量? (开玩笑)

传递关联数组有一个有用的优点:可以使多个函数参数为可选参数,并且您可以传递参数值而不必传递* N-1 * th参数。

但是,如果您不通过它们,则无法使用编译时错误生成强制参数。你也不能声明类型检查。

您必须在被调用的函数中编写代码来检查所需参数的存在和类型。

我使用的另一种方法是声明传统的参数为强制性参数,然后作为最后一个(可选)参数声明一个名为$options的关联数组,其中只包含可选项。

function database_connect($dbname, $user, $password, array $options = array()) 
9

缺点是任何人看着你的代码想法什么参数进入方法,他们来自哪里,或者他们是什么。他们也不知道如何调用一个方法,因为如果不仔细查看代码中“参数数组”所需的代码,就不清楚。

1

列出每个参数可以提高代码的可读性。传递单个关联数组并不一定能解释传递给函数的数据类型。

1

如果我拿起你的函数,发现它只是在单个函数参数中开始引用散列值,我会有点困惑。使用@param明确声明变量并在docblock中给出一些文档有助于极大地提高。与可读性列表参数yield相比,必须在两个地方添加一个参数是一个很小的代价。

2

大概其中一个缺点是,你会以太多的参数结束。 这会导致代码很可能失去可读性的问题。

在严格的面向对象的方法中,您将所有这些“传递”多个函数调用的参数转换为持有方法的类的实例变量。

您不应该将参数传递给实际上不需要的函数。

0

这里最大的代码味道是添加另一个变量将级联4-5个不同的函数。我无法真正想到这需要发生的原因。

听起来好像您需要将此代码重构为类,以便您可以将值传递给构造函数一次,并将它们另存为成员变量。

0

如果你有参数命名并单独传入,它使得生成文档变得更容易。你可能会认为使用数组可以更容易地添加新的代码,但是它的好处并不在于可读性。加上离开你的代码2个月,回来......弄清楚以什么样的顺序将params添加到你的阵列中,哪些情况会变得非常头疼。

2

这不一定是一个想法的坏处,因为PHP缺少许多其他现代编程语言(Python,Ruby等)中的“关键字参数”功能。然而,肯定有一些问题吧:

  1. 如果更改一个函数接受的参数,那么很有可能你就必须改变一些代码在那里的反正叫,以匹配新的参数。

  2. 如果您正在广泛使用这些数组,并且在许多函数调用中使用数组并简单地“传递它”,这可能意味着您应该考虑将这些参数中的某些参数转换为结构化类。

  3. 如果你使用这些数组作为可变数据结构,你不一定知道调用该函数后的数组与你传入的数组相同。这可能会回来得到你在某个时候。

0

在某些情况下,这有一定道理,我觉得,但往往你可以通过创建行为稍有不同的多种方法简化事情。该方法的名称将明确说明它的用途。

一般来说,如果你的函数有> 3个参数,它将无法读取。

作为替代方案,并且经常使用的模式使得函数的一个参数成为(分类)对象。 '参数类'将明确定义支持的内容。

0

如果您quetion是如何给数组作为inputof功能,这是你的答案:

<?php 
function city($input){ 
    $i=count($input['iran']); 
    $result=""; 
    for($b=1;$b<=$i;$b++){ 
     $result.='<div style="background:gold">'.$input['iran'][$b].'</div>'; 
     } 
     return $result; 
    } 
$cityName['iran'][1]="Tehran"; 
$cityName['iran'][2]="Qom"; 
$cityName['iran'][3]="MashHad"; 
$cityName['iran'][4]="Isfahan"; 
$cityName['iran'][5]="Shiraz"; 
$cityName['iran'][6]="Yazd"; 

echo city($cityName); 
?> 
1

我个人使用下面的方法:

  1. 将参数声明为函数定义中的数组;

  2. 建立“默认值”assoc。阵列;

  3. 匹配将带默认参数传递给我在函数内部使用的确定参数assoc.array。为此,我使用param_default()函数。

通过遵循此方法,我避免了强制参数问题和管理默认值;以任何顺序传递密钥的能力也非常舒适。

// default values fx. 
function param_default($def = array(), $parameters= array()){ 
    $parm_diff = array(); 
    $ak=array(); 
    $va=array(); 
    $parm = array(); 
    foreach($def as $key=>$values) if(!in_array($key, array_keys($parameters))){ 
     $ak[]=$key; 
     $va[]=$values; 
    } 
    $parm_diff = array_combine($ak,$va); 
    $parm = array_merge($parm_diff,$parameters); 
    unset($parm_diff, $ak,$va); 

    return $parm; 
} 

因此,这是使用一个简单的例子:

<?php 
// sample use 
function my_func($parameters = array()){ 
    $def = array(
     'first' => 1, 
     'second' => 'foo', 
     'third' => -1 
    ); 
    $parm = param_default($def, $parameters); 
    //hereon I can use my array 

    var_dump($param); 

    if ($param['second'] !=='foo'){ 
     echo 'Not foo!!'; 
     // whatever... 
    } 

    return true; 
} 
?> 

输出的实施例:

// calling my_fun() 

$example = my_func(array('second'=>'bar')); 

// results in 
$param array: 
'first' => 1, 
'second' => 'bar', 
'third' => -1 
0

创建功能:

function testing($argumentos) { 
    $var_1 = $argumentos['var_01']; 
    $var_2 = $argumentos['var_02']; 

    echo $var_1 . " " . $var_2; 
} 

调用函数:

​​

输出:

mierda conio!