2013-01-12 4 views
3

사용자 정의 프레임 워크에서 컨트롤러를 전환하는 좋은 방법을 이해하려고합니다. 다음 예제는 현재 시범 적으로 단순화 된 것으로 생각하지만 더 나은 접근 방법이 있으면 전문가의 조언을 듣는 것이 좋습니다.컨트롤러 간 전환 (MVC)

class BaseController() { 
    function __construct() { 
     $this->model = new ModelFactory(); 
     $this->view = new View(); 

     if(isset($_SERVER['QUERY_STRING'])) { 
      list($controller, $action) = explode('=', $_SERVER['QUERY_STRING']); 
      self::process($controller); 
     } 
    } 

    public function process($controller) { 
     switch($controller) { 
      case 'user': 
       $user = new UserController($action); 
      break; 

      case 'forum': 
       $forum = new ForumController($action); 
      break; 

      default: 
       // use base controller 
       switch($action) { 
        case 'contact': 
         $this->view->load($action); 
        break; 
       } 
     } 
    } 
} 

// inside UserController.php 
switch($action) { 
    case 'register': 
    break; 

    case 'login': 
    break; 
} 

// inside ForumController.php 
switch($action) { 
    case 'new_thread': 
    break; 

    case 'edit_post': 
    break; 
} 
+1

프레임 워크 사용자가 사용자 지정 작업을 통해 사용자 지정 컨트롤러를 구현할 수 있도록 계획 하시겠습니까? –

+0

@ bob-the-destroyer 그렇게하면 코드가 더 다양해질 것이고, 그렇다고 가정한다면, 그렇습니다. –

답변

3

이것은 실제로 당신에게 좋은 조언을 줄 부분 답변입니다. 더 나은 대답을 가진 사람이 올 것이라고 확신합니다.

  1. 예에서 BaseController의 이름이 잘못되었을 수 있습니다. 가지고있는 것은 다른 컨트롤러 클래스가 파생 할 수있는 기본 컨트롤러보다 컨트롤러 팩터 리처럼 보이게 만듭니다. 이것은 "라우팅"클래스에 가깝기 때문에 더 적절한 이름을 부여하는 것이 좋습니다.

  2. 당신은 당신의 프레임 워크 사용자가 사용자 지정 작업과 사용자 정의 컨트롤러를 만들려면 :

    가) 당신은 확실히 모든 컨트롤러 클래스 구현하기위한 최소한의 인터페이스를 만들 수 있습니다. IController 또는 이와 비슷한 이름으로 지정하십시오. 이것은 다음 단계에서 사용됩니다.

    b) 문자열을 클래스 이름으로 사용하여 개체를 생성해야합니다. "Route"처리기 클래스 내의 IE $controllerObject = new $controller();. 그 이유는 컨트롤러와 액션 이름을 요청 URL에서 곧바로 실행해야하기 때문입니다. 이 부분을 앨리어싱하는 방법이 있지만, 그것은 또 다른 질문입니다. 이 아니면 클라이언트에서 전달 된 이러한 "컨트롤러"클래스 이름의 유효성을 검사하거나 화이트리스트에 등록하는 것을 잊지 마십시오. 유효성을 검사하려면 PHP 함수 class_exists($controller)을 사용하고 true 인 경우 PHP 클래스 class_implements($controller)을 사용하여 컨트롤러 클래스가 IController을 구현하는지 확인하십시오. 다음 컨트롤러 개체를 실제로 만들려면 $controllerObject = new $controller();해야합니다. 즉, 이름 (컨트롤러가 어떤 방법을 선언하지 마십시오)

    public function process($controller, $action) { 
        if (!class_exists($controller)) { 
         throw new Exception('Controller class does not exist.'); 
        } 
        if (!in_array("IController", class_implements($controller))) { 
         throw new Exception('Route is not a valid controller.'); 
        } 
        if (!method_exists($controller, $action)) { 
         throw new Exception('No such action for requested controller.'); 
        } 
        $ctrl = new $controller(); 
        return $ctrl->$action(); 
    } 
    

    C :

    당신의 "경로는"process 방법은 더 같은 것을하게 (그리고 이것은 매우 단순화 된 예입니다 명심) 어떤 값이든 $action 일 수 있습니다.) 위의 디자인 패턴을 사용하여 클라이언트가 직접 실행하는 것을 원하지 않습니다. 바라건대 프레임 워크 사용자도이 점을 이해하기 바랍니다. 프레임 워크 사용자가이를 알 수 있도록 내부적으로 어떻게 작동하는지 올바르게 문서화하십시오.

물론 그 이상의 방법이 있지만 그게 프레임 워크 디자이너입니다. 또한, 행동은 "보기"에서 사용할 최종 의견을 가져야합니다. 액션에서 명시 적으로보기를 사용하지 않을 경우 기본값을 설정하는 방법이 있습니다. 하지만 또 다른 질문이있을 것입니다.

+0

+1은 클래스의 이름을 변경합니다. 컨트롤러에 대한 부모 기본 클래스가 있다고 가정하면 이름에 대해 훨씬 더 나은 선택입니다. – Chief

0

실제로 MVC가 실제로 무엇인지 읽어야합니다. 파울러의 GUI Architectures으로 시작하는 것이 좋습니다. 한 가지는 확실히 확신합니다. 당신이 가지고있는 것은 그렇지 않습니다.

이름이 BaseController 인 것처럼 보이지만 실제로 라우팅을 처리하고 있습니다. 그것은 사용자의 요청 URL을 포함하고 URL에서 검색 한 내용을 기반으로 한 파일을 포함합니다. 이것은 OOP 또는 절차 프로그래밍이 아닙니다. 당신이 가지고있는 것은 non-structured programming입니다.

대신이 응용 프로그램의 라우팅 메커니즘을 구현하는 별도의 클래스를 만들어야합니다. 그리고 데이터를 기반으로 구조체를 추출한 다음 특정 컨트롤러 인스턴스를 시작하고 그에 대한 메서드를 호출해야합니다. 같은

뭔가 : 물론

$request = new Request('QUERY_STRING'); 

$router = new Router; 
$router->import('/path/to/routing/config.file'); 
$router->route($request); 

$klass = $request->getParameter('controller'); 

if (class_exists($controller)) 
{ 
    $command = $request->getMethod() . $request->getParameter('action'); 
} 
else 
{ 
    $klass = 'Error'; 
    $command = 'getMessage'; 
} 

$controller = new $klass; 
$controller->{$command}($request); 

이는 매우 단순화 된 버전입니다. MVC 패턴은 대규모 프로젝트에 어떤 명령을 내리기위한 것입니다. 간단한 블로그/비즈니스 카드 웹 사이트와 같은 것을 만들기 위해이 도구를 사용하면 과장된 것처럼 보일 수 있습니다 (페이지가 성장하지 않는다고 가정).

P.this, this, thisthis과 같은 유용한 링크를 찾을 수 있습니다.