Мне все больше и больше нравится использовать Spring. Возможно вскоре напишу более обширный сравнительный обзор между Spring и Zend Framework, а пока что просто пример.
Представьте что вы создаете серьезное отказоустойчивое и защищенное приложение. Например биллинг. Как должен быть реализован контроллер для вывода какого-либо объекта по его id?
ZendFramework style:
class SomeController extends Zend_Controller_Action { public function viewAction() { $id = $this->getRequest()->getParam( 'id' ); if ( empty( $id ) ) { throw new MissingRequestParameterException( 'Action requires "id" parameter' ); } if ( !is_numeric( $id ) ) { throw new TypeMismatchException( '"id" param must be integer' ); } $id = intval( $id ); // тут переменная готова к использованию $obj = SomeRepository::get( $id ); $this->view->obj = $obj; } }
Spring style:
@Controller @RequestMapping( value="/some/*" ) public class SomeController { @RequestMapping ( method=RequestMethod.GET ) public ModelAndView view( @RequestParam( value="id" ) Integer id ) { // тут переменная готова к использованию Obj obj = SomeRepository.get( id ); return new ModelAndView( "view", "obj", obj ); } }
В ZF можно не писать так много кода в экшне. У роута могут быть variable requirements.
Т.е можно написать так:
$route = new Zend_Controller_Router_Route(
‘ view/:id’,
array(
‘controller’ => ‘some’,
‘action’ => ‘view’
),
array(‘id’ => ‘\d+’)
);
$router->addRoute(‘some-view’, $route);
http://framework.zend.com/manual/en/zend.controller.router.html#zend.controller.router.routes.standard.variable-requirements
Согласен — можно, но отрыв от контекста все же остается и получать из request и приводить к типу переменную все-равно будет нужно
Немного допилив Zend_Controller_Action можно получить маппинг параметров из request-a в параметры метода: http://fbdevzone.com/2009/10/request-parameter-mapping/
Для этого нужно «допилить», что может быть подвержено ошибкам. В Спринг же это предусмотрено из коробки.
Вообще я как бы не говорю что Зенд и ПыХыПы — сакс. Нет. Просто привожу примеры того с чем доводиться сталкиваться при решении подобных задач разынми инструментами
это называется манипуляция фактами.
контроллер может выглядеть так:
public function viewAction() {
$this->view->obj = SomeRepository::get($this->_getParam(‘id’));
}
Нисколько. Вы привели пример слоя бизнес логики, а я — контроллера.
Возможно эта дискуссия выходит за рамки данного поста, но было бы весьма интересно узнать что вы имеете в виду под понятием «слой бизнес логики» и «слой контроллера» и в чем их принципиальное отличие, если таковое есть.
а я всего лишь перенес информацию о валидации и типе идентификатора внутрь фабрики, где, на мой взгляд, ей самое место.
я имел ввиду это
нда, как все запущено :)
ок. спрошу по другому
чем принципиально отличается:
public function viewAction() {
$this->view->obj = SomeRepository::get($this->_getParam(’id’));
}
от:
public function viewAction() {
$id = $this->getRequest()->getParam( ‘id’ );
if ( empty( $id ) ) {
throw new MissingRequestParameterException( ‘Action requires «id» parameter’ );
}
if ( !is_numeric( $id ) ) {
throw new TypeMismatchException( ‘»id» param must be integer’ );
}
$id = intval( $id );
// тут переменная готова к использованию
$obj = SomeRepository::get( $id );
$this->view->obj = $obj;
}
Принципиально в отказоустойчивости приложения. Суть поста в том что в Spring не надо проверять тип переменной только если к null, её значение и приводить в последствии к определенному типу, который в послествии гарантирует безопастность использования данной переменной в бизнес логике.