1.13 避免使用过多参数

在开发中,我们要尽量在函数或方法中避免使用过多的参数。首先可维护性不好,其次在调用时写起来也麻烦,一不小心就可能被提示缺少参数。

因此,当参数过多、过长时,就要考虑我们的思路是否需要修正。如果参数过多的情况无法避免,可以利用全局变量,但是这种方法不提倡。

下面我们就来讨论如何避免函数参数过多的解决方案,应该有一款风格适合你。

1.13.1 使用数组

在函数中可以使用标量变量作为参数,也可以使用数组作为参数,从而有效减少函数参数的数量。

这样在调用函数时可用如下形式:

        $bar = func(array('dude', 'where is my', 'car'));

函数定义如下:

        function func($args){
            $first = $args[0]; // 数组的第一个元素从0开始
            $second = $args[1];
            $third = $args[2];
        }

可以看到调用函数时使用数组,PHP函数将数组元素作为单独的变量来进行处理。

1.13.2 使用对象

我们知道,对象是一个类的实例,当使用对象传递给函数或方法时,方法或函数中就可以调用对象提供的全部公有和私有方法,而不只是一个参数。

在下面实例中有一个User用户类和一个UserCsvTemplate类,有一个方法来显示一个CSV类与CSV的用户数据,如代码清单1-20所示:

代码清单1-20使用对象传递参数

        <? php
        class User{
            public $user_name:
            public $type;
            public $email;
            public $address;
            public $city;
            public $country;
            public $gender;
            //...
        }
        class UserCsvTemplate{
            public function render($user_name, $type, $email, $address, $city, $country,
                $gender){
                echo $user_name, '; ',
                $type, '; ', $email, '; ',
                $address, '; ', $city, '; ',
                $country, '; ', $gender, PHP_EOL;
            }
        }
        ?>

我们想调用UserCsvTemplate类,首先新建User对象,然后再将值传递。如代码清单1-21所示:

代码清单1-21使用值传递参数

        $user = new User();
        ...
        $csv_template = new UserCsvTemplate()
        $csv_template->render($user->user_name,  $user->type,  $user->email,  $user->
            address, $user->city, $user->country, $user->gender);

可以看到上面的render()方法包含非常多的参数。

由于所有的参数属于一个对象,可以直接传递,如代码清单1-22所示:

代码清单1-22使用对象传递参数

        <? php
        class UserCsvTemplate{
            public function render(User $user){
                echo $user->first_name, '; ', $user->last_name, '; ',
                $user->type, '; ', $user->email, '; ',
                $user->address, '; ', $user->city, '; ',
                $user->country, '; ', $user->gender, PHP_EOL,
            }
        }
        $user = new User();
        //...
        $csv_template = new UserCsvTemplate();
        $csv_template->render($user);