복붙노트

PHP의 MVC 뷰 이해하기

PHP

PHP의 MVC 뷰 이해하기

MVC에서 Views의 개념을 파악하는 데 문제가있는 것처럼 보입니다. 필자가 읽은 바에 따르면, 응용에서 프레젠테이션을 관리하는 계층이지만, 내가 읽었던 많은 자료는이 점에있어서 다른 것처럼 보입니다. 이것에서 PHP Master.com의 문제.

보기는 일부 HTML 코드를 반환하는 함수가있는 클래스입니다. 나머지 HTML은 어디에 있습니까? 이 View 코드에 액세스하는 독립적 인 .html 페이지에 넣어야합니까?

이 기사에서 php-html.net의 View는 확장자가 .php 인 간단한 HTML 파일이지만 데이터에 어떻게 액세스하고 있습니까? 첫 번째 튜토리얼에서는 인스턴스화와 같은 require () 또는 어떤 것도 볼 수 없다.

해결법

  1. ==============================

    1.

    MVC 및 MVC에서 영감을 얻은 디자인 패턴의 핵심 아이디어는 Separation of Concerns입니다. 상기 분리는 두 가지이다 :

    모델 계층 ( "클래스"또는 "객체"가 아닌)은 비즈니스 논리의 서로 다른 측면을 다루는 여러 그룹의 구조를 포함합니다. 주요 부분은 다음과 같습니다.

    또한 저장소, 작업 단위 및 다른 것들이 섞여있을 수도 있습니다.

    UI 레이어는 대부분 뷰와 컨트롤러로 구성됩니다. 그러나 둘 다 서비스를 활용하여 모델 계층과 상호 작용합니다. 서비스는 컨트롤러가 모델 계층의 상태를 변경하고 뷰가 새로운 상태를 기반으로 정보를 수집하는 방법을 제공합니다.

    웹 컨텍스트에서보기와 컨트롤러는 느슨한 쌍을 형성합니다. 웹 응용 프로그램이 표시하는 요청 - 응답 특성 때문입니다.

    컨트롤러가 현재 뷰의 상태를 직접 변경할 수는 있지만 이러한 변경 사항은 모델을 통해 영향을 받는다는 것이 일반적입니다. 보기를 직접 변경하는 한 가지 이유는 예를 들어 XML 대신 JSON으로 응답해야하는 경우입니다.

    각각의 출력 형식에 대해 다른 뷰를 간단하게 인스턴스화하고 다형성을 활용할 수 있다고 주장 할 수도 있습니다.

    보기가 단순히 찬사를받은 템플릿 파일이라는 오해가 널리 퍼져 있습니다. 이 실수는 RubyOnRails 프로토 타입 제작 프레임 워크가 출시 된 이후 매우 인기가있었습니다.

    뷰는 템플릿이 아닙니다. 이와 같이 사용하면 MVC 및 MVC에서 영감을 얻은 패턴의 핵심 원리를 깨뜨릴 수 있습니다.

    템플릿이 뷰인 것처럼 보이면 아키텍처에 엄청난 영향을 미칩니다. 뷰에 프리젠 테이션 로직을위한 공간이 없기 때문에 컨트롤러 또는 모델 레이어에서 프리젠 테이션 로직을 푸시합니다. 대부분의 사람들은 프리젠 테이션 로직이 모델 레이어에 없다는 것을 알고 있기 때문에 보통 "컨트롤러"가 선택됩니다.

    본질적으로 이것은 뷰와 컨트롤러의 합병을 야기합니다.

    이 견해의 책임은 표현 논리를 다루는 것입니다. 웹 컨텍스트에서보기의 목표는 사용자에게 응답을 생성하는 것입니다 (btw는 인간이 아닌 브라우저입니다).

    이 응답보기를 만들려면 모델 계층에서 정보를 가져오고 수집 된 데이터를 기반으로 데이터를 템플릿에 배포하고 렌더링하거나 때로는 HTTP 위치 헤더를 보내는 방식으로 응답을 어셈블합니다.

    최근에 나는 다음과 같은 접근 방식을 사용하여 MVC와 상호 작용하는 것을 선호했다.

      // the factory for services was injected in constructors
      $controller->{ $method.$command }($request);
      $view->{ $command }();
      $view->respond();
    

    $ 메소드는 현재 REQUEST_METHOD이며, REST와 유사한 API를 가짜로 조정했으며, $ 명령은 사람들이 일반적으로 "액션"이라고 부르는 것입니다. 컨트롤러에는 GET 및 POST (다른) 요청에 대한 별도의 루틴이 있습니다. 이렇게하면 모든 "행동"에서 동일한 if를 피하는 데 도움이됩니다.

    보기에서 나는 두 가지 방법을 호출합니다. 첫 번째는 데이터 수집을위한 동적 호출입니다. 두 번째 목표는 어떤 유형의 응답을 만드는 것입니다.

    이미 눈치 챘을 수도 있듯이보기를 인스턴스로 갖는 데 약간의 문제가 있습니다. 당신은 반복되는 코드 조각들로 끝날 것입니다. 예 : 메뉴 또는 페이지 매김.

    페이지 매김을 살펴 봅니다 .. 페이지 매김에는 로직이 포함되어 있지만이 로직은 모델 레이어와 관련이 없습니다. 모델에는 "페이지"개념이 없습니다. 대신이 로직 비트는 UI 레이어에 상주합니다. 그러나 각 의견에 페이지 매김이 포함되거나 상속되는 경우 SRP에 대한 명확한 위반이됩니다 (실제로 여러 가지 다른 원칙도 있음).

    이 문제를 피하기 위해 IMHO에서 프레젠테이션 개체를 뷰에 도입 할 수 있습니다.

    프리젠 테이션 오브젝트는 반복되는 로직을 처리합니다. 이로 인해보기가 훨씬 가벼워지고 일부 측면에서는 모델 계층에서 서비스 구조를 미러링하기 시작합니다.

    프리젠 테이션 객체와 템플릿 간의 상호 작용은 도메인 객체와 데이터 맵퍼 간의 상호 작용과 유사합니다.

    아닙니다.이 특정 접근법은 코드에 중점을 두었습니다. UI 레이어는 많은 복잡성을 가지고 있으며 입력 처리를 프레젠테이션과 제정의 제물로 구분해야합니다.

    귀하의 응용 프로그램에 매우 간단한 UI가 있다면 .. emm .. 당신은 더 큰 통합 프로젝트를 위해 REST API를 만들고 있습니다. 그런 실용적인 옵션에서 모든 컨트롤러 -보기 쌍을 단일 클래스로 병합하는 것이 가능합니다.

    또한 레거시 코드베이스를 리팩토링 할 때 좋은 단계가 될 수 있습니다.이 제한이없는 접근 방식을 사용하면 전체 코드를 이동할 수 있기 때문입니다. 이전 코드를 분리하여 검사하면 모든 것이 여전히 작동합니다 (레거시 코드는 테스트를 거치지 않으므로 "레거시"가됩니다). 그런 다음 비즈니스 로직을 분리하는 데 주력하면서 더 이상 분리 할 수 ​​있습니다 UI에서.

  2. ==============================

    2.두 번째 튜토리얼은 Code Igniter 프레임 워크가 작동하는 방식과 내가 익숙했던 방식입니다. 나는 전혀 프레임 워크를 사용하지 않을 때에도 그것을 따른다.

    두 번째 튜토리얼은 Code Igniter 프레임 워크가 작동하는 방식과 내가 익숙했던 방식입니다. 나는 전혀 프레임 워크를 사용하지 않을 때에도 그것을 따른다.

    실제로 개발자는 MVC와 같은 원칙을 실제로 적용해야하며, 그렇지 않으면 MVC와 유사한 지향 프레임 워크를 사용하여 라자냐 또는 스파게티를 만들 수 있습니다.

    기본적으로 반복 구조 (foreach ($ array as $ item)), 기본 조건문 (if ($ boolean)) 및 echo -와 같이 최소한 PHP 구문을 사용하는 것이 가장 이상적입니다. 그것은 참으로 템플릿 언어 였고 그 이상은 아니 었습니다.

    따라서 뷰 템플릿 파일의 태그는 단지 자리 표시 자일 뿐이고 다른 것은 없습니다.

    뷰 템플릿 파일에서는 데이터베이스 쿼리, 모델 액세스, 계산 등을 수행하지 않아야합니다. 기본적으로 자리 표시자를 사용하여 HTML 파일로 처리해야합니다. (관련 CSS와 자바 스크립트로, 애플리케이션이 자바 스크립트 / AJAX를 많이 사용하는 경우 상황이 더 복잡해 질 수 있습니다 ...)

    이 간단한 원칙에 따라 우리는 프레젠테이션을 비즈니스 논리에서 효과적으로 분리합니다. 너무 단순하게 들리는데, 나는 그것을 따르지 않는 Code Igniter 코드를 다루는데 지쳤습니다. 일부는 모델 / 데이터베이스 호출을 가장하기 위해 "도우미 함수"를 사용합니다 - 그리고 좋은 연습이라고 생각하십시오! :-)

    대신에 "view building"메소드에서 필요하기 때문에이 PHP 뷰 템플릿 파일 안에 require가 표시되지 않습니다.

    물론 컨트롤러 및 모델 기능 내부에서 에코 및 / 또는 인쇄를해서는 안됩니다. 이것은 또한 매우 간단하지만, CI 컨트롤러 메소드 내부에서 HTML을 반향시키는 스파게티 코드를 보느라 피곤합니다.

    실제로, 컨트롤러는 모델 메소드를 호출하고, 뷰에 필요한 모든 데이터를 빌드하고, 마지막 단계로서 뷰를 호출 (즉, 빌드 및 출력)하고 이미 획득 한 데이터를 뷰에 전달합니다.

    말이된다? 나는 당신의 질문에 대답했는지 모르겠습니다. 적어도, 이들은 나의 "2 센트"입니다.

  3. ==============================

    3.다른 프레임 워크는 다른 로직을 사용하여 변수를 지정하여 해당 내용을보고 가져옵니다. 다음은 ob_start () 함수를 사용하는 간단한 예제입니다.

    다른 프레임 워크는 다른 로직을 사용하여 변수를 지정하여 해당 내용을보고 가져옵니다. 다음은 ob_start () 함수를 사용하는 간단한 예제입니다.

    <?php
         $title = 'Hello...';
         ob_start();
         file_get_contents('view.phtml');
         $viewContents = ob_get_clean();
         echo $viewContents;
    
    ?>
    
    //view.phtml
    <b>Hello the title is <?php echo $title; ?></b>
    

    희망이 답변을 귀하의 질문 ...

  4. ==============================

    4.당신은 출력 형식에 독립적 인 뷰를 빌드하는 데 필요한 모든 것을 뷰 클래스에 전달해야합니다. 대부분의 개발자는 일종의 템플릿 엔진을 사용하여 대량의 페이지를 작성한 다음 요청 정보를 사용하여 본문을 채 웁니다. 당신이 이것을하는 것에 대해 갈 수있는 많은 방법들이 있습니다. 양식과 입력과 같은 공통 요소에 대한 도우미 메서드를 정의하는 추상 뷰 클래스를 갖는 것도 좋습니다.

    당신은 출력 형식에 독립적 인 뷰를 빌드하는 데 필요한 모든 것을 뷰 클래스에 전달해야합니다. 대부분의 개발자는 일종의 템플릿 엔진을 사용하여 대량의 페이지를 작성한 다음 요청 정보를 사용하여 본문을 채 웁니다. 당신이 이것을하는 것에 대해 갈 수있는 많은 방법들이 있습니다. 양식과 입력과 같은 공통 요소에 대한 도우미 메서드를 정의하는 추상 뷰 클래스를 갖는 것도 좋습니다.

    디자인이나 출력 형식을 어떤 식 으로든 변경하려는 경우 응용 프로그램의 논리를 변경할 필요가 없도록이 계층을 추상화합니다.

    편집하다: MVC 세트로 표현되는 각 모듈에는 출력을 브라우저에 전송하는 메소드 콜렉션이있는 자체 뷰가 있습니다. 당신이 갈 수있는 많은 방법이 있지만 여기에 하나의 예가 있습니다 :

    class testModule_view extends viewAbstract {
        public function showTestData($title, $subtitle, $data) {
            $XHTML = '<h1>' . $title . '</h1>'
                . '<h2>' . $subtitle . '</h2>'
                . parent::data2table($data);
    
            parent::outputToBrowser(DEFAULT_TEMPLATE, $XHTML);
        }
    }
    

    이것은 간단한보기 메소드가 어떤 모양인지 알 수있는 간단한 예입니다.

  5. ==============================

    5.브라우저가 페이지를 호출하면 컨트롤러가로드됩니다. 컨트롤러는 앱의 라이프 사이클을 관리합니다. 그는 데이터를 가져 오는 데만 사용되는 모델에서 데이터를 가져옵니다 (아마도 데이터베이스에서). 뷰는 HTML 만이며, 컨트롤러는 뷰를 반향시키고 필요한 경우 몇 개의 매개 변수를 전달합니다.

    브라우저가 페이지를 호출하면 컨트롤러가로드됩니다. 컨트롤러는 앱의 라이프 사이클을 관리합니다. 그는 데이터를 가져 오는 데만 사용되는 모델에서 데이터를 가져옵니다 (아마도 데이터베이스에서). 뷰는 HTML 만이며, 컨트롤러는 뷰를 반향시키고 필요한 경우 몇 개의 매개 변수를 전달합니다.

  6. ==============================

    6.

    <?php
    

    class View {

    protected $data;
    
    protected $path;
    
    protected static function getDefaultViewPath() {
        $router = App::getRouter();
    
        if(!$router){
            return false;
        }
    
        $controller_path = $router->getController();
        $method_path = ($router->getMethodPrefix() !== "" ? $router->getMethodPrefix() . '_' : '') . $router->getAction();
    
        return ROOT . "/views/" . $controller_path . "/" . $method_path . ".phtml";
    }
    
    public function __construct($data = array(), $path = null) {
    
        if(!$path){
            //default
           $path = $this->getDefaultViewPath();
        }
    
        if(!file_exists($path)){
            throw new Exception("Error view file!");
        }
    
        $this->data = $data;
        $this->path = $path;
    }
    
    
    public function render(){
        $data = $this->data;
    
        ob_start();
        include ($this->path);
        $content = ob_get_clean();
    
        return $content;
    }
    

    }

  7. ==============================

    7.이 코드를 확인하십시오 :

    이 코드를 확인하십시오 :

    include_once(ROOT.'/'.'config/config.php');
    
    function __autoload($class_name){
        $lib_path = ROOT . '/' . 'lib/class.'.$class_name . '.php';
        $controller_path = ROOT . '/' . 'controllers/'.str_replace("controller", "", strtolower($class_name)) . '.controller.php';
        $model_path = ROOT . '/' . 'models/'.strtolower($class_name) . '.php';
    
    if(file_exists($lib_path)){
        require_once ($lib_path);
    } else if (file_exists($controller_path)){
        require_once ($controller_path);
    } else if(file_exists($model_path)){
        require_once ($model_path);
    } else {
        throw new Exception("File {$class_name} cannot be found!");
    }
    
    }
    
  8. from https://stackoverflow.com/questions/16594907/understanding-mvc-views-in-php by cc-by-sa and MIT license