회원가입 | 고객센터 |
DESIGNONEX DXCMS BOARD
로그인
DESIGNONEX
디자인원엑스
About DXMB └ 메뉴얼 └ 이용약관 └ MB키 발급 └ 업데이트 DXCMS └ 메뉴얼 └ 다운로드 └ Themes └ Plugin └ Skin └ 사용후기 └ 마켓개발자 키 발급 DXB └ DXB Documentation └ InterfaceGallery └ Download └ 사용후기 └ 디자인소스 Service Q&A PR리그 자유게시판 갤러리 포인트게임 공지사항
로그인 회원가입
고객센터
라라벨 사용자를 위한 팁

DXCMS vs Laravel 구조 • 기능 • 문법 • 확장성 완전 비교 분석

A Administrator
2026.04.10 21:19(수정됨) 11 0

01. 한눈에 보는 총평표

9개 영역 빠른 비교 — 자세한 내용은 각 섹션에서
 

비교 항목 DXCMS Laravel 핵심 요약
PHP 버전 지원 ✅ 5.6+ △ 8.2+ DXCMS가 압도적으로 넓음. 저가 호스팅 완전 호환
Composer 의존성 ✅ 없음 ❌ 필수 DXCMS는 FTP 업로드만으로 배포 가능
라우팅 API ✅ 95% ✅ 100% 문법 거의 동일. named route만 없음
QueryBuilder ✅ 90% ✅ 100% 문법 거의 동일. Model 클래스만 없음
DI 컨테이너 ✅ 85% ✅ 100% bind/singleton/make 동일. 타입힌트 자동해결 없음
미들웨어 ✅ 80% ✅ 100% 내장 6종 동일. 미들웨어 클래스 구조 없음
이벤트/훅 ✅ 75% ✅ 100% Action/Filter 구조 동일. 이벤트 클래스 없음
ORM Active Record ❌ 없음 ✅ Eloquent DXCMS 최대 격차. DxModel 추가 필요
템플릿 엔진 △ PHP 직접 ✅ Blade 기능은 되나 Blade의 편의성 없음
보안 시스템 ✅ 우수 ✅ 우수 Secure.php 집중화 vs 분산 레이어. 방식 차이만
CMS 기능 ✅ 압도 ❌ 없음 게시판/회원/포인트/샵/관리자 내장. 라라벨은 직접 구현
생태계/패키지 △ 초기 ✅ 방대 Packagist vs DX 마켓. 격차 존재
국내 특화 기능 ✅ 내장 ❌ 별도 카카오/네이버/토스페이 내장
저가 호스팅 호환 ✅ 최고 ❌ 어려움 DXCMS의 핵심 강점 영역
테스트 인프라 ❌ 없음 ✅ 완비 PHPUnit•Feature Test 없음
공식 문서/커뮤니티 △ 초기 ✅ 방대 한국어 메뉴얼 있음. 영문/글로벌 없음


02. 포지셔닝 — 두 도구의 목적과 철학

무엇을 위해 만들어진 도구인가
 
DXCMS Board Laravel
PHP CMS + 미니 프레임워크 풀스택 PHP 프레임워크
올인원: 게시판•회원•포인트•샵•관리자 내장 기능 없음: 모든 것을 직접 구현
PHP 5.6~8.x 단일 코드베이스 PHP 8.2+ 전용
Composer 없음 — FTP 업로드만으로 배포 Composer 필수 — SSH/CLI 환경 필요
국내 저가 호스팅 완전 최적화 국제 표준 호스팅 환경 타겟
카카오•네이버•토스페이 내장 별도 패키지 설치 필요
설치 마법사 (브라우저 5분 설치) Artisan CLI (php artisan migrate)
타겟: 커뮤니티•쇼핑몰•기업 홈페이지 타겟: API 서버•SaaS•대형 앱

💡 핵심: 두 도구는 경쟁 관계가 아니라 "다른 문제를 푸는 다른 도구"입니다.
라라벨이 "빈 캔버스 위에 무엇이든 그릴 수 있는 붓"이라면,
DXCMS는 "한국형 웹사이트에 필요한 것이 이미 그려진 완성형 패키지"입니다.


