2014-07-17 2 views
8

간단한 crud-style 어플리케이션을 위해 Slim Framework를 사용하고 있습니다. 내 index.php 파일은 길고 모든 다른 경로로 다루기 힘들어졌습니다. 이 코드를 어떻게 정리/리팩터링 할 수 있습니까? 예를 들어 나는 모든 다른 경로에 대해 다음과 GET, POST가, PUT과 같은 코드를 가지고, 등경로의 긴 php 파일을 리팩토링하는 방법 (Slim Framework를 사용하고 있습니다)

$app->get("/login", function() use ($app) 
{//code here.....}); 

답변

12

내가하고 싶은 것은 그룹 경로이며 각 그룹에 대해 routes라는 하위 디렉토리 아래에 새 파일을 만듭니다. Slim docs에서 몇 가지 예제 코드와 함께 설명하기 :

의 index.php :

$app = new \Slim\Slim(); 
$routeFiles = (array) glob(__DIR__ . DIRECTORY_SEPARATOR . 'routes' . DIRECTORY_SEPARATOR . '*.php'); 
foreach($routeFiles as $routeFile) { 
    require_once $routeFile; 
} 
$app->run(); 

루트/api.php :

// API group 
$app->group('/api', function() use ($app) { 

    // Library group 
    $app->group('/library', function() use ($app) { 

     // Get book with ID 
     $app->get('/books/:id', function ($id) { 

     }); 

     // Update book with ID 
     $app->put('/books/:id', function ($id) { 

     }); 

     // Delete book with ID 
     $app->delete('/books/:id', function ($id) { 

     }); 

    }); 

}); 

당신은 심지어 여러 수준으로이 작업을 수행 할 수 있습니다 , 당신이 이것을 극 복하지 않도록하십시오.

물론이 기능을 사용할 수도 있습니다.

+1

루트 디렉토리의 모든 파일을 열 때 불필요한 파일로드 (디스크 액세스) 및 구문 분석 (CPU/메모리 사용)이 발생할 수 있으므로 앱이 너무 많이 커지는 경우이 솔루션은 성능 문제가 발생할 수 있습니다 ... – KnF

4

당신은 개의 다른 파일로의 index.php 컨텐츠를 이동하고 그들을 단지를 포함 할 수 있습니다 삭제합니다.

의 index.php :

$app = new \Slim\Slim(); 
... 
require_once 'path_to_your_dir/routes.php'; 
... 
$app->run(); 

routes.php : 다른 경로 유형에 대한

$app->get('/hello/:name', function ($name) { 
    echo "Hello, $name"; 
}); 
... 

또는 당신도 만들 수 있습니다 다른 파일 :

예를 들어 index.php :

$app = new \Slim\Slim(); 
... 
require_once 'path_to_your_dir/routes.php'; 
require_once 'path_to_your_dir/admin_routes.php'; 
require_once 'path_to_your_dir/some_other_routes.php'; 
... 
$app->run(); 

같은 접근 방식은 또한 DI 서비스 초기화 등 (당신의 index.php에 이르기까지)

7

에 대한 괜찮 할 수 있습니다 예를 들어, 이동 코드 클래스 내부 코드 :

$app->get("/login", function() use ($app) 
{ 
    $user = new User(); 
    $user->login(); 
}); 

또는 당신의 index.php에서 다음

class Router { 

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

    public function createRoutes() { 
    $this->app->get("/login", function() use ($this->app) 
    { 
     $user = new User(); 
     $user->login(); 
     }); 

     // other routes, you may divide routes to class methods 
    } 
} 

및 라우팅을 처리 할 자신의 클래스를 생성

$router = new Router($app); 
$router->createRoutes(); 
3

이것은 내가 Slim을 사용하는 방법입니다. 나는 경로가있는 하나의 파일을 가지고 있지만 3 계층 접근법을 사용합니다.

index.php - 여기서 어떤 논리도 처리하지 않습니다. 방금 경로를 등록하고 api 메소드 (게시, 삽입, 삭제 등)를 사용합니다.

$app->post('/bible/comment/', function() use($ioc) { 
    $ioc['commentApi']->post(); 
}); 

API 레이어는 슬림 앱 객체를 삽입하는 기본 클래스를 상속합니다. 거기에서 필자는 헬퍼 메소드를 사용하여 필수 필드, 선택적 필드 등을 사용하여 배열을 사용하여 요청으로부터 데이터를 추출합니다. 여기서 유효성 검사를 수행하지 않습니다. 이것은 또한 내가 xss에 대한 요청을 정리하는 곳이다.

가장 중요한 것은 여기서 예외를 처리합니다. 잘못된 요청은 예외를 throw하고 오류 응답에서 발견되어 변환됩니다.

class CommentApi extends BaseApi { 
    public function post() { 
     $fields = array(array('message', 'bookId', 'chapter', 'verseFrom', 'verseTo')): 
     $dtoModel = new Models\CreateComment(); 
     $data = $this->extractFormData(); 
     Utils::transformDto($dtoModel, $data, $fields): 
     try { 
      $result = $this->commentService->create($this->getUserId(), $dtoModel); 
      $response->success("You've added a book to the bible."); // helper from BaseApi to set the response 200 
      $response->setResult($result); 
     } 
     catch(\Exceptions\CommentRepeatedException $ex) { 
      $response->invalid('The foo already exist. Try a new one'); 
     } 
     catch(\Exceptions\CommentsClosedException $ex) { 
      UtilsExceptions::invalidRequest($dtoModel, $ex); 
      $response->invalid('Invalid request. Check the error list for more info.'); 
     } 
     $this->respond($response); // encode the response in json, set the content type, etc 
} 

이 계층 클래스는 리포지토리 및 기타 리소스를 사용할 비즈니스 계층을 사용합니다. 비즈니스 계층에 대해 프로젝트를 테스트하고 API 레이어는 데이터를 추출하고 dto 모델을 만들고 응답을 처리합니다.

요청/응답 모델은 상태 코드를 반환하는 인터페이스를 구현합니다. 즉, 클라이언트에서 소비 될 erros 메시지입니다 (이 점을 자동화하면 멋지다).

class CommentBusiness { 
    public function create($userId, Models\CreateComment $model) { 
     // Validate the request object 
     // Assert all logic requirements 
     $dataRes = $this->repository->create('message' => $model->getMessage(), 'bookId' => $model->getUserId(), 'chapter' => $model->getChapter(), 'verseFrom' => $mode->getVerseFrom(), 'verseTo' => $model->getVerseTo()); 
     if($dataRes->isInvalid()) { 
      throw new \Exceptions\DataException($dataRes->getExModel()); 
     } 
     return $dataRes; 
    } 
} 
2

나는 클래스같은 경로 콜백을 사용하고, 경로의 그룹과 그 결합 것을 좋아합니다. (당신이 당신의 경로를 정의하기 위해 선택할 때마다 또는)이이 index.php 파일 아마 매우 "슬림"이 될 것이라고 이렇게 :

이 예에서
$app->group('/user', function() use ($app) { 
    $app->map('/find/:id', '\User:search')->via('GET'); 
    $app->map('/insert', '\User:create')->via('POST'); 
    // ... 
}); 

/user/find/:id 경로가 search 메소드를 호출 (:id의 값을 전달 첫 번째 매개 변수)입니다. 그래서 콜백 클래스는 비트 다음과 같습니다

class User { 
    public function search($userId) { 
     // ... 
    } 
} 

당신은 CRUD 스타일의 응용 프로그램 (즉, 데이터베이스 액세스를 필요로) 작성, 특히 이점은,이 방법에있다. 예를 들어, 모든 데이터베이스 로직을 기본 클래스에 포함 할 수 있으며 루트 콜백에 대해 상속 된 하위 클래스를 사용할 수 있습니다. 모든 라우트 그룹 관련 로직을 별도의 클래스로 캡슐화 할 수도 있습니다 (예 : 모든/user 라우트를 처리하는 User 클래스를 갖는 등등.

관련 문제