회원가입 | 고객센터 |
DESIGNONEX
디자인원엑스
Service
PR리그N
Q&AN
지식공유N
공지사항N
통계
로그인 회원가입
고객센터
16. 이슈 가이드

막코딩 필수 규칙

A Administrator
2026.05.21 21:50(수정됨) 11 0

1. 시작 전 필독

DXCMS는 PHP 5.6 ~ 8.x 를 모두 지원합니다. 아래 규칙을 어기면 구형 서버에서 Fatal Error 가 발생하거나, 데이터가 손상될 수 있습니다. 막코딩이라도 이 규칙만큼은 반드시 지켜주세요.
 
항목 올바른 값 이유
PHP 버전 5.6 이상 호환 작성 공유호스팅 PHP 5.6 다수 사용
문자셋 UTF-8 필수 한글 깨짐 방지
DX_CMS 상수 defined('DX_CMS') 체크 필수 직접 접근 차단
BIGINT ID 문자열 그대로 사용 32bit (int) 오버플로우 방지


2. PHP 5.6 호환 — 절대 쓰면 안 되는 문법


2-1. ?? null 병합 연산자 금지


❌ 틀림 (PHP 7+) 
$name = $user['name'] ?? '기본값';   // ❌ PHP 5.6 Fatal Error
✅ 맞음 (PHP 5.6 호환) 
$name = isset($user['name']) ? $user['name'] : '기본값';


2-2. 배열 단축 문법 [] 금지

 
❌ 틀림 
$arr = ['key' => 'value'];   // ❌ PHP 5.3 미만에서 에러
 ✅ 맞음
$arr = array('key' => 'value');   // ✅


2-3. IIFE (즉시실행 익명함수) 금지


 ❌ 틀림 (PHP 7+) 
(function() {
    define('MY_CONST', true);
})();   // ❌ PHP 5.6 에서 동작 안 함
 ✅ 맞음 
if (!defined('MY_CONST')) {
    define('MY_CONST', true);
}


2-4. 훅에 클로저(익명함수) 금지

dx_add_hook() 의 콜백에는 반드시 일반 함수명(문자열)을 사용해야 합니다.
 
❌ 틀림 
dx_add_hook('dx_after_login', function($args) {   // ❌ 클로저 금지
    // ...
});
 ✅ 맞음 
dx_add_hook('dx_after_login', 'my_login_handler');

function my_login_handler($args) {
    // ...
}


3. BIGINT ID — 절대 (int) 캐스팅 금지

DXCMS 의 id 컬럼은 BIGINT(밀리초 타임스탬프, 예: 1747123456789) 입니다. 32bit PHP 에서 (int) 캐스팅하면 오버플로우로 음수나 잘못된 값이 됩니다.
 
❌ 틀림 
$id  = (int)$user['id'];         // ❌ 32bit 오버플로우
$pid = (int)$_GET['post_id'];    // ❌
$row = $db->row("... WHERE id=" . (int)$id);  // ❌
 ✅ 맞음 
$id  = $user['id'];              // ✅ 문자열 그대로
$pid = dx_get('post_id', '', 'bigint');  // ✅ dx_get bigint 타입 사용
$row = $db->row("... WHERE id=?", array($id));  // ✅ 파라미터 바인딩

⚠ URL 에 넣을 때도 그대로 사용합니다.
// ✅ BIGINT 문자열 그대로 URL에 사용
$url = dx_base_url('view/' . $post['id']);

// ✅ 파라미터 바인딩으로 DB 쿼리
$post = $db->row("SELECT * FROM `{$db->table('posts')}` WHERE id=? LIMIT 1",
    array($post['id'])  // 문자열 그대로
);


4. DB 쿼리 안전 패턴


4-1. 반드시 파라미터 바인딩 사용

? 자리에 배열로 값을 전달하면 SQL 인젝션이 자동으로 방어됩니다.
 
❌ 틀림 (SQL 인젝션 위험) 
$db->row("SELECT * FROM dx_posts WHERE id=" . $id);  // ❌
 ✅ 맞음 
$db->row("SELECT * FROM `{$db->table('posts')}` WHERE id=? LIMIT 1",
    array($id)
);


4-2. 테이블명은 $db->table() 사용

테이블 prefix(기본 dx_)가 자동으로 붙습니다. 하드코딩 금지.
$db->table('posts')     // → 'dx_posts'
$db->table('members')   // → 'dx_members'
$db->table('boards')    // → 'dx_boards'


4-3. try/catch 감싸기

테이블이 없거나 컬럼명이 다른 서버에서 500 에러가 나지 않도록 항상 감쌉니다.
$rows = array();
try {
    $rows = $db->rows(
        "SELECT id, title FROM `{$db->table('posts')}` WHERE status=1 LIMIT 10"
    );
} catch (Exception $e) {
    // 조용히 무시하거나 로그 기록
}


4-4. dx_members 주요 컬럼명

그누보드와 컬럼명이 다릅니다. 헷갈리지 마세요.
 
그누보드 DXCMS 비고
mb_id login_id 로그인 아이디
mb_name name 회원 이름
mb_email email  
mb_point point  
mb_level level  
mb_datetime join_date 가입일 (created_at ❌)
(없음) id BIGINT 식별자 — (int) 캐스팅 금지