03. 요청 라이프사이클 비교

HTTP Request가 들어와서 Response가 나가기까지
 
 
DXCMS Laravel
1
ob_start() + 상수 정의 (DX_ROOT•DX_CMS 등) Composer Autoloader + Application 인스턴스 생성
2
require_once 20+ 클래스 수동 로드 HTTP Kernel 부트스트랩
3
Secure::getInstance() — 보안 초기화     ServiceProvider 자동 등록 (config•route•view 등)
4
DB 연결 (data/config.php) 미들웨어 파이프라인 구성
5
HookManager + PluginRegistry 초기화 Router 매칭
6
DxSite → DxTheme → Auth 순서 초기화     컨트롤러 의존성 자동 주입 (ReflectionClass)
7
DxContainer::registerCoreServices() Response 생성 + 반환
8
extend/top/ 실행 (파일 기반 주입 슬롯) (라라벨에 없는 개념)
9
routes/*.php 자동 로드
10 DxRouter::dispatch() → 매칭 없으면 폴백
11 파일 기반 Dispatcher 폴백 실행
12 extend/bottom/ 실행 → ob_end_flush()

→ DXCMS의 extend/top/middle/bottom 3점 주입 구조는 라라벨에 없는 독자적 강점입니다.
→ 라라벨의 ServiceProvider 자동 등록이 없어 require_once를 수동 나열하는 것이 가장 큰 구조적 차이입니다.
→ 두 방식 모두 단일 진입점(index.php) → 초기화 → 라우팅 → 디스패치의 흐름은 동일합니다.


04. 디렉토리 구조 비교

프로젝트 폴더 1:1 대응표

역할 DXCMS Laravel
단일 진입점 index.php public/index.php
핵심 엔진 core/ vendor/laravel/framework/src/
라우트 정의 routes/*.php (자동 로드) routes/web.php, api.php
컨트롤러 controllers/ app/Http/Controllers/
모델 (ORM) 없음 → QueryBuilder 직접 app/Models/
뷰 (템플릿) themes/{name}/*.php resources/views/*.blade.php
설정 data/config.php config/*.php + .env
공개 에셋 assets/ public/
업로드/캐시 data/ storage/
플러그인/패키지 plugins/ vendor/ (Composer)
관리자 패널 admin/ (완전 내장) 없음 (Filament 등 설치)
설치 마법사 install/ 없음 (Artisan)
확장 자동실행 extend/ — 독자 강점 없음
미들웨어 클래스 없음 → DxRouter 인라인 app/Http/Middleware/
ServiceProvider 없음 → plugin.php app/Providers/
게시판 스킨 boards/skins/{skin}/ 없음 (직접 구현)
테마 themes/{name}/ 없음 (직접 구현)
페이지 pages/ 없음 (직접 구현)


05. 라우팅 시스템 — 문법 정밀 비교

DxRouter.php 소스코드 직접 기반

5-1. 기본 라우트 등록

DXCMS Laravel
// routes/web.php
DxRouter::get('/posts','PostController@index');
DxRouter::post('/posts','PostController@store');
DxRouter::put('/posts/{id}','PostController@update');
DxRouter::patch('/posts/{id}','PostController@update');
DxRouter::delete('/posts/{id}','PostController@destroy');
DxRouter::any('/search','SearchController@index');

// 클로저 라우트
DxRouter::get('/health', function() {
  dx_json(array('status' => 'ok'));
  exit;
});
// routes/web.php
Route::get('/posts',[PostController::class,'index']);
Route::post('/posts',[PostController::class,'store']);
Route::put('/posts/{id}',[PostController::class,'update']);
Route::patch('/posts/{id}',[PostController::class,'update']);
Route::delete('/posts/{id}',[PostController::class,'destroy']);
Route::any('/search',[SearchController::class,'index']);

// 클로저 라우트
Route::get('/health', function() {
  return response()->json(['status' => 'ok']);
});


5-2. 파라미터 & 미들웨어 체이닝

DXCMS Laravel
   

 

DXCMS Laravel
// 파라미터 캡처 + 미들웨어
DxRouter::get('/posts/{id}',
  'PostController@show')
  ->middleware('auth');

// 복수 미들웨어 (PHP 5.6 array())
DxRouter::post('/admin/posts',
  'PostController@store')
  ->middleware(array('admin','csrf'));

// 내장 미들웨어 6종:
// auth  — 로그인 필수 (→ /auth/login)
// admin — 관리자 필수 (→ 403)
// guest — 비로그인 전용
// csrf  — CSRF 토큰 검증
// json  — JSON 헤더 자동
// throttle — 요청 제한
// 파라미터 캡처 + 미들웨어
Route::get('/posts/{id}',
  [PostController::class,'show'])
  ->middleware('auth');

// 복수 미들웨어
Route::post('/admin/posts',
  [PostController::class,'store'])
  ->middleware(['auth','verified']);

// 커스텀 미들웨어 클래스
// app/Http/Middleware/MyMiddleware.php
Route::get('/','HomeController@index')
  ->middleware(MyMiddleware::class);

// named route
Route::get('/posts/{id}', ...)
  ->name('posts.show');


5-3. 라우트 그룹

DXCMS Laravel
   

 

DXCMS Laravel
// 그룹 (prefix + middleware)
DxRouter::group(
  array(
    'prefix'     => '/admin',
    'middleware' => 'admin'
  ),
  function() {
    DxRouter::get('/dashboard',
      'AdminController@dashboard');
    DxRouter::get('/users',
      'AdminController@users');
    DxRouter::post('/users',
      'AdminController@store')
      ->middleware('csrf');
  }
);
// 그룹 (prefix + middleware)
Route::group([
  'prefix'     => 'admin',
  'middleware' => 'auth:admin',
], function () {
  Route::get('/dashboard',
    [AdminController::class,'dashboard']);
  Route::get('/users',
    [AdminController::class,'users']);
  Route::post('/users',
    [AdminController::class,'store']);
});

// 체이닝 스타일도 가능
Route::prefix('admin')
  ->middleware('auth:admin')
  ->group(function () { ... });

5-4. Resource 라우트
DXCMS Laravel
   


 
DXCMS Laravel
// resource() — 6개 자동 등록
DxRouter::resource('/posts','PostController');
// GET    /posts        → index
// POST   /posts        → store
// GET    /posts/{id}   → show
// PUT    /posts/{id}   → update
// PATCH  /posts/{id}   → update
// DELETE /posts/{id}   → destroy

// 일부만 등록
DxRouter::resource('/posts',
  'PostController',
  array('index','show'));
 
// resource() — 7개 자동 등록
Route::resource('posts', PostController::class);
// GET    /posts          → index
// GET    /posts/create   → create  ← 추가
// POST   /posts          → store
// GET    /posts/{post}   → show
// GET    /posts/{post}/edit → edit ← 추가
// PUT    /posts/{post}   → update
// DELETE /posts/{post}   → destroy

// 일부만 등록
Route::resource('posts', PostController::class)
  ->only(['index','show']);

5-5. 라우팅 기능 완성도
기능 DXCMS Laravel 비고
GET/POST/PUT/PATCH/DELETE 완전 동일
라우트 파라미터 {id} 완전 동일
미들웨어 체이닝 ->middleware() 문법 동일
라우트 그룹 group() 거의 동일
Resource RESTful ✅ 6종 ✅ 7종 create/edit 뷰 라우트 없음
클로저 라우트 완전 동일
named route ->name() dx_route() 헬퍼 없음
라우트 캐싱 route:cache Artisan 없음
암묵적 모델 바인딩 Eloquent Model 없어서 불가
정규식 제약 ->where() 향후 추가 가능
커스텀 미들웨어 클래스 클로저만 지원, 클래스@handle 없음
파일 기반 라우팅 폴백 ✅ 독자강점 없음 기존 코드 100% 호환 유지

06. ORM / QueryBuilder 비교
QueryBuilder.php 소스코드 직접 기반

6-1. 기본 조회
DXCMS Laravel
   


 
DXCMS Laravel
// dx_db() 전역 헬퍼 함수
$posts = dx_db('posts')
  ->where('status', 1)
  ->orderBy('id', 'desc')
  ->limit(10)
  ->get();          // array[] 반환

$post = dx_db('posts')
  ->where('id', $id)
  ->first();        // array|null

$title = dx_db('posts')
  ->where('id', $id)
  ->value('title'); // 단일값

$titles = dx_db('posts')
  ->pluck('title'); // 컬럼 배열
// DB 파사드 (QueryBuilder)
$posts = DB::table('posts')
  ->where('status', 1)
  ->orderBy('id', 'desc')
  ->limit(10)
  ->get();          // Collection 반환

$post = DB::table('posts')
  ->where('id', $id)
  ->first();        // stdClass|null

$title = DB::table('posts')
  ->where('id', $id)
  ->value('title');

$titles = DB::table('posts')
  ->pluck('title'); // Collection

6-2. WHERE 조건 — 전체 비교
DXCMS Laravel
   
 
DXCMS Laravel
dx_db('posts')
  ->where('status', 1)           // =
  ->where('views', '>=', 100)   // >=
  ->orWhere('featured', 1)       // OR
  ->whereIn('cat_id',[1,2,3])    // IN
  ->whereNotIn('id',[4,5])       // NOT IN
  ->whereNull('deleted_at')      // IS NULL
  ->whereNotNull('published_at') // NOT NULL
  ->whereBetween('views',10,100) // BETWEEN
  ->whereRaw(
      'YEAR(created_at)=?',
      array(2025))
  ->get();
DB::table('posts')
  ->where('status', 1)
  ->where('views', '>=', 100)
  ->orWhere('featured', 1)
  ->whereIn('cat_id',[1,2,3])
  ->whereNotIn('id',[4,5])
  ->whereNull('deleted_at')
  ->whereNotNull('published_at')
  ->whereBetween('views',[10,100])
  ->whereRaw(
      'YEAR(created_at)=?',
      [2025])
  ->get();

6-3. JOIN • GROUP • ORDER
DXCMS Laravel
   
 
DXCMS Laravel
dx_db('posts')
  ->leftJoin('members',
     'posts.member_id','=',
     'members.id')
  ->select(array(
    'posts.*',
    'members.nickname'))
  ->groupBy('category_id')
  ->orderBy('id','desc')
  ->orderBy('views','desc')
  ->get();
DB::table('posts')
  ->leftJoin('members',
     'posts.member_id','=',
     'members.id')
  ->select(
    'posts.*',
    'members.nickname')
  ->groupBy('category_id')
  ->orderBy('id','desc')
  ->orderBy('views','desc')
  ->get();

6-4. CRUD — INSERT / UPDATE / DELETE
DXCMS Laravel
   
 
DXCMS Laravel
// INSERT
$id = dx_db('posts')->insert(array(
  'title'   => '제목',
  'content' => '내용',
  'member_id' => $userId,
));

// UPDATE (WHERE 없으면 자동 차단)
dx_db('posts')
  ->where('id', $id)
  ->update(array('title' => '수정'));

// DELETE (WHERE 없으면 자동 차단)
dx_db('posts')
  ->where('id', $id)
  ->delete();

// UPSERT
dx_db('stats')->upsert(
  array('user_id'=>1,'count'=>1),
  array('count' => 2)
);

// INCREMENT / DECREMENT
dx_db('posts')
  ->where('id',$id)->increment('views');
 
// INSERT
$id = DB::table('posts')
  ->insertGetId([
    'title'   => '제목',
    'content' => '내용',
    'member_id' => $userId,
  ]);

// UPDATE
DB::table('posts')
  ->where('id', $id)
  ->update(['title' => '수정']);

// DELETE
DB::table('posts')
  ->where('id', $id)
  ->delete();

// UPSERT (Laravel 8+)
DB::table('stats')->upsert(
  ['user_id'=>1,'count'=>1],
  ['user_id'],['count']
);

// INCREMENT / DECREMENT
DB::table('posts')
  ->where('id',$id)->increment('views');


6-5. 페이지네이션 & 집계
DXCMS Laravel
   
 
DXCMS Laravel
// 페이지네이션
$result = dx_db('posts')
  ->where('status',1)
  ->orderBy('id','desc')
  ->paginate(20);
// 반환: array(
//   'data'         => [...],
//   'total'        => 100,
//   'per_page'     => 20,
//   'current_page' => 1,
//   'last_page'    => 5,
//   'from'         => 1,
//   'to'           => 20,
// )

// 집계
dx_db('posts')->count();
dx_db('posts')->max('views');
dx_db('posts')->sum('views');
dx_db('posts')->avg('views');
dx_db('posts')->where('id',1)->exists();

// SQL 디버그
list($sql,$binds) = dx_db('posts')
  ->where('status',1)->toSql();
// 페이지네이션
$result = DB::table('posts')
  ->where('status',1)
  ->orderBy('id','desc')
  ->paginate(20);
// 반환: LengthAwarePaginator
//   $result->items()
//   $result->total()
//   $result->perPage()
//   $result->currentPage()
//   $result->lastPage()
//   $result->from()
//   $result->to()

// 집계
DB::table('posts')->count();
DB::table('posts')->max('views');
DB::table('posts')->sum('views');
DB::table('posts')->avg('views');
DB::table('posts')->where('id',1)->exists();

// SQL 디버그
DB::table('posts')
  ->where('status',1)->toSql();

6-6. Eloquent Model — DXCMS 최대 격차
⚠ DXCMS에는 Eloquent에 해당하는 Model 클래스가 없습니다.
QueryBuilder로 모든 DB 작업이 가능하지만, Active Record 패턴(관계•이벤트•스코프)은 지원하지 않습니다.
→ 로드맵: DxModel 기본 클래스 추가 (PHP 5.6 호환, QueryBuilder 위에 얇은 레이어)
DXCMS Laravel
   


 
DXCMS Laravel
// DXCMS — QueryBuilder 직접 사용
$post = dx_db('posts')
  ->where('id',$id)->first();

// 관계 — JOIN으로 수동 처리
$post = dx_db('posts')
  ->leftJoin('members',
     'posts.member_id'
     ,'=','members.id')
  ->where('posts.id',$id)
  ->first();

// 사용: $post['nickname'] (배열)

// ⚠ 없는 것들:
// - hasMany/belongsTo 관계
// - creating/updated 이벤트
// - scopePublished() 스코프
// - $timestamps 자동 관리
// - $fillable/$guarded 보호
// Eloquent — Active Record
class Post extends Model {
  protected $table = 'posts';
  // 관계 자동 해결
  public function author() {
    return $this
      ->belongsTo(Member::class);
  }
  public function comments() {
    return $this->hasMany(Comment::class);
  }
  // 스코프
  public function scopePublished($q){
    return $q->where('status',1);
  }
}
// 사용
$post = Post::with('author')
  ->published()->find($id);
$post->author->nickname; // 객체

07    DI 컨테이너 비교
DxContainer.php 소스코드 직접 기반

7-1. 바인딩 & 해석
DXCMS Laravel
   
 
DXCMS Laravel
// 팩토리 바인딩
dx_app()->bind('mailer', function() {
  return new MyMailer(
    dx_config('smtp_host')
  );
});

// 싱글턴 바인딩
dx_app()->singleton('sms', function() {
  return new AlimtalkSMS(
    dx_config('alimtalk_key')
  );
});

// 인스턴스 직접 등록
dx_app()->instance('redis', $redis);

// 별칭
dx_app()->alias('db', 'database');

// 바인딩 여부 확인
dx_app()->bound('mailer'); // bool

// 해제
dx_app()->forget('mailer');

// 꺼내 쓰기
$m = dx_app()->make('mailer');
$m = dx_make('mailer'); // 단축함수
// 팩토리 바인딩
app()->bind(Mailer::class, function($app) {
  return new MyMailer(
    config('mail.smtp_host')
  );
});

// 싱글턴 바인딩
app()->singleton(SMS::class, function($app) {
  return new AlimtalkSMS(
    config('services.alimtalk_key')
  );
});

// 인스턴스 직접 등록
app()->instance('redis', $redis);

// 별칭
app()->alias(Mailer::class, 'mailer');

// 바인딩 여부 확인
app()->bound(Mailer::class); // bool




// 꺼내 쓰기
$m = app()->make(Mailer::class);
$m = app(Mailer::class); // 단축함수

7-2. 컨트롤러 자동 의존성 주입
DXCMS Laravel
   
 
DXCMS Laravel
// DxContainer::call()로 실행
dx_app()->call(
  'BoardController@index',
  array('board_key' => 'free')
);

// 생성자 파라미터 자동 주입
// (바인딩된 서비스만 주입 가능)
class BoardController {
  private $db;
  public function __construct(
    Database $db    // 바인딩 필요
  ) {
    $this->db = $db;
  }
  public function index($params) {
    $key = $params['board_key'];
    // ...
  }
}

// 컨트롤러 자동 로드 순서:
// 1. controllers/{Class}.php
// 2. plugins/*/controllers/{Class}.php
// 타입힌트만으로 자동 해결
// 컨트롤러 메서드에서 바로 사용




