Критический абстрактный класс для обработки запросов GET и POST? - PullRequest
3 голосов
/ 31 марта 2011

Меня интересует только обработка запросов GET или POST, поэтому я разработал этот абстрактный класс, чтобы определить, какой запрос был сделан, и впоследствии вызвать соответствующую функцию. Буду очень признателен за отзыв об этом. Спасибо!

PS Я думаю, что это должна быть вики сообщества, но я не уверен, как это установить.

abstract class AHttpRequestHandler
{   
    public function handleRequest()
    {
        if($_SERVER['REQUEST_METHOD'] == 'POST') {
            $this->handlePostRequest();
        } else if($_SERVER['REQUEST_METHOD'] == 'GET') {
            $this->handleGetRequest();
        } else {
            $this->handleIllegalRequest();
        }
    }

    abstract protected function handleGetRequest();
    abstract protected function handlePostRequest();

    protected function handleIllegalRequest()
    {
        throw new Exception('Illegal request detected in HttpRequestHandler::handleIllegalRequest().');
    }
}

В ответ на комментарии:

Я буду обрабатывать только одно или другое (GET или POST), но не оба одновременно. Либо HTML-форма будет отправлена ​​через POST, либо будет выполнено перенаправление со строкой запроса, которая будет GET-запросом. Я не знаю, как можно сделать смешанный запрос (как GET, так и POST), но так как это личный проект, я могу контролировать, происходит ли он или нет.

Я использую класс AHttpRequestHandler (см. Выше), реализуя методы handleGetRequest() и handlePostRequest() в подклассе, который является абстрактным контроллером AController. Затем для каждой страницы моей CMS я создаю подкласс AController, например ImageUpload или ImageDetailsEditor. Я могу предоставить более подробную информацию, если это поможет.

Вот классы AController, Controller и View:

аСопЬгоНег

abstract class AController extends AHttpRequestHandler
{
    protected $view;

    public function __construct()
    {
        $this->handleRequest();
    }

    protected function handleGetRequest()
    {
        throw new Exception('handleGetRequest not yet implemented.');
    }

    protected function handlePostRequest()
    {
        throw new Exception('handlePostRequest not yet implemented.');
    }

    abstract protected function initView();
}

Контроллер

class Controller extends AController
{
    protected $content;

    public function __construct()
    {
        $this->view = new View();
        parent::__construct();
    }

    protected function handleGetRequest()
    {
        $this->content = 'GET Request';
        $this->initView();
    }

    protected function handlePostRequest()
    {
        $this->content = 'POST Request';
        $this->initView();
    }

    protected function initView()
    {
        $this->view->content = $this->content;
        $this->view->display();
    }
}

View

//An over-simplified view for example use only
class View
{
    public $content;

    public function display()
    {
        echo "<p>$this->content</p>";
    }
}

Фактическое использование:

require_once 'Controller.php';
$controller = new Controller();

Ответы [ 3 ]

4 голосов
/ 03 апреля 2011

Прежде всего вы можете сделать запрос GET и запрос POST одновременно. Подумайте о форме, которую вы публикуете, но в URL есть некоторые переменные в запросе (get).

1.Я не понимаю необходимости в таком классе, но первое, что вы можете сделать, это сделать два отдельных класса для post и получить, которые расширяют класс AHttpRequestHandler. Таким образом, вам нужна только абстрактная функция handleRequest, которую вы будете реализовывать в дочерних классах.

2.Вы должны применить «Намерение раскрывающих имен». Ваш класс должен быть RequestHandler, а ваши методы не должны содержать в себе Request. Вы знаете это из названия класса.

3. Подумайте об этом: вам может потребоваться обработать почтовый запрос в одном контроллере. Так что вам придется каждый раз добавлять второй абстрактный метод, чтобы уважать абстрактный класс.

4.Вы не должны совершать круговые звонки между классами (принцип Голливуда). handleRequest вызывается из дочернего класса, а затем родительский вызывает handleGetRequest или handlePostRequest из дочернего класса.

Как я уже сказал, вы разработчик, вы знаете каждый контроллер, который будет использовать: POST или GET (как насчет COOKIE?), Так что вы можете обрабатывать их на уровне контроллера без необходимости дополнительных классов просто ради этого .

0 голосов
/ 07 апреля 2011

Наличие абстрактного класса для запросов - хорошая идея, и она есть во всех средах.Но я не думаю, что это хорошо - расширять этот класс всеми контроллерами.Лучшим решением будет разделить это на два, абстрактный класс запроса и базовый класс контроллера.В классе запроса у вас могут быть методы, позволяющие определить, является ли это запросом на получение или последующим запросом, например

class Request{

public function isPost() {
      return ($_SERVER['REQUEST_METHOD'] == 'POST');
}

    public function isGet() {
      return ($_SERVER['REQUEST_METHOD'] == 'GET');
    }
}

. Также у нас будет базовый класс контроллера с по крайней мере следующими параметрами

class Controller
   {
     public $request;
     public function __construct() {
      $this->setRequest(new Request());
     }

     public function setRequest(Request $request) {
       $this->request = $request;
      }
    }

Все наши клиентские контроллеры будут расширять базовый контроллер как обычно.Преимущество этого метода заключается в том, что клиентские контроллеры могут свободно определять тип запроса.если они хотят использовать запросы GET и POST одновременно, это также будет возможно.Приведенное выше, конечно, неполное.Вам нужно добавить больше методов в базовые классы или нет - ваш выбор.

0 голосов
/ 03 апреля 2011
  1. см. Ссылку
  2. см. Ссылку
  3. см. Ссылку
  4. см. Ссылку
  5. И Контроллер должен получать запрос (команду), а не расширять запрос, чтобы отделить вещи. Не используйте для этого словосочетание, возможно, разделение проблем. Это расширение 1. выше, но только если вам действительно нужен объект запроса.
...