0. 핵심 규칙 (먼저 읽기)
- 모든 HTTP 요청은 루트
index.php하나로 들어온다.core/,admin/등의 PHP 파일은 직접 실행되지 않는다(웹서버가 차단). - 라우터는 두 겹이다. 먼저
DxRouter(라라벨 스타일,routes/*.php)가 매칭을 시도하고, 하나도 매칭되지 않을 때만Router+Dispatcher(기존 URL 규칙 기반)가 실행된다. - 새 URL을 추가할 때의 기본 선택:
routes/web.php에DxRouter로 추가한다. 코어 파일(Router.php,Dispatcher.php)은 업그레이드 시 덮어써지므로 수정하지 않는다. - 파일 시작은 항상
if (!defined('DX_CMS')) exit('Direct access not allowed.'); DxRouter로 등록한 라우트는extend/middle/을 실행하지 않고$GLOBALS['dx_route']도 세팅되지 않는다. (§6, §9)DxRouter의csrf미들웨어는 존재하지 않는 함수를 호출한다. 쓰지 말 것. (§5.4)- URL 생성은 항상
dx_base_url('path'). 하드코딩/path금지(서브디렉토리 설치·url_rewrite=0환경에서 깨진다).
1. 요청 처리 흐름
브라우저
→ .htaccess / nginx try_files → index.php
index.php
STEP1 core/*.php 로드 (Router, Dispatcher, DxRouter, DxContainer 포함)
STEP2 세션·보안 헤더
STEP3 data/config.php 로드 (DB 연결)
STEP4 load_plugins() → initSecurity(WAF/IP차단) → DxSite → DxTheme → Auth
→ DxContainer::registerCoreServices()
→ extend/top/*.php 실행
STEP5 routes/*.php 전부 require_once (파일명 정렬순)
→ if (!DxRouter::dispatch()) { ← ① 라라벨 스타일
(new Dispatcher(new Router()))->dispatch(); ← ② 파일/DB 기반
}
→ extend/bottom/*.php → ob_end_flush()
② Dispatcher::dispatch() 내부 순서:
Router::resolve()→ 라우트 배열 생성$GLOBALS['dx_route'] = $routeextend/middle/*.php실행 + 훅dx_extend_middleswitch ($route['type'])→ 각dispatchXxx()
미설치(data/config.php 없음) 시 /install/로 리다이렉트. // 중복 슬래시는 301로 정규화.