// 생성자 + 메서드 모두 자동 주입
// 미등록 클래스도 Reflection으로 해결
class BoardController extends Controller {
  private $db;
  public function __construct(
    Database $db  // 타입힌트만으로 OK
  ) {
    $this->db = $db;
  }
  public function index(
    Request $request  // 메서드도 자동
  ) {
    // ...
  }
}

7-3. 핵심 차이 요약
기능 DXCMS Laravel 비고
bind() / singleton() / instance() 완전 동일
make() / alias() / bound() 완전 동일
생성자 타입힌트 자동 주입 △ 바인딩된 것만 ✅ 모든 클래스 라라벨이 더 스마트
메서드 파라미터 자동 주입 라라벨만 지원
Contextual Binding 인터페이스별 다른 구현체
태깅 (tag)  
ServiceProvider 패턴 ❌ → plugin.php 개념은 동일, 구조 차이

08    미들웨어 비교
DxRouter.php의 runMiddleware() 소스코드 기반

8-1. 내장 미들웨어 비교
이름 DXCMS 동작 Laravel 동작
auth 미로그인 시 /auth/login?redirect=... 으로 리다이렉트 Authenticate 미들웨어 — /login 리다이렉트
admin 비관리자 시 HTTP 403 반환 auth:admin — Gate 기반
guest 로그인 상태면 홈으로 리다이렉트 RedirectIfAuthenticated
csrf dx_csrf_verify() — 실패 시 403 + JSON 에러 VerifyCsrfToken — 자동 적용 (Web 라우트)
json Content-Type: application/json 헤더 자동 AcceptsJson + JSON 응답
throttle 기본 정의됨 (향후 확장) ThrottleRequests — 분당 횟수 설정

