В каждом контроллере, мы сейчас инициализируем Формы, сами засовываем данные из Запроса, и также потом это все обрабатываем, добавляем Фильтры, которые по id объекта получают Модели, и т.д.
В итоге в контроллере находится огромное количество кода, который уменьшает как качество кода, так и читаемость.
В Symfony была реализована автоподстановка Значений из БД (как MySql, так и Mongo), в виде Entity, но при этом перехватить сообщение, о том, что что-то не найдено - не очень хорошо.
Я предлагаю реализовать классы - Mapper'ы, которые могут проверить полученные данные, отфильтровать их, а только потом предоставить эти данные в контроллер.
Пример такого Mapper'а:
namespace Arilas\User\Mapper;
use Some\Package\RequestMapper;
use Some\Package\Field;
class ProfileMapper extends RequestMapper {
/**
* @var Arilas\User\Entity\User
*/
protected $user;
/**
* @var string
*/
protected $name;
public function init(array $values) {
$user = new Field('user_id');
$user->getFilterChain()
->attach(new Digits())
->attach(new Entity([
'className' => 'Arilas\User\Entity\User',
]);
$name = new Field('name');
$name->setRequired(false);
$name->getFilterChain()
->attach(new StringTrim());
$this
->add($user, 'user')
->add($name)
;
}
public function getUser(){
return $this->user;
}
public function getName(){
return $this->name;
}
public function onError(Request $request){
if ($request->isXMLHttpRequest()) {
$result = new JsonModel();
} else {
$result = new ViewModel();
}
$result->setVariable('success', false);
$result->setVariable('errors', $this->getMessages());
return $result;
}
}
Суть очень похожа на Формы в ZF2, то-есть все те же InputFilter'ы, с Фильтрацией и Валидацией, но при этом этот код должен работать до(!) Контроллера, и предоставлять интерфейс к данным запроса.
Данный подход реализован в большинстве фреймворков на Java, так как это позволяет инкапсулировать данные запроса.
Также при портировании приложения на HACK, в режиме sctrict, типизация запроса смогла бы помочь.