146 lines
4.4 KiB
PHP
146 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace lib\Core;
|
|
|
|
use lib\Core\Controller;
|
|
|
|
abstract class App
|
|
{
|
|
private string $_url = "";
|
|
private string $_module = "";
|
|
protected ?Controller $_controller;
|
|
protected string $_method = "";
|
|
protected array $_segments = [];
|
|
|
|
public function __construct(string $url)
|
|
{
|
|
$this->_url = $url;
|
|
$this->init();
|
|
}
|
|
final public function getURL(): string
|
|
{
|
|
return $this->_url;
|
|
}
|
|
private function init(): void
|
|
{
|
|
$path = parse_url($this->getURL(), PHP_URL_PATH);
|
|
$arguments = explode('/', trim($path, '/'));
|
|
// var_dump($arguments);
|
|
//컨트롤러와 메서드를 설정
|
|
$this->setModule($arguments);
|
|
$this->setController($arguments);
|
|
$this->setMethod($arguments);
|
|
// 남은 세그먼트를 파라미터로 설정
|
|
$this->setSegments($arguments);
|
|
}
|
|
protected function routeModule(string $route): string
|
|
{
|
|
return $route;
|
|
}
|
|
protected function routeController(string $route): string
|
|
{
|
|
return ucfirst($route . 'Controller');
|
|
}
|
|
protected function routeMethod(string $route): string
|
|
{
|
|
return $route;
|
|
}
|
|
final protected function getModule(): string
|
|
{
|
|
return $this->_module;
|
|
}
|
|
private function setModule(array &$segments): void
|
|
{
|
|
$route = count($segments) ? $segments[0] : '';
|
|
$route = $this->routeModule($route);
|
|
$module = "lib\\Controllers\\" . $route;
|
|
if (is_dir(ROOT_PATH . DIRECTORY_SEPARATOR . $module)) {
|
|
array_shift($segments);
|
|
$this->_module = $module . DIRECTORY_SEPARATOR;
|
|
}
|
|
}
|
|
final protected function getController(): Controller
|
|
{
|
|
return $this->_controller;
|
|
}
|
|
private function setController(array &$segments): void
|
|
{
|
|
$route = count($segments) ? $segments[0] : 'Home';
|
|
$route = $this->routeController($route);
|
|
$controller = $this->getModule() . $route;
|
|
if (class_exists($controller)) {
|
|
$this->_controller = new $controller();
|
|
} else {
|
|
throw new \Exception("[{$controller}] 해당 Controller를 찾을수 없습니다.");
|
|
}
|
|
array_shift($segments);
|
|
}
|
|
final protected function getMethod(): string
|
|
{
|
|
return $this->_method;
|
|
}
|
|
final protected function setMethod(array &$segments): void
|
|
{
|
|
//$segments[0]인이유는 setController에서 $segments를 array_shift했기때문
|
|
$route = count($segments) ? $segments[0] : 'index';
|
|
// echo "METHOD:{$route}\n";
|
|
$method = $this->routeMethod($route);
|
|
// echo get_class($this->getController()) . ",METHOD2:{$method}\n";
|
|
if (method_exists($this->getController(), $method)) {
|
|
array_shift($segments);
|
|
} else {
|
|
throw new \Exception("해당 함수[{$method}]를 " . get_class($this->getController()) . "에서 찾을수 없습니다.");
|
|
}
|
|
$this->_method = $method;
|
|
}
|
|
final public function getSegments(): array
|
|
{
|
|
return $this->_segments;
|
|
}
|
|
final protected function setSegments(array &$segments): void
|
|
{
|
|
// 세그먼트 배열을 key/value 쌍으로 변환
|
|
$params = [];
|
|
for ($i = 0; $i < count($segments); $i += 2) {
|
|
if (isset($segments[$i + 1])) {
|
|
$params[$segments[$i]] = $segments[$i + 1];
|
|
}
|
|
}
|
|
$this->_segments = $params;
|
|
}
|
|
final public function run(): mixed
|
|
{
|
|
$controller = $this->getController();
|
|
$method = $this->getMethod();
|
|
// 컨트롤러에 세그먼트 전달
|
|
$controller->setSegments($this->getSegments());
|
|
// 키/값 형태로 세그먼트 처리
|
|
$params = [];
|
|
$segments = $this->getSegments();
|
|
// 메서드의 매개변수 정보 가져오기
|
|
$reflectionMethod = new \ReflectionMethod($controller, $method);
|
|
$parameters = $reflectionMethod->getParameters();
|
|
if (count($parameters) > 0) {
|
|
// 매개변수가 존재하면 URL 세그먼트를 순서대로 매개변수에 매핑
|
|
foreach ($parameters as $i => $param) {
|
|
// 매개변수 이름을 가져와서 세그먼트에서 값을 찾기
|
|
$paramName = $param->getName();
|
|
if (isset($segments[$paramName])) {
|
|
$params[] = $segments[$paramName];
|
|
} else if (isset($segments[$i])) {
|
|
$params[] = $segments[$i];
|
|
} else if ($param->isDefaultValueAvailable()) {
|
|
$params[] = $param->getDefaultValue();
|
|
} else {
|
|
$params[] = null;
|
|
}
|
|
}
|
|
} else {
|
|
// 매개변수가 없으면 빈 배열 전달
|
|
$params = [];
|
|
}
|
|
|
|
return call_user_func_array([$controller, $method], $params);
|
|
}
|
|
}
|