8-2. 커스텀 미들웨어
DXCMS Laravel
   
 
DXCMS Laravel
// DXCMS — 클로저 방식만 지원
DxRouter::get('/admin','AdminController@index')
  ->middleware(function($params) {
    $auth = Auth::getInstance();
    if (!$auth->isLoggedIn()) {
      header('Location: /auth/login');
      exit;
    }
    if ($auth->get('level') < 5) {
      http_response_code(403);
      exit('권한 없음');
    }
  });

// ⚠ 클래스@handle 구조 미지원
// → 로드맵: 미들웨어 클래스 추가 예정
// Laravel — 미들웨어 클래스
// app/Http/Middleware/CheckLevel.php
class CheckLevel {
  public function handle(
    Request $request, Closure $next,
    $level = 1
  ) {
    if (!auth()->check()) {
      return redirect('/login');
    }
    if (auth()->user()->level < $level) {
      abort(403);
    }
    return $next($request);
  }
}

// 등록 후 사용
Route::get('/admin','AdminController@index')
  ->middleware('check.level:5');

8-3. extend/ — 미들웨어를 대체하는 독자 방식
DXCMS Laravel
   
 
DXCMS Laravel
// extend/top/01_maintenance.php
// 코드 등록 없이 파일만 넣으면 실행됨

