使用PHP将多个变量传递给函数的最佳实践是什么?

时间:2014-07-08 13:15:37

标签: php function

我有一个带5个参数的函数,随着应用程序的增长,我们需要添加更多的参数,这些参数最终有9个参数,其中4个参数有默认值。

我想知道传递这样的参数或使用数组会更好吗?

我更喜欢这样的

fun(array(
     'par1' => 'x',
     'par2' => 'y',
     .....
    )
 )

Insted of

func($par1, $par2, $par3, ...);

您怎么看?

2 个答案:

答案 0 :(得分:11)

在很大程度上取决于用例。

但是这里有一些解决这个问题的方法。


固定订单

如果订单有些固定而你永远不需要改变它,那么:

<?php

function fn($a1, $a2, $a3, $a4, $a5, $a6 = null, $a7 = "foo", $a8 = "bar", array $a9 = array()) {}

<强>赞成

  • 自我记录
  • 类型提示
  • 默认值

<强>缺点

  • 固定订单

阵列

另一方面,如果订单总是有些不同,请使用数组。

<?php

function fn($a1, $a2, $a3, $a4, $a5, array $optional = array()) {}

fn("", "", "", "", "", array("arg9" => false));

<强>赞成

  • 易于使用
  • 没有固定的订单

<强>缺点

  • 非自我记录
  • 验证成本高昂

参数对象

参数对象当然也是一种有效的解决方案,但处理起来不切实际:

<?php

class Args {

  public $arg5 = "foo";

  public $arg6 = "bar";

  public $arg7 = null;

  public $arg8 = array();

  public $arg9 = true;

}

function fn($arg1, $arg2, $arg3, $arg4, $arg5, \Args $optional = null) {}

// Now comes the impractical part.
$optional = new Args();
$optional->arg9 = false;
fn("", "", "", "", "", $optional);

<强>赞成

  • 自我记录
  • 没有固定的订单

<强>缺点

  • 非常不切实际
  • 验证成本高昂

数组到参数对象

你可以混合使用这两种方法:

<?php

class Args {

  public $arg5 = "foo";

  public $arg6 = "bar";

  public $arg7 = null;

  public $arg8 = array();

  public $arg9 = true;

  public __construct($args) {
    foreach ($args as $property => $value) {
      $this->"set{$property}"($value);
    }
  }

  public function setArg5($value) {
    if (is_string($value) === false) {
      throw new \InvalidArgumentException;
    }
    $this->arg5 = $value;
  }

  // and so on ...

}

function fn($arg1, $arg2, $arg3, $arg4, $arg5, array $optional = null) {
  if (isset($optional)) {
    $optional = new Args($optional);
  }
  // ...
}

fn("", "", "", "", "", array("arg9" => false));

<强>赞成

  • 轻松验证
  • 分离关注
  • 易于传递
  • 易于处理
  • 可以记录API

<强>缺点

  • 仍然无法将其记录为与固定的args方法一样好
  • 验证成本高昂

Variadics

您可能会发现PHP 5.6中的一项新功能variadics

<?php

function fn($a1, $a2, $a3, $a4, $a5, ...$optional) {}

<强>赞成

  • 非常快
  • 允许构建特殊的API(例如数据库预处理语句绑定)

<强>缺点

  • 不易记录
  • 验证成本高昂

命名参数

我们将来可能会看到named parameters

答案 1 :(得分:6)

你正在攻击错误的问题。

将9个参数传递给函数是一个明确的code smell

  

参数太多:过程中的一长串参数或   功能使可读性和代码质量变差。

有了这么多参数,你很可能违反了:

  

长方法:一种方法,功能或程序也在增长   大。

创建将这些参数组合在一起的任意array将无法解决真正的问题。它可以使您的代码更易于阅读,并且对于省略参数($arg1, $arg2, $arg4)等小问题而言不那么易受攻击,而不是真正的解决方案。

你应该做什么:

弄清楚为什么函数需要那么多参数,然后解决这个问题。

  • 如果单个函数具有太多的可复制性:拆分它。您可以执行单个顺序拆分:一个任务在另一个之后。
  • 如果可以将多个参数聚合到单个实体,则为其创建一个对象(例如:x和y坐标可以合并为一个点。矩形可以由两个相对的角点描述)。尝试创建可重用的东西,因此它的唯一目的不仅仅是能够将参数传递给这个单一的函数。

有很多技巧,阅读一篇关于(oo)代码重构的好文章/书可以给你一些提示。