Обработка HTTP-запросов


Этот класс обрабатывает HTTP-запросы. Это одноэлементный класс, который разбирает URI, чтобы получить контроллер, метод и параметры, а затем выполняется метод контроллера.

Может быть, parseUri должен быть в другом классе и, может быть, слишком много ответственности для данного класса.

Я знаю, что он может быть улучшен. Метод execute может быть лучше, потому что есть некоторые повторяющегося кода.

<?php
class Request
{
    private static $_instance;
    private $_host;
    private $_request_uri;
    private $_script_name;
    private $_controller;
    private $_method;
    private $_parameters;
    private $_headers;

    private function __construct()
    {
        $this->_host = $_SERVER['HTTP_HOST'];
        $this->_request_uri = $_SERVER['REQUEST_URI'];
        $this->_script_name = $_SERVER['SCRIPT_NAME'];
        $this->_headers = array();

        $this->_parseUri();
    }

    private function _parseUri()
    {
        /* In 'http://www.example.com/foo/bar/' get the '/foo/bar/' part */
        $part = str_replace(
            dirname($this->_script_name),
            '',
            $this->_request_uri
        );

        /* break it into chunks and clean up empty positions */
        $chunks = explode('/', $part);
        $chunks = array_filter($chunks);

        if (count($chunks))
        {
            if ($this->_controller = array_shift($chunks))
            {
                $this->_controller = ucfirst($this->_controller) . '_Controller';
            }

            if ($this->_method = array_shift($chunks))
            {
                $this->_method = ucfirst($this->_method) . 'Action';
            }
            $this->_parameters = $chunks ? $chunks : null;
        }
    }

    private function _send_headers()
    {
        foreach($this->_headers as $header)
        {
            header($header);
        }
    }

    public static function instance()
    {
        if (!self::$_instance)
        {
            self::$_instance = new Request();
        }

        return self::$_instance;
    }

    public function execute()
    {
        /* There is a controller ... */
        if (!empty($this->_controller))
        {
            if (!class_exists($this->_controller, true))
            {
                array_push($this->_headers, 'HTTP/1.1 404 Not Found');
                $this->_send_headers();
                return;
            }

            $controller = new $this->_controller();
            /* ... and a method */
            if ($this->_method)
            {
                if (!method_exists($controller, $this->_method))
                {
                    array_push($this->_headers, 'HTTP/1.1 404 Not Found');
                    $this->_send_headers();
                    return;
                }

                $method = new ReflectionMethod(
                    $controller, $this->_method
                );

                /* Do we have parameters? Let's call the right method */
                $this->_parameters
                    ? $method->invokeArgs($controller, $this->_parameters)
                    : $method->invoke($controller);

                array_push($this->_headers, 'HTTP/1.1 200 OK');
                $this->_send_headers();
            }
            /* we don't have a method here, let's call the 'index_action' method */
            else
            {
                $method = new ReflectionMethod($controller, 'indexAction');
                $method->invoke($controller);

                array_push($this->_headers, 'HTTP/1.1 200 OK');
                $this->_send_headers();
            }
        }
        /* We don't have a Controller, let's call the default one. */
        else
        {
            if (!class_exists('Default_Controller', true))
            {
                throw new RequestException("'Default_Controller' class not found.");
            }

            $controller = new Default_Controller();

            if (!method_exists($controller, 'indexAction'))
            {
                throw new RequestException(
                    "'indexAction' method not found in 'Default_Controller' class."
                );
            }

            $method = new ReflectionMethod($controller, 'indexAction');
            $method->invoke($controller);
        }
    }
}
?>


3078
4
задан 25 февраля 2011 в 02:02 Источник Поделиться
Комментарии
1 ответ

Только что-то лил, не пишите закрытия ?> потому что , если есть пробел после а вы попробуйте modifiy заголовок нигде, он не будет работать и вам придется очень долго искать пробелы.

3
ответ дан 26 февраля 2011 в 02:02 Источник Поделиться