dbms_primeidc/extdbms/lib/Core/App.php
2025-04-02 17:24:23 +09:00

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" . DIRECTORY_SEPARATOR . "Controllers" . DIRECTORY_SEPARATOR . $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, true)) {
$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);
}
}