如何重构这段代码?

时间:2010-02-14 19:15:31

标签: php refactoring oop

Grouped params:

<?php
class Form {
    private $field;

    public function getFieldRelated($field) {
        return $this->fieldrelated[$field];
    }

    public function __construct() {
        $this->fieldrelated['email']['name'] = 'email';
        $this->fieldrelated['email']['value'] = $_POST['email'];
        $this->fieldrelated['email']['pattern'] = REGEX_EMAIL;
        $this->fieldrelated['email']['confirmation'] = 'emailconfirmation';
        $this->fieldrelated['email']['names'] = 'emails';

        $this->fieldrelated['emailconfirmation']['name'] = 'email confirmation';
        $this->fieldrelated['emailconfirmation']['value'] = $_POST['emailconfirmation'];
        $this->fieldrelated['emailconfirmation']['pattern'] = REGEX_EMAIL;

        $this->fieldrelated['password']['name'] = 'password';
        $this->fieldrelated['password']['value'] = $_POST['password'];
        $this->fieldrelated['password']['pattern'] = REGEX_PASSWORD;
        $this->fieldrelated['password']['confirmation'] = 'passwordconfirmation';
        $this->fieldrelated['password']['names'] = 'passwords';

        $this->fieldrelated['passwordconfirmation']['name'] = 'password confirmation';
        $this->fieldrelated['passwordconfirmation']['value'] = $_POST['passwordconfirmation'];
        $this->fieldrelated['passwordconfirmation']['pattern'] = REGEX_PASSWORD;
        }
    }
?>

Validate类的一部分:

public function isEmpty($field) {
    $fieldrelated = $this->form->getFieldRelated($field);
    $name = $fieldrelated['name'];
    $value = $fieldrelated['value'];

    if(empty($value)) {
        $this->setProperty($field, 'empty');
        $this->addErrorMessage('The '.$name.' is empty!');
        return true;
    } else {
        $this->setProperty($field, 'unempty');
        return false;
    }
}
public function isValid($field) {
    $fieldrelated = $this->form->getFieldRelated($field);
    $name = $fieldrelated['name'];
    $value = $fieldrelated['value'];

    $pattern = $fieldrelated['pattern'];

    if(preg_match($pattern, $value)) {
        $this->setProperty($field, 'valid');
        return true;
    } else {
        $this->setProperty($field, 'invalid');
        $this->addErrorMessage('The '.$name.' is invalid!');
        return false;
    }
}
public function isConfirmed($field) {
    $fieldrelated = $this->form->getFieldRelated($field);
    $value = $fieldrelated['value'];

    $field2 = $fieldrelated['confirmation'];

    $fieldrelated2 = $this->form->getFieldRelated($field2);
    $value2 = $fieldrelated2['value'];

    $names = $fieldrelated['names'];

    if($value == $value2) {
        $this->setProperty($field, 'confirmed');
        $this->setProperty($field2, 'confirmed');
        return true;
    } else {
        $this->setProperty($field, 'unconfirmed');
        $this->setProperty($field2, 'unconfirmed');
        $this->addErrorMessage('The '.$names.' are unconfirmed!');
        return false;
    }
}
public function isEmailOnlyIn($correct) {
    $fieldrelated = $this->form->getFieldRelated('email');
    $name = $fieldrelated['name'];
    $value = $fieldrelated['value'];

    $value = mysql_real_escape_string($value);
    $result = "SELECT * FROM account WHERE email = '$value'";
    $result = mysql_query($result);
    $result = mysql_fetch_array($result);

    if($result) {
        $this->setProperty('email', 'email only in');
        if($correct == 'not in') {
            $this->addErrorMessage('The '.$name.' is in database!');
        }
        return true;
    } else {
        $this->setProperty('email', 'email only not in');
        if($correct == 'in') {
            $this->addErrorMessage('The '.$name.' is not in database.');
        }
        return false;
    }
}
public function isPasswordAlsoIn($correct) {
    $fieldrelated = $this->form->getFieldRelated('email');
    $name = $fieldrelated['name'];
    $value = $fieldrelated['value'];

    $fieldrelated2 = $this->form->getFieldRelated('password');
    $name2 = $fieldrelated2['name'];
    $value2 = $fieldrelated2['value'];

    $value = mysql_real_escape_string($value);

    $value2 = md5($value2);
    $value2 = mysql_real_escape_string($value2);

    $result = "SELECT * FROM account WHERE email = '$value' AND password = '$value2'";
    $result = mysql_query($result);
    $result = mysql_fetch_array($result);

    if($result) {
        $this->setProperty('password', 'password also in');
        if($correct == 'not in') {
            $this->addErrorMessage('The '.$name2.' is in database!');
        }
        return true;
    } else {
        $this->setProperty('password', 'password also not in');
        if($correct == 'in') {
            $this->addErrorMessage('The '.$name2.' is not in database!');
        }
        return false;
    }
}

用法:

    if(!$validate->isEmpty('email')) {
        $validate->isValid('email');
    }
    if(!$validate->isEmpty('emailconfirmation')) {
        $validate->isValid('emailconfirmation');
    }
    if($validate->isProperty('email', 'valid') && $validate->isProperty('emailconfirmation', 'valid')) {
        $validate->isConfirmed('email');
    }

    if(!$validate->isEmpty('password')) {
        $validate->isValid('password');
    }
    if(!$validate->isEmpty('passwordconfirmation')) {
        $validate->isValid('passwordconfirmation');
    }
    if($validate->isProperty('password', 'valid') && $validate->isProperty('passwordconfirmation', 'valid')) {
        $validate->isConfirmed('password');
    }

    if($validate->isProperty('email', 'confirmed') && $validate->isProperty('emailconfirmation', 'confirmed')) {
        $validate->isEmailOnlyIn('not in');
    }

3 个答案:

答案 0 :(得分:2)

编写(单元)测试以确保您的代码正常运行。然后逐步改变 并在每个步骤后运行测试。这样,您可以确保在重构​​后代码正常工作。

测试框架,例如PHPUnit

(我希望你不要指望重构的代码作为答案。)

答案 1 :(得分:1)

尝试查找代码中组件之间的相似点和不同点。例如,您需要一个已经找到的Form,但表单由不同的字段组成,那么为什么不将它们提取到一堆Field - 类中?与EmailFieldPasswordField一样。

您可能已经注意到Validate做了太多事情。例如,如果表单仅包含电子邮件字段,则您不希望Validate包含有关密码等的任何内容。当您开始为“用户名”或“原产国”或任何其他属性添加验证规则时,您不希望将规则添加到大型单Validate - 类,而是添加到每个{{1或者是一个辅助类,例如Field

答案 2 :(得分:0)

我发现有关Validate类的两件事:

  1. 它有验证方法
  2. 它有用于查询数据库的代码块。
  3. 那么,查询数据库的代码可以放在不同的类中。这是为了确保将问题分开(关注点分离)。在方法中,isPasswordAlsoIn,将有与业务规则相关的代码,然后可以将数据库检查委托给单独的类。

    另外,您可能希望避免SQL查询,如下所示,以避免SQL注入。

    SELECT * FROM account WHERE email ='$ value'AND password ='$ value2'