Как провести рефакторинг этого кода? - PullRequest
2 голосов
/ 14 февраля 2010

Сгруппированные параметры:

<?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 ]

2 голосов
/ 14 февраля 2010

Запись (юнит) тестов , чтобы убедиться, что ваш код работает правильно. Затем измените его шаг за шагом и запускайте тесты после каждого шага. Таким образом вы гарантируете, что ваш код работает правильно после рефакторинга.

Тестовая структура, например PHPUnit

(надеюсь, вы не ожидали, что код ответа был изменен).

1 голос
/ 15 февраля 2010

Попытайтесь найти сходства и различия между компонентами в вашем коде. Например, вам нужен Form, который вы уже выяснили, но форма состоит из разных полей, так почему бы не извлечь их в набор Field -классов? Как EmailField, PasswordField.

Вы, наверное, заметили, что Validate делает слишком много вещей. Например, если форма состоит только из поля электронной почты, вы не хотите, чтобы Validate включал что-либо, касающееся паролей или тому подобного. Когда вы начинаете добавлять правила проверки для «имен пользователей» или «страны происхождения» или любого другого атрибута, вы не хотите добавлять правила в один большой класс Validate, но либо в каждый Field, либо вспомогательный класс, такой как ValidateEmailField.

0 голосов
/ 22 февраля 2013

Две вещи, которые я нашел в классе Validate:

  1. У него есть методы для проверки
  2. Имеет блок кода для запросов к базе данных.

Хорошо, код для запроса к базе данных может быть помещен в другой класс. Это делается для того, чтобы убедиться, что проблемы разделены (разделение интересов) . В методе isPasswordAlsoIn будет код, связанный с бизнес-правилами, а затем проверка базы данных может быть делегирована отдельному классу.

В отдельном примечании вы можете избегать SQL-запросов, например, следующих, просто чтобы избежать внедрения SQL.

ВЫБРАТЬ * ИЗ УЧЕТНОЙ ЗАПИСИ, где электронная почта = '$ value' И пароль = '$ value2'

...