Как спроектировать мой сайт, чтобы он служил веб-сервисом с использованием MVC? - PullRequest
0 голосов
/ 22 марта 2011

Мне интересно, как лучше спроектировать мой сайт, который должен выводить HTML для браузера и JSON для мобильного устройства в структуре MVC (Model-View-Controller).

Моя идея состоит в том, чтобы просто добавить оператор if / else, чтобы определить вывод HTML или JSON в действиях в контроллере, но я чувствую, что есть лучший (или более гибкий) способ сделать это.

Кто-нибудь может рассказать мне об этом или сказать, какие ключевые слова я должен использовать для поиска?

Спасибо!

Ответы [ 3 ]

1 голос
/ 22 марта 2011

Вы в основном ищете слой абстрагированного представления. Для этого я бы определил интерфейс представления, который просто принимает данные и возвращает строковый ответ. Примерно так:

interface View {
    function render($viewName, $data);
}

Теперь вы можете создать реализацию этого:

class PhpFileView implements View {
    private $baseDir;
    private $format;

    public function __construct($baseDir) {
        $this->baseDir = $baseDir;
        $this->format = 'html';
    }

    public function setFormat($format) {
        $this->format = $format;
    }

    public function render($viewName, $data) {
        ob_start();
        require "{$this->baseDir}/$viewName.{$this->format}.php";
        return ob_get_clean();
    }
}

Теперь вы можете дать вашему контроллеру экземпляр класса PhpFileView и сделать что-то вроде этого:

class MyController {
    protected $view;

    public function __construct($config) {
        $this->view = new PhpFileView($config['view_dir']);
    }

    public function indexAction($params) {
        $this->view->setFormat($params['format']);
        return $this->view->render('my/index', array(
            'some_var' => 'some value',
        ));
    }
}

$config = array('view_dir' => 'app/views');
$controller = new MyController($config);
// format could be dynamically set to 'xml', yaml, anything
$params = array_merge($_REQUEST, array('format' => 'html'));
echo $controller->indexAction($params);

Это дает вам большую гибкость, поскольку вы можете установить любой формат, который вы хотите, в $params['format'], который затем используется для включения $viewdir/$viewName.$format.php. В нашем примере это будет отображать app/views/my/index.html.php.

Внутри этого файла представления у вас есть доступ к переменной $data. Таким образом, вы могли бы сделать что-то вроде <?php echo $data['some_var']; ?>.

Большим преимуществом такой системы является то, что вы можете легко добавить поддержку для механизмов альтернативного представления, таких как Twig (вам следует взглянуть на это).

0 голосов
/ 22 марта 2011
//From ur controller.
public handleResponse($responseData)
{
   $responseInf = Util::getResponseObject($headers,$responseData);
   $responseInf->flushOutput();
} 


class Util
{
   static function getResponseObject($headers,$responseData)
   {
       $responseInf = false;
       if($headers specific mobile)
         $responseInf = new JSON_Output($responseData);
       else
         $responseInf = new HTML_Output($responseData);

       return $responseInf;
   }
}

Interface ResponseInf
{
   public function flushOutput();
}

class JSON_Output implements ResponseInf
{
    private $responseData = false;

    function ___construct($data)
      $this->responseData = $data;

    public function flushOutput()
    {
       //Convert $this->responseData to JSON object
       //flush json object from here.
    }
}

class HTML_Output implements ResponseInf
{
    private $responseData = false;

    function ___construct($data)
      $this->responseData = $data;

    public function flushOutput()
    {
       //Convert $this->responseData to HTML string 
       //flush html from here.
    }
}
0 голосов
/ 22 марта 2011

Лучше было бы использовать отдельные представления для HTML и JSON.

В правильно реализованных средах MVC вы можете установить класс представления (или шаблон), который будет использоваться для визуализации вывода.Это может быть JSON, HTML, XML или любой другой.

...