Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/241.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 此函数的参数是否过多?_Php_Function_Parameters_Coding Style - Fatal编程技术网

Php 此函数的参数是否过多?

Php 此函数的参数是否过多?,php,function,parameters,coding-style,Php,Function,Parameters,Coding Style,最后,我得到了这个函数。我不知道这是否正常 function user_registration($user_name, $user_email, $user_pass, $address, $city, $postalcode, $country, $phone, $mobilephone) 我如何以及为什么可以改进这一点 一个解决方案是只有一个参数,它可以包含多个数据段,比如一个数组 您的函数可以这样定义: function user

最后,我得到了这个函数。我不知道这是否正常

function user_registration($user_name, $user_email, $user_pass, $address, 
                           $city, $postalcode, $country, $phone, $mobilephone)

我如何以及为什么可以改进这一点

一个解决方案是只有一个参数,它可以包含多个数据段,比如一个数组

您的函数可以这样定义:

function user_registration(array $data) {
    // work with $data['name']
    // and $data['email']
    // ...
}
你会这样称呼它:

user_registration(array(
    'name' => 'blah',
    'email' => 'test@example.com', 
    'pass' => '123456',
    // and so on
));

好东西是:

  • 您可以轻松添加/删除“参数”
  • “参数”可以按您想要的任何顺序传递
不那么糟糕的是:

  • 在IDE中键入时没有提示
  • 无文档(如phpDoc)

一种方法是将数组作为参数传递给此函数,并将所有信息放入该数组中:

function user_registration(array $user_info)
{
   // process $user_info;
}

您可以传递一个包含所有变量的数组,或者创建一个“用户”类,通过setter添加所有属性,最后使用专用方法进行验证:

class User {

  public function setName($name) {
    $this->name = $name;
  }

  [...]

  public function register() {

    //Validate input
    if (empty($this->name))
      $this->errors[] = "ERROR, Username must not be emtpy";

    //Add the user to the database
    //Your SQL query
    return empty($this->errors);
  }

}

$user = new User();
$user->setName("Peter");
$success = $user->register();

if (!$success)
  echo "ERRORS OCCURED: ".print_r($user->errors, true);

我个人认为它没有太多的参数。从函数定义来看,很清楚您需要什么作为输入,如果使用数组调用,这一点就不那么明显了

“如果它没有坏,就别修了!”

我会这样做的

fields=explode(",","name,surname,lastname,street,city,region,zip,country");
user_registration($fields);

因为我确信这些变量来自$\u POST

,所以我创建了如下键数组

$fields = array('field1', 'field2');
function register (array $values, array $keys)
{
    $data = array();
    foreach ($keys as $one)
    {
        if (isset($values[$one])) $data[$one] = $values[$one];
    }
    // or you can use array functions like array_flip and after - array intersect
}

没有任何参数的函数(方法)是最好的。单参数函数优于双参数函数。有2个参数的函数比有3个参数的函数好,以此类推。

作为一般经验法则(而不是固定规则),任何时候你都要问“这个函数有太多参数吗?”--答案是肯定的。你的直觉告诉你一些你的大脑还没能解决的事情


在这种情况下,首先想到的是应该首先检查您的用户cred.s(用户名是否已经存在?pw是否足够复杂),并且应该单独添加您的用户详细信息,可能使用对象或数组。

@Florian提供了一个完善的解决方案,可以改进您的代码。通过这一评论,我想从系统设计的角度详细阐述“为什么”部分

从面向对象的角度来看,其他对象应该能够操作属性。这就是为什么属性永远不应该被定义为“公共”。它们应该是“私人”的,例如:

原因是当其他对象操作此变量时,该对象的正确工作将面临风险。另一方面,方法可以公开定义:

public function register() 
因此,属性的操作将通过适当的方法进行。还可以使用一种方法来评估属性操作的正确性

有两种操作可能发生:使用获取方法读取属性的当前值和使用设置方法保存属性的新值

一个好的实践是为每个类属性实现一个get方法。每个可以修改的属性也应该有一个适当的set方法

有时最好还是不要实现get/set方法(例如showData())。这是因为在特定类中使用getter和setter可能会降低性能。但是,这意味着在更改或实现类时,在试图保存错误信息时必须小心,从而使类的完整性处于危险之中


现在,考虑一下你决定只使用一个电话号码而不是电话和手机号码的事实。当手机号码被弃用时,您的主程序仍然保持不变。您所要做的就是更改/删除一个方法。使用getter和setter的优点是增强了适应性和可维护性当您查看参数名称时,您不得不注意到它们可以分为三个不同的组:

User Data:    $user_name, $user_pass
Address Data: $address, $city, $postalcode, $country
Contact Data: $user_email, $phone, $mobilephone
因此,您可以申请:

通常,您会看到一组特定的参数倾向于一起传递。有几个方法可以在一个类或多个类中使用此组。这样一组类是一个数据束,可以用一个包含所有这些数据的对象来替换。将这些参数转化为对象是值得的,只是为了将数据分组在一起。这种重构很有用,因为它减少了参数列表的大小,而且长参数列表很难理解。在新对象上定义的访问器也使代码更加一致,这也使代码更易于理解和修改

如果不想执行OOP,也可以将参数分组到数组中,但这样会失去所有类型优势。我假设你不介意使用对象。因此,在应用重构之后,您将得到

function user_registration(User $user, Address $address, Contact $contact)

查看该参数列表应该首先注意到地址和联系人可能属于用户,因此您可以考虑将函数签名更改为

function user_registration(User $user)
然后这样称呼它:

$user = new User('johndoe', 'secretsauce');
$user->setAddress(new Address('Doe Street', 'Doe Town', 12345, 'Neverland'));
$user->setContact('jdoe@example.com', '+123 12345', '+123 54321');
user_registration($user);
我们可能也可以将用户名和密码设置为凭证对象,然后执行以下操作

user_registration(new User($credentials, $address, $contact));
通过要求ctor中的数据,我们确保新注册的用户确实拥有所有这些信息。我们可能会争论是否需要地址和联系人来注册用户,所以在这里可能就足够了:

$user = new User(new Credentials('johndoe', 'secretsauce'));
$user->setAddress(new Address('Doe Street', 'Doe Town', 12345, 'Neverland'));
$user->setContact(new Contact('jdoe@example.com', '+123 12345', '+123 54321'));
user_registration($user);
但是,
用户注册
作为全局范围内的一个单独功能是错误的。在这种情况下,方法应该针对拥有最多信息的对象来履行职责。这改善并减少了成本。换言之:

$user = new User($credentials);
$user->setAddress($address);
$user->setContact($contact);
$user->register();
用户类现在的一个问题是它包含密码。密码仅用于根据身份验证服务对用户进行身份验证。我们可以争论用户名,但密码绝对不应该是用户对象的一部分。所以你应该做点什么,李
$user = new User($credentials);
$user->setAddress($address);
$user->setContact($contact);
$user->register();
$user = new User;
$user->setAddress($address);
$user->setContact($contact);
$user->register($credentials);