5. 출력 보안 — XSS 방지

HTML 에 데이터를 출력할 때는 반드시 htmlspecialchars 를 사용합니다.

 ❌ 틀림 (XSS 위험) 
echo $user['name'];             // ❌
echo $_GET['keyword'];          // ❌
 ✅ 맞음 
echo htmlspecialchars($user['name'], ENT_QUOTES, 'UTF-8');
echo htmlspecialchars(dx_get('keyword', ''), ENT_QUOTES, 'UTF-8');


6. POST 처리 — CSRF 보안

POST 요청은 반드시 첫 줄에 CSRF 검증을 해야 합니다. 실패하면 자동으로 종료됩니다.
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST') {
    dx_csrf_check();   // ← 반드시 첫 줄! 실패 시 자동 exit

    $title = dx_post('title', '');     // $_POST 안전하게 가져오기
    $id    = dx_post('id', '', 'bigint'); // BIGINT 타입
}

HTML 폼에 CSRF 토큰을 반드시 추가합니다.
<form method="post">
    <?php echo dx_csrf_field(); ?>   <!-- hidden input 자동 생성 -->
    <input type="text" name="title">
    <button type="submit">저장</button>
</form>


7. 직접 접근 차단

core/, api/, extend/ 등 모든 PHP 파일 첫 줄에 반드시 추가합니다.
<?php
if (!defined('DX_CMS')) exit('Direct access not allowed.');

// 이 아래부터 실제 코드


8. 외부 파일에서 DXCMS 사용 (Direct 방식)

그누보드의 _common.php 처럼 dx_load.php 한 줄로 DXCMS 전체 환경을 불러옵니다.
// 방법 1: dx_load.php 가 같은 폴더
require_once 'dx_load.php';

// 방법 2: 어느 폴더에서든 자동 탐색 (권장)
$p = __DIR__;
while (!file_exists($p . '/dx_load.php')) {
    $pp = dirname($p);
    if ($pp === $p) break;
    $p = $pp;
}
require_once $p . '/dx_load.php';

// 이후 바로 DXCMS 전체 기능 사용 가능
$db   = Database::getInstance();
$auth = Auth::getInstance();
$user = dx_is_login() ? $auth->user() : null;


9. 자주 쓰는 공용 함수 요약

함수 설명 그누보드 대응
dx_is_login() 로그인 여부 bool is_login()
dx_is_admin() 관리자 여부 bool is_admin()
dx_base_url($path) 사이트 URL 생성 G5_URL
dx_current_url() 현재 페이지 전체 URL
dx_redirect($url) 리다이렉트 + exit goto_url()
dx_config($key, $default) 사이트 설정 조회 $config[]
dx_get($key, $default) $_GET 안전 취득 직접 접근
dx_post($key, $default) $_POST 안전 취득 직접 접근
dx_method('POST') 요청 메서드 확인
dx_csrf_check() CSRF 검증 (실패 → exit) check_token()
dx_csrf_field() hidden input 출력 get_token(true)
dx_json($data) JSON 응답 + exit
dx_ip() 접속자 IP (프록시 고려) G5_IP
dx_pagination(...) 페이지네이션 HTML 반환 get_paging()
dx_board_posts($key, $n) 게시판 최신글 배열 반환
DxPoint::add($id, $n, $msg) 포인트 지급 insert_point()
dx_theme_file($path) 테마 파일 절대경로 반환


10. 테마 레이아웃(헤더/푸터) 적용

Direct 파일에서 사이트 테마를 그대로 사용할 수 있습니다.
ob_start();    // ← 출력 캡처 시작
?>
<div>내 HTML 콘텐츠</div>
<?php
$dx_content = ob_get_clean();   // ← 캡처 완료

// type='direct' : 사이드바 없이 전체 폭으로 출력
$context     = array('type' => 'direct');
$_layoutFile = dx_theme_file('layout/main.php');
if ($_layoutFile && file_exists($_layoutFile)) {
    include $_layoutFile;    // ← 테마가 $dx_content 를 감싸서 출력
} else {
    echo $dx_content;
}


11. 커밋 전 체크리스트

  • ?? 연산자 사용 없음 → isset() ? : 로 대체
  • 배열을 array() 로 작성 ([] 단축 없음)
  • IIFE (function(){})() 없음
  • 훅 콜백이 문자열 함수명 (클로저 없음)
  • BIGINT id 에 (int) 캐스팅 없음
  • DB 쿼리에 파라미터 바인딩 array() 사용
  • 테이블명 $db->table('name') 사용
  • HTML 출력 htmlspecialchars 적용
  • POST 첫 줄에 dx_csrf_check() 호출
  • 파일 첫 줄에 defined('DX_CMS') 체크
  • dx_members 컬럼명 join_date / login_id 사용

댓글0

로그인 후 댓글을 작성할 수 있습니다.
16. 이슈 가이드 막코딩 필수 규칙 2026.05.21 16. 이슈 가이드 그누보드의 `_common.php` 처럼, `dx_load.php` 한 줄로 DXCMS의 모든 기능을 사용하는 방법입니다. 2026.05.21
31
전체 회원
423
전체 게시글
556
전체 댓글
56
오늘 방문
32,040
전체 방문
3
현재 접속
인기글 7일 이내
최신글
최신댓글
목록