【问题标题】:How can I write a function which has lots of arguments better?我怎样才能更好地编写一个有很多参数的函数?
【发布时间】:2017-05-03 14:16:15
【问题描述】:

我有这样的功能:

public function myfunc ($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8) {
    // do something
}

看到了吗?我的函数有 8 个参数。是的,它也可以,但你知道,它有点难看..!没有更好的主意吗?例如,仅传递一个数组包含所有参数。可能吗?甚至类似的东西。

【问题讨论】:

  • func_get_args()
  • 你可以使用数组作为参数。
  • 对于一个试图做太多事情的函数来说,很多参数是一种代码味道。问自己几个问题:你的函数是否有超过 20 行代码?它是否有超过 2 级的缩进?它是否包含超过 3 个 if/case/条件语句?循环内有循环吗?如果其中任何一个的答案是肯定的,那么如果将代码重构为多个函数而不是单个函数,那么您的代码可能会更好
  • @Mohammad 只有在必须以类似方式处理的类似事物数组的情况下,您才应该这样做。您不应该使用它来缩短参数列表!
  • @MartinAJ 在这种情况下,关联数组是一个合适的参数(当然假设是准备好的语句!)

标签: php function parameter-passing


【解决方案1】:

我是这样做的..

$params = [];

把东西放在参数里..

$params[] = $a;
$params[] = $b;

将数组传递给函数

myFunction($params);

函数接受数组作为arg,定义:

public function myFunction($params = []){}

传入一些东西,然后 var_dump 自己检查...

【讨论】:

    【解决方案2】:

    好的,现在我知道您正在执行的是 SQL 操作,那么最好的方法是关联数组(假设 PDO 和准备好的语句)。

    public function myFunc (array $data)
    {
        // Using 3 values for example!
        $stmt = $this -> pdo -> prepare ("INSERT INTO TABLE thisTable (
            col1, 
            col2, 
            col3
        ) VALUES (
            :val1, 
            :val2, 
            :val3
        )");
    
        if (false !== $stmt execute ($data))
        {
            return $stmt -> rowCount ();
        } else {
            return 0;
        }
    }
    

    你可以用一个包含正确参数的数组来调用它:

    $success = (bool) $obj -> myFunc (["val1" => "First value to insert",
                                       "val2" => "Second value to insert",
                                       "val3" => "Third value to insert"]);
    

    【讨论】:

    • 我认为期望程序员知道你准备好的语句的 pdo 实现细节是不明智的(':valx' 是一个细节)。你不认为只把定义占位符的责任留给这个方法会更好吗?
    • 只是为了说明原理。除了占位符之外,顺序变得很重要,如果您以错误的顺序传入具有正确参数的数组,您可能会得到意想不到的结果。
    【解决方案3】:

    这取决于myfunc是否属于暴露的api(即:public)

    如果它是公开的,则签名必须在您更新底层模型(您的插入查询)时中断,否则将在客户端提交错误。

    使用数组,您将模型映射到应用程序,而您只是期望程序员向您发送正确的值。使用紧密/限制映射,这种错误不会发生。

    我认为,如果您在数据库中保存一个项目,您实际上需要所有这些字段。它确实不优雅,但它不是一种反模式,因为它们都不是可选的。即使有一两个是,也不会是一个问题。

    您可以做些什么来改进您的 api:

    1. 如果在某些情况下您只需要传递少数参数(即大多数参数是可选的或取决于特定场景),那么您可以将方法专门化为单独的函数。但是 PHP 不接受函数多态性对于这种事情来说是一件很痛苦的事情;您必须以不同的方式命名方法。

      public function myfunctosavedatainaparticularcase ($arg1, $arg2, $arg3, $arg4) 
          // do something
      }
      
      public function myfunctosavedatainanotherparticularcase ($arg5, $arg6, $arg7, $arg8) 
          // do something
      }
      
    2. 使用对象模型映射器。例如,假设您正在保存用户数据。您只需将 User 对象传递给该方法:

      public function myfunc (User $user) 
          // map fields to the User signature.
      }
      

    如果您可以控制 User 类,这是可以接受的,因为您必须更改它以反映模型更改。

    1. 使用 ORM 为您处理此问题。在您决定更改数据库模型后,您只需要更新模式的 xml 规范,所有必要的更改都会自动传播到应用程序。当然对象定义会改变,但这是不可避免的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-18
      • 1970-01-01
      • 2014-03-31
      • 2021-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多