Какой паттерн лучше использовать, когда идет обработка разных форм

Petja

Новичок
Есть 2 или более формы.
Обработка каждой идет примерно одинаково.
Но разные массивы данных - разные названия полей, разные условия валидации.

Я пытаюсь представить вот как:
Сделать абстрактный класс, в нем прописать:
метод обработки пост данных
метод проверки полей на ошибки
метод подготовки ответа

На основе него сделать 2 класса на 2 формы (или более, но у меня 2 сейчас).

Далее в зависимости от переменной $_POST['action'] (или одна форма или другая) создать экземпляр или одного класса или другого.

Тут проблема в том, что надо делать проверку if - а хочется чтобы просто запускалась логика по содержимому переменной $_POST['action'].

Плюс в конце еще надо получить конечные данные для ответа и сформировать ответ или для ajax или заполнить плейсхолдеры в шаблоне...


Подскажите, плз, как можно красиво реализовать эту простую функцию через ООП?
Хочу научиться грамотно проектировать ООП.

Заранее огромная благодарность!
 

Redjik

Джедай-мастер
Серебряной пули нет.
Дай больше данных - расскажу как сделать.
 

Petja

Новичок
И еще не подскажете, как лучше хранить в классе ассоциаивные массивы - которые выступют вроде хранителей констант типа того:

$errMsg = array(
'messageEmpty' => 'Поле сообщение не может быть пустым',
'emailFailed' => 'Введите корректно емайл'
);

То есть бывает часто нужно подобные данные удобно хранить, чтобы иметь быстрый доступ к ним, в зависимости от переменной $msg = $this->errMsg[$var];.

Я имею ввиду мелкие скрипты, где БД заводить и лексиконы придумывать смысла нет.
Но может быть в массивах не стоит хранить, а может классы делать для хранения более менее объемных "констант"?

Извиняюсь, если я неуклюже пишу, просто я самоучка, неоткого было понятия и терминологии цеплять...
 

Petja

Новичок
Серебряной пули нет.
Дай больше данных - расскажу как сделать.
Просто какой паттерн и как лучше использовать для проверки отправки раных форм, чтобы можно было добавлять новые формы...

Не представляю как можно в моем случае дать больше данных, ведь реализации пока нет, а задача с 2 и более формами - на мой взгляд достаточно тривиальна...

Я могу попробовать сделать свое решение и выложить, чтобы вы меня осудили и подсказали лучшее пути решения?
 

Redjik

Джедай-мастер
По второму - ООПшно будет сделать на каждый тип валидации свой класс.
В классе в абстрактном родителском классе валидации сделать свойство - $errorMessage
 

Petja

Новичок
По второму - ООПшно будет сделать на каждый тип валидации свой класс.
В классе в абстрактном родителском классе валидации сделать свойство - $errorMessage
Спасибо, а подобные массивы лучше не делать? Для меня так нагляднее всего было делать - чтобы потом можно было быстро разобраться...
То есть мини БД в асоцитивных массивах хранил всегда, чтобы легко увидеть и разобраться было. Я имею ввиду не очень большие массивы данных...
 

Redjik

Джедай-мастер
Я тебя только запутаю, если будем разговаривать об абстрактных сущностях.
Посмотри как в yii работа с формами сделана.
 

WMix

герр M:)ller
Партнер клуба
я просто попробывал бы готовый класс, подгядел, что там хорошо и что плохо и написал бы (если будет после этого иметь смысл свой). тут нет патерна. патерн это еще более абстрактнее чем форма.
извеняюсь за рекламу http://framework.zend.com/manual/2.0/en/modules/zend.form.quick-start.html
и сорцы https://github.com/zendframework/zf2/blob/master/library/Zend/Form/Form.php
 

Redjik

Джедай-мастер
WMix, задача может быть как очень простой, так и не очень.
Вот пример - модель пользователя и модель телефона.
При таком раскладе надо создавать сервисный слой в котором делать транзакцию, отдельно валидировать каждую модель ... итд
 

WMix

герр M:)ller
Партнер клуба
да, но судя по его описанию, его класс не будет делать ничего.
Сделать абстрактный класс, в нем прописать:
метод обработки пост данных
метод проверки полей на ошибки
метод подготовки ответа
по сути мой ответ похож на твой предыдущий, только framework другой
 

riff

Новичок
Тут проблема в том, что надо делать проверку if - а хочется чтобы просто запускалась логика по содержимому переменной $_POST['action'].
Если нужен очень простой ответ, то:
PHP:
class BaseForm {
    public function exec() {
        echo 'ok';
    }
}
class Form_Test1 extends BaseForm {}
class Form_Test2 extends BaseForm {}

$action = $_POST['action'];
$form = 'Form_'.$action;
if (!class_exists($form)) throw new Exception('error');
$form = new $form;
$form->exec();
UPD: P.S. не надо в один вопрос добавлять несвязные с ним другие вопросы.
 