$mode = dx_config('maintenance', 0);
if ($mode) {
  $auth = Auth::getInstance();
  if (!$auth->isAdmin()) {
    header('Content-Type: text/html');
    echo '<h1>점검 중입니다. 잠시 후 접속하세요.</h1>';
    exit;
  }
}

// extend/middle/01_access_log.php
$uri = dx_request_uri();
$ip  = dx_ip();
dx_db('access_logs')->insert(array(
  'uri'   => $uri,
  'ip'    => $ip,
  'ua'    => $_SERVER['HTTP_USER_AGENT'],
  'at'    => date('Y-m-d H:i:s'),
));
// Laravel — 동등 구현: 미들웨어 클래스
// (파일 생성 + 등록 + Kernel 추가 필요)

// app/Http/Middleware/Maintenance.php
class Maintenance {
  public function handle($req, $next) {
    if (config('app.maintenance')) {
      if (!auth()->user()?->isAdmin()) {
        return response('점검 중', 503);
      }
    }
    return $next($req);
  }
}

// app/Http/Middleware/AccessLog.php
class AccessLog {
  public function handle($req, $next) {
    $res = $next($req);
    DB::table('access_logs')->insert([..]);
    return $res;
  }
}
// + Kernel.php에 등록 필요

09    이벤트 / 훅 시스템 비교
HookManager.php 소스코드 기반
 
