The PHP Practitioner 09 - Router
29 Dec 2019 | Laracast PHPLaracasts - The PHP Practitioner 강의를 듣고 정리한 포스팅 입니다.
1. Router
어플리케이션의 url을 관장하는 역할(Django의 urls.py). 어플리케이션의 구조를 아래와 같이 좀 더 구체화시킴
- Views: Template의 역할. 브라우저에 보여지는 부분
- Controllers: router에 따라 연결된 controller를 호출하며 각 controller는 정해진 로직에 따라 views와 연결.
- Core: Database, boostrap, 추가적인 클래스 정의
routes.php: root directory에 생성. 연습을 위해 “about”, “about-culture”, “contact”, “index” 페이지에 대한 views, controller, routes를 형성함.
1-1. Controllers & views의 예시
// controllers/about.php
<?php
require 'views/about.view.php';
//views/about.php
<body>
<h1>About Us</h1>
</body>
2. Routes.php
<?php
$router->define([
'' => 'controllers/index.php',
'about' => 'controllers/about.php',
'about/culture' => 'controllers/about-culture.php',
'contact' => 'controllers/contact.php'
]);
//아래와 같이 다양한 방법으로도 표현 가능
//$router->define('', 'controllers/index.php');
//$router->define('about', 'controllers/index.php');
// Router::define('', 'controllers/index.php');
//$router->define('', 'controllers/index.php');
3. core/bootstrap.php
router 관련 로직을 core/Router.php
내 router
클래스에서 구현 & bootstrap.php
와 연결
Request.php
: 서버 내 요청된URI
를trim
하는 클래스가 구현된 파일
<?php
$app = [];
$app['config'] = require 'config.php';
require 'core/Router.php';
require 'core/Request.php';
require 'core/database/Connection.php';
require 'core/database/QueryBuilder.php';
$app['database'] = new QueryBuilder(
Connection::make($app['config']['database'])
);
4. core/Router.php
define
: $routes
를 프로퍼티에 저장하는 메서드
load
: $file
은 routes.php
의미함. routes.php
의 로직에 따라 ($router->define([])
) 의 routing값들이 $routes
에 저장됨.
load
는 스태틱 메서드이므로 인스턴스를 생성하지 않음. 따라서,new static
또는new self
를 사용해야함.- 인스턴스를 생성하지 않으므로
$this
는 사용이 불가능함. 따라서,new static
이 저장된$router
을 return 함.
direct
: 들어온 URI가 실제로 존재하는지 유무를 프로퍼티와 대조하여 검증함 (array_key_exists
) . 존재할 경우, 대응되는 URI를 반환시킴. 존재하지 않을 경우 Throw
<?php
class router
{
protected $routes = [];
public static function load($file) // $file: routes.php
{
// static method는 인스턴스를 생성하지 않는 global method.
// 인스턴스 생성을 위해서는 new static (or new self)
$router = new static;
require $file;
// return $this; static method는 인스턴스를 생성하지 않으므로 $this는 사용이 불가능 함.
return $router;
}
public function define($routes)
{
$this->routes = $routes;
}
public function direct($uri)
{
// about/culture
// 들어온 uri와 매칭되는 key값이 있는지를 routes.php에서 검
if (array_key_exists($uri, $this->routes)) {
return $this->routes[$uri];
}
// 존재하지 않을 경우 Throw
throw new Exception('No route defined for this uri');
}
5. Request.php
<?php
class request
{
public static function uri()
{
return trim($_SERVER['REQUEST_URI'],'/');
}
}
6. index.php
bootstrap.php
를 호출함으로써, router
, request
클래스 등 router에 필요한 모든 로직을 불러올 수 있음.
<?php
require 'core/bootstrap.php';
// option 1.
$router = new Router; // Router 클래스는 bootstrap과 연결되어 있음.
require 'routes.php'; // routes (uri list)를 불러오며 $route(route 인스턴스)의 프러퍼티에 경로 저장.
$uri = trim($_SERVER['REQUEST_URI'],'/'); // URI 경로 trim
require $router->direct($uri); // Router 클래스의 메서드: routes 존재 여부 검사후 redirect.
//die(var_dump($app));
// option 2.
$router = Router::load('routes.php');
require $router-> direct($uri);
// option 3.
require Router::load('routes.php')
->direct(Request::uri());
Comments