Последнее редактирование:

Redjik

Джедай-мастер
Роутинге в контроллере - классно...
А еще можно роутинг в объекте роутинга делать.
 

Petja

Новичок
Спасибо большое за ответы.
Я сейчас попробую сделать по своему эту штуку.
Можно тут показать будет, чтобы получить критику?
 

Фанат

oncle terrible
Команда форума
можно.
но заранее наберись терпения.
а то тут полно любителей посамоутверждаться за чужой счет.
но если научиться не обращать внимание на их расчесанное ЧСВ
то пользу для себя извлечь можно
 

Petja

Новичок
Вот так сделал пока что, если можно, дайте критику, как можно было бы лучше и грамотнее сделать?
Внешний класс, который будет работать с результатами проверки форм, по сути его можно и не указывать, но чтобы видно было, как происходит работа с классом обработчиком форм:
PHP:
require_once('fbexternal.class.php');

class feedbackForms {
    public $form;
    function __construct(){
        $action = $_POST['action'];
        $c = '\feedbackForms\\'.$action.'Form';
        if(class_exists($c)){
            $this->form = new $c;
        }
        var_dump($this->form->data);
    }
}
А вот и сам код обработчик форм, который я хотел сделать как можно понятнее и расширяемее по принципам ооп...
Файл fbexternal.class.php
PHP:
namespace feedbackForms;

abstract class form {
    public $data;
    function __construct(){
        $this->postProcessor();
        $this->fieldProcessor();
    }
    function postProcessor(){
        foreach($this->data as $name => $v){
            if($_POST[$name]){
                $this->data[$name]['value'] = trim(strip_tags($_POST[$name]));
            }
        }
    }
    abstract function fieldProcessor();
}

class recallForm extends form{

    public $data = array(
        'phone' => array(
            'value' => '',
            'required' => array(true, 'msg'=>'укажите телефон'),
            'regexp' => array('#^\+?[\s-\d\)\(]{7,20}$#', 'msg'=>'телефон указан некорректно'),
            'errors' => array(),
        ),
        'desire' => array(
            'value' => '',
            'required' => false,
            'regexp' => false,
            'errors' => array(),
        ),
    );

    function fieldProcessor(){
        foreach($this->data as $name => $prop){
            if($prop['required'][0] and !$prop['value']){
                array_push($this->data[$name]['errors'],$prop['required']['msg']);
            }elseif($re = $prop['regexp'][0] and !preg_match($re,$prop['value'])){
                array_push($this->data[$name]['errors'],$prop['regexp']['msg']);
            }
        }
    }

}


class writeForm extends form{

    public $data = array(
        'email' => array(
            'value' => '',
            'required' => array(true, 'msg'=>'укажите email'),
            'regexp' => false,
            'errors' => array(),
        ),
        'message' => array(
            'value' => '',
            'required' => array(true, 'msg'=>'обязательное поле'),
            'regexp' => false,
            'errors' => array(),
        ),
    );

    function fieldProcessor(){
        foreach($this->data as $name => $prop){
            if($prop['required'][0] and !$prop['value']){
                array_push($this->data[$name]['errors'],$prop['required']['msg']);
            }elseif($re = $prop['regexp'][0] and !preg_match($re,$prop['value'])){
                array_push($this->data[$name]['errors'],$prop['regexp']['msg']);
            }
            if($name == 'email' and !filter_var($prop['value'], FILTER_VALIDATE_EMAIL)){
                array_push($this->data[$name]['errors'],'некорректно введен email');
            }
        }
    }

}
 
Последнее редактирование:

Petja

Новичок
Увидел недочет и убрал из дочерних классов function __construct() в абстрактный класс, обновил предыдущий пост.
 

riff

Новичок
По поводу классов я ничего полезного сказать не могу. Хотел лишь обратить внимание
require_once('fbexternal.class.php');
Ты пользуешься namespaйсами, поэтому самое время отказаться от require_once, а точнее придумать такую структуру папок/названия файлов/namespace, чтобы всю загрузку модулей разруливать в __autoload'е.
 

WMix

герр M:)ller
Партнер клуба
Petja, ну идея понятная, хотя я вижу только половину функциональности, твой класс работает только после отправки данных, но при этом содержит данные, которые интересны при создании формы - имя поля, а возможно и тип, и размер и максимальная длина и опции для селекта и и и). а основная проблема "не возможности использования данных обьекта при рендеринге формы" в том, что процесоор уже на этапе создания обьекта выполняет всю цепочку комманд.
 

riff

Новичок
сначала ты предложил дурацкую реализацию обработки форм
Вы с WMix дали ответы про формы, и я не лез со своим мнением в эту тему. У ТС был подвопрос "как избавиться от if", я только дал ответ на этот счёт. Я сильно сомневаюсь, что ТС сможет в раз понять и переписать свою структуру в соответствии со "стандартом", поэтому такие мелкие ответы для него остаются актуальными.
 
Сверху