DXCMS Laravel
// ── Action 훅 (이벤트 발생/구독) ──

// 훅 등록 (구독)
dx_add_hook('dx_after_login',
  function($args) {
    $user = $args['user'];
    DxPoint::reward($user['id'], 10);
    DxMemberMonitor::onLogin($user['id']);
  },
  20   // 우선순위 (낮을수록 먼저)
);

// 훅 실행 (이벤트 발생)
dx_run_hook('dx_after_login',
  array('user' => $userData)
);

// ── Filter 훅 (값 변환) ──

// 필터 등록
dx_add_filter('post_content',
  function($content) {
    return nl2br($content);
  }
);

// 필터 실행 — 등록된 콜백들이 순서대로 값 변환
$html = dx_apply_filter('post_content', $raw);

// 훅 존재 확인 / 제거
dx_has_hook('dx_after_login'); // bool
dx_remove_hook('dx_after_login', $cb);
 
// ── Laravel Event (이벤트 발생/구독) ──

// 리스너 등록 (EventServiceProvider)
Event::listen(
  UserLoggedIn::class,
  function(UserLoggedIn $event) {
    $user = $event->user;
    Points::reward($user->id, 10);
    MemberMonitor::onLogin($user->id);
  }
);

// 이벤트 발생
event(new UserLoggedIn($user));


// ── Filter 개념 없음 ──
// Pipeline으로 직접 구현해야 함







// 리스너 클래스 방식도 지원
Event::listen(
  UserLoggedIn::class,
  SendWelcomeEmail::class
);
  
표준 훅 포인트 목록
훅 이름 발생 시점 활용 예
dx_top 모든 페이지 최상단 (body 시작) 광고 배너•공지•AB테스트
dx_bottom 모든 페이지 최하단 (body 끝) 챗봇•스크립트 주입
dx_body_bottom ob_flush 직전 DxPopup 팝업 자동 출력
dx_{type}_top/bottom 게시판/페이지 타입별 board_top, page_bottom
dx_after_login 로그인 성공 후 포인트 지급•로그•알림
dx_after_logout 로그아웃 후 세션 정리•접속 기록
dx_extend_top/bottom extend/ 실행 직후 추가 초기화•후처리
post_content (Filter) 게시글 본문 출력 시 마크다운•하이라이트 변환
board_list_query (Filter) 게시글 목록 쿼리 시 커스텀 필터 주입
before_post_save 게시글 저장 직전 유효성 검사•데이터 가공
after_comment_save 댓글 저장 완료 후 실시간 알림 발송
member_register 회원가입 완료 후 환영 포인트•이메일


10    템플릿 엔진 비교
PHP 직접 vs Blade
 
DXCMS Laravel
// ── DXCMS — PHP 직접 ──
// themes/default/layout/main.php

<!DOCTYPE html>
<html>
<head>
  <title><?php echo dx_esc($title); ?></title>
  <?php DxSeo::renderMeta(); ?>
</head>
<body>
<?php dx_hook_top(); // 훅 포인트 ?>

<!-- 메뉴 include -->
<?php include DX_THEMES.'/default/parts/nav.php'; ?>

<!-- 콘텐츠 영역 -->
<main><?php echo $dx_content; ?></main>

<?php dx_hook_bottom(); // 훅 포인트 ?>
<?php dx_run_hook('dx_body_bottom'); ?>
</body>
</html>
// ── Laravel — Blade ──
// resources/views/layouts/app.blade.php

<!DOCTYPE html>
<html>
<head>
  <title>{{ $title }}</title>
  @stack('head')
</head>
<body>
@yield('header')

<!-- 컴포넌트 -->
@include('partials.nav')

<!-- 콘텐츠 영역 -->
<main>@yield('content')</main>

@stack('scripts')
</body>
</html>
DXCMS 템플릿은 Blade보다 단순하지만, 그것이 약점만은 아닙니다.
순수 PHP이므로 IDE 자동완성이 완벽하게 동작하고, 별도 컴파일 과정이 없어 저가 호스팅에서도 동일하게 실행됩니다.
단, {{ }} 자동 이스케이프가 없으므로 출력 시 반드시 dx_esc()를 사용해야 합니다.

11    보안 시스템 비교
Secure.php 집중화 vs Laravel 분산 레이어
보안 항목 DXCMS Secure.php Laravel
CSRF 토큰 csrfToken()/csrfCheck() TTL 24시간, 활동 시 자동 갱신 VerifyCsrfToken 미들웨어 Web 라우트 자동 적용
XSS 방어 dx_esc() 수동 호출 (출력 이스케이프) Blade {{ }} 자동 이스케이프
세션 보안 HttpOnly•Secure•SameSite=Lax 설정 Session 드라이버 + 암호화
Rate Limit Redis → 파일 폴백 자동전환
ateLimit($key,$max,$window)
ThrottleRequests 미들웨어
Route::throttle()
파일 업로드 MIME+이중확장자 이중 검증
alidateUpload($file)
Storage 드라이버 + MIME 검증
SQL Injection PDO 준비된 구문 일관 사용
(QueryBuilder 자동 처리)
Eloquent PDO 바인딩 자동
보안 헤더 sendSecurityHeaders() X-Frame-Options 등 자동 TrustHosts + 별도 패키지
WAF POST 본문 SQL/XSS 패턴 탐지 없음 (서버/별도 패키지)
Bot 탐지 검색봇 허용, 의심봇 로그 기록 없음 (서버/별도 패키지)
비밀번호 bcrypt (PHP 5.6 폴백 포함) Hash::make() bcrypt/argon2
보안 패치 Secure.php 1파일만 교체 프레임워크 업데이트
DXCMS의 보안 집중화 전략:
core/Secure.php 한 파일에 모든 보안 코드가 집중되어 있습니다.
보안 패치 시 이 파일 하나만 교체하면 됩니다. 소수 팀에서 유지보수하기에 최적인 구조입니다.

→ WAF•Bot 탐지는 라라벨이 기본 제공하지 않는 영역에서 DXCMS가 앞서 있습니다.


12    플러그인 vs Service Provider
생태계 확장 패턴 비교
 
DXCMS Laravel
   
 
DXCMS Laravel
   
 
DXCMS Laravel
   
 
DXCMS Laravel
   
 
DXCMS Laravel
   






 

댓글0

로그인 후 댓글을 작성할 수 있습니다.
22
전체 회원
69
전체 게시글
46
전체 댓글
569
오늘 방문
47,886
전체 방문
0
현재 접속
인기글 7일 이내
최신글
최신댓글