문서의 이전 판입니다!
목차
DokuWiki PHP 개발 가이드라인
DokuWiki는 강력하고 유연한 위키 시스템으로, PHP 언어를 기반으로 구축되었습니다. 이 문서는 DokuWiki 환경에서 PHP를 효과적으로 사용하고, 특히 DokuWiki 플러그인을 개발하는 데 필요한 핵심 가이드라인을 제공합니다. PHP의 기본 문법부터 DokuWiki의 내부 구조와 상호작용하는 방법, 그리고 플러그인 개발의 모범 사례에 이르기까지 전반적인 내용을 다룹니다. 이 가이드라인은 DokuWiki 확장 기능을 개발하고자 하는 모든 사용자에게 유용한 자료가 될 것입니다.
1. 개요 및 목적
DokuWiki는 PHP로 작성된 평면 파일 기반의 위키 엔진입니다. 이는 DokuWiki의 모든 기능과 확장이 PHP 코드를 통해 구현됨을 의미합니다. 따라서 DokuWiki를 깊이 있게 이해하고, 사용자 정의 기능을 추가하거나 기존 기능을 수정하기 위해서는 PHP에 대한 이해가 필수적입니다.
- DokuWiki 환경에서 PHP 사용의 중요성
- DokuWiki의 핵심 로직과 모든 플러그인, 템플릿은 PHP로 작성됩니다.
- PHP를 이해하면 DokuWiki의 동작 방식을 파악하고 문제를 해결하는 데 용이합니다.
- 새로운 기능을 추가하거나 기존 기능을 수정하는 데 필수적인 언어입니다.
- 플러그인 개발 시 PHP 활용 강조
- DokuWiki의 가장 강력한 확장 기능인 플러그인은 전적으로 PHP로 개발됩니다.
- PHP를 통해 DokuWiki의 이벤트 시스템에 후킹하고, 새로운 구문, 액션, 관리 기능을 추가할 수 있습니다.
- 이 가이드라인은 안전하고 효율적인 플러그인 개발을 위한 지침을 제공합니다.
2. DokuWiki PHP 개발의 기본
DokuWiki 환경에서 PHP 개발을 시작하기 전에, DokuWiki의 기본적인 구조와 PHP 개발 환경에 대한 이해가 필요합니다.
1) DokuWiki PHP 개발 환경
DokuWiki는 별도의 데이터베이스 없이 작동하므로, PHP와 웹 서버(Apache, Nginx 등)만 있으면 개발 환경을 구축할 수 있습니다.
- DokuWiki 설치 경로
- 일반적으로 DokuWiki는 웹 서버의 문서 루트 디렉토리(예:
/var/www/html/dokuwiki/
)에 설치됩니다. - 모든 PHP 파일, 설정 파일, 데이터 파일은 이 경로 하위에 존재합니다.
- PHP 버전 요구사항
- DokuWiki는 특정 PHP 버전 이상을 요구합니다. 공식 DokuWiki 웹사이트에서 현재 사용 중인 DokuWiki 버전에 맞는 PHP 최소 요구 사항을 확인해야 합니다.
- 최신 DokuWiki 버전은 일반적으로 최신 PHP 버전을 지원하며, 성능과 보안 이점을 제공합니다.
2) DokuWiki 핵심 파일 이해
DokuWiki의 주요 디렉토리와 파일은 DokuWiki가 어떻게 작동하는지 이해하는 데 중요합니다.
conf/
디렉토리- DokuWiki의 설정 파일(예:
local.php
,users.auth.php
)이 위치합니다. - 플러그인 개발 시
conf/plugins/
디렉토리에 플러그인 관련 설정 파일을 저장할 수 있습니다.
lib/
디렉토리- DokuWiki의 핵심 라이브러리 파일과 모든 플러그인, 템플릿이 위치합니다.
lib/plugins/
: 모든 설치된 플러그인이 이 디렉토리 하위에 자체 디렉토리를 가집니다.lib/tpl/
: DokuWiki 템플릿이 위치합니다.
inc/
디렉토리- DokuWiki의 주요 함수와 클래스 정의 파일이 위치합니다.
- DokuWiki API와 상호작용할 때 이 디렉토리의 파일들을 참조하게 됩니다.
3. PHP 문법 가이드라인
DokuWiki 플러그인 개발을 위한 PHP 코드를 작성할 때, 가독성, 유지보수성, 성능 및 보안을 고려한 표준화된 문법 가이드라인을 따르는 것이 중요합니다.
1) 변수 및 상수
PHP 변수와 상수는 데이터를 저장하고 참조하는 데 사용됩니다.
- 명명 규칙
- 변수: 소문자로 시작하며 언더스코어(underscore)를 사용하여 단어를 구분하는
스네이크 케이스
(예:$my_variable
). - 상수: 대문자로만 구성되며 언더스코어를 사용하는
대문자 스네이크 케이스
(예:MY_CONSTANT
). - 클래스 이름: 각 단어의 첫 글자를 대문자로 하는
파스칼 케이스
(예:MyClass
).
- 사용 예제
<?php $page_id = 'start'; // 변수 선언 define('DOKUWIKI_VERSION', '2023-04-04 "Jackrum"'); // 상수 선언 class MyPlugin { const PLUGIN_VERSION = '1.0.0'; // 클래스 상수 public $data; } ?>
2) 데이터 타입
PHP는 동적 타입 언어이지만, 올바른 데이터 타입 사용은 코드의 안정성을 높입니다.
- 주요 데이터 타입
- 문자열 (
string
): 텍스트 데이터. - 숫자 (
integer
,float
): 정수 및 부동 소수점 숫자. - 배열 (
array
): 순서가 있거나 연관된 값의 집합. - 객체 (
object
): 클래스의 인스턴스. - 불리언 (
boolean
): 참(true) 또는 거짓(false).
- 타입 캐스팅 (필요 시)
- 명시적 타입 캐스팅을 사용하여 변수의 타입을 변경할 수 있습니다.
- 예:
(int) $string_value
,(bool) $number_value
.
3) 조건문 및 반복문
프로그램의 흐름을 제어하는 데 사용됩니다.
if
,else if
,else
- 조건에 따라 다른 코드 블록을 실행합니다.
switch
- 여러 조건 중 하나를 선택하여 실행할 때 유용합니다.
for
,foreach
,while
for
: 특정 횟수만큼 반복.foreach
: 배열의 각 요소에 대해 반복 (권장).while
: 특정 조건이 참인 동안 반복.
<?php $data = array('item1', 'item2', 'item3'); foreach ($data as $item) { echo $item . "\n"; } $count = 0; while ($count < 3) { echo "Count: " . $count . "\n"; $count++; } ?>
4) 함수 및 클래스
코드의 재사용성과 모듈화를 위해 함수와 클래스를 적극적으로 활용해야 합니다.
- 함수 정의 및 호출
- 특정 작업을 수행하는 코드 블록을 정의합니다.
- 가능한 한 함수는 단일 책임을 가지도록 작성합니다.
- 클래스 및 객체 지향 프로그래밍 (OOP) 기본
- DokuWiki 플러그인은 대부분 객체 지향적으로 설계됩니다.
- 클래스를 사용하여 관련 데이터와 함수를 캡슐화하고, 상속 및 다형성을 활용하여 코드를 확장합니다.
<?php function my_custom_function($text) { return "Processed: " . $text; } echo my_custom_function("Hello DokuWiki"); class MyDokuPlugin extends DokuWiki_Plugin { public function getInfo() { return array( 'author' => 'Your Name', 'name' => 'My Doku Plugin', 'date' => '2023-11-20', 'desc' => 'A simple example plugin.', 'url' => 'https://example.com' ); } } ?>
5) 오류 처리 및 디버깅
문제 발생 시 이를 감지하고 해결하는 것은 개발의 필수적인 부분입니다.
error_reporting
- PHP 오류 보고 수준을 설정합니다. 개발 환경에서는 모든 오류를 보고하도록 설정하는 것이 좋습니다 (
E_ALL
). - 운영 환경에서는 사용자에게 오류 메시지가 노출되지 않도록 주의해야 합니다.
try-catch
블록- 예외 처리를 위해 사용됩니다. 잠재적으로 오류를 발생시킬 수 있는 코드를
try
블록 안에 넣고, 발생한 예외를catch
블록에서 처리합니다.
- DokuWiki 디버깅 모드
conf/local.php
파일에서$conf['debug'] = 1;
로 설정하여 DokuWiki의 디버그 모드를 활성화할 수 있습니다.- 이는 오류 메시지를 더 자세히 표시하고, 개발 중 유용한 정보를 제공합니다.
4. DokuWiki 플러그인 개발을 위한 PHP 활용
DokuWiki 플러그인은 DokuWiki의 기능을 확장하는 핵심 방법입니다. PHP를 사용하여 다양한 종류의 플러그인을 만들 수 있습니다.
1) 플러그인 구조 이해
DokuWiki 플러그인은 특정 명명 규칙과 파일 구조를 따릅니다.
- 이벤트 핸들러 (Action Plugin)
- DokuWiki 코어에서 발생하는 특정 이벤트에 반응하여 동작합니다.
- 파일명:
action.php
- 클래스:
action_plugin_yourpluginname
- `register_hook()` 메서드를 사용하여 이벤트를 “구독”합니다.
- 구문 플러그인 (Syntax Plugin)
- 사용자 정의 DokuWiki 구문을 추가하여 페이지 내용을 파싱하고 렌더링합니다.
- 파일명:
syntax.php
- 클래스:
syntax_plugin_yourpluginname
- `getType()`, `getPType()`, `getSort()`, `connectTo()` 등의 메서드를 구현합니다.
- 관리 플러그인 (Admin Plugin)
- DokuWiki 관리 패널에 새로운 관리 도구를 추가합니다.
- 파일명:
admin.php
- 클래스:
admin_plugin_yourpluginname
- `handle()` 메서드를 사용하여 관리 작업을 처리합니다.
2) DokuWiki API 상호작용
DokuWiki 플러그인은 DokuWiki 코어의 함수와 전역 변수를 사용하여 상호작용합니다.
- 전역 변수 (
$ID
,$ACT
)$ID
: 현재 보고 있는 DokuWiki 페이지의 ID (경로).$ACT
: 현재 DokuWiki가 수행하고 있는 액션 (예: 'show', 'edit', 'preview').
- DokuWiki 함수 호출 예제
- `p_wiki_xhtml($id, $rev, $return_xhtml)`: 특정 페이지의 XHTML 내용을 가져옵니다.
- `io_saveFile($file, $content)`: 파일을 저장합니다.
- `msg($text, $level)`: 사용자에게 메시지를 표시합니다.
<?php // 현재 페이지 ID 가져오기 $current_page_id = $ID; msg("현재 페이지 ID: " . $current_page_id, 'info'); // 특정 페이지 내용 읽기 (예: 'start' 페이지) $start_page_content = p_wiki_xhtml('start'); // ... $start_page_content를 사용하여 작업 ... // 파일에 내용 쓰기 $file_path = DOKU_INC . 'data/pages/myplugin_data.txt'; $success = io_saveFile($file_path, 'This is my plugin data.'); if ($success) { msg("데이터가 성공적으로 저장되었습니다.", 'ok'); } else { msg("데이터 저장 실패!", 'error'); } ?>
3) 보안 고려사항
플러그인을 개발할 때는 항상 보안을 최우선으로 고려해야 합니다.
- 사용자 입력 검증
- `$_GET`, `$_POST`, `$_REQUEST` 등 사용자로부터 받은 모든 입력은 절대적으로 검증하고 필터링해야 합니다.
- DokuWiki는 HTMLpurifier와 같은 내부 필터링 메커니즘을 제공하지만, 개발자는 항상 추가적인 검증을 수행해야 합니다.
- SQL 인젝션 방지
- DokuWiki는 기본적으로 파일 기반이지만, 데이터베이스를 사용하는 플러그인을 개발할 경우 SQL 인젝션 공격에 매우 취약해질 수 있습니다.
- Prepared Statement를 사용하거나, DokuWiki가 제공하는 데이터베이스 추상화 계층을 사용해야 합니다.
- XSS (Cross-Site Scripting) 방지
- 사용자 입력이 HTML로 렌더링될 때, `hsc()` (
htmlspecialchars
) 함수를 사용하여 HTML 엔티티를 이스케이프해야 합니다. - `p_render()` 함수를 사용할 때도 출력 필터링에 주의해야 합니다.
5. PHP 코드 예제
실제 DokuWiki 플러그인 개발에 활용할 수 있는 간단한 PHP 코드 예제입니다.
1) 간단한 플러그인 예제
이 예제는 DokuWiki 페이지 하단에 간단한 메시지를 추가하는 액션 플러그인입니다.
action.php
파일 (lib/plugins/myexampleplugin/action.php
경로에 생성)
<?php // DokuWiki_Plugin 클래스를 상속받습니다. class action_plugin_myexampleplugin extends DokuWiki_Plugin { // 플러그인 정보 반환 (선택 사항이지만 권장) public function getInfo() { return array( 'author' => 'Your Name', 'name' => 'My Example Plugin', 'date' => '2023-11-20', 'desc' => 'A simple DokuWiki action plugin example.', 'url' => 'https://example.com' ); } // DokuWiki 이벤트에 후킹합니다. public function register_hook(Doku_Event_Handler $handler) { // 'TPL_CONTENT_DISPLAY' 이벤트에 후킹하여 페이지 내용 출력 후 동작합니다. $handler->append('TPL_CONTENT_DISPLAY', 'AFTER', $this, 'handle_content_display'); } // 이벤트 핸들러 메서드 public function handle_content_display(Doku_Event $event, $param) { // 이벤트 데이터에 접근하여 HTML 출력을 추가합니다. $event->data .= '<p>This message is added by My Example Plugin!</p>'; } } ?>
2) DokuWiki 데이터 조작 예제
이 예제는 특정 페이지의 내용을 읽고, 새로운 텍스트를 페이지에 추가하는 방법을 보여줍니다.
- 페이지 내용 읽기/쓰기
<?php // DOKU_INC는 DokuWiki 설치 경로를 나타내는 상수입니다. $page_path = DOKU_INC . 'data/pages/playground/testpage.txt'; // 예시 페이지 경로 // 페이지 내용 읽기 if (file_exists($page_path)) { $content = file_get_contents($page_path); echo "<p>Original content of testpage:</p>"; echo "<pre>" . hsc($content) . "</pre>"; // hsc()로 HTML 엔티티 이스케이프 } else { echo "<p>testpage.txt does not exist.</p>"; } // 페이지에 새로운 내용 추가 (기존 내용 뒤에) $new_content = "\n\nThis text was added by a PHP script."; $success = io_saveFile($page_path, $new_content, true); // true는 append 모드 if ($success) { msg("Content successfully appended to testpage.txt", 'ok'); } else { msg("Failed to append content to testpage.txt", 'error'); } // 변경된 내용 확인 (다시 읽기) if (file_exists($page_path)) { $updated_content = file_get_contents($page_path); echo "<p>Updated content of testpage:</p>"; echo "<pre>" . hsc($updated_content) . "</pre>"; } ?>
- 사용자 정보 접근
- DokuWiki는 사용자 인증 및 권한 관리를 위한 다양한 함수를 제공합니다.
<?php global $USERINFO; // 현재 로그인한 사용자 정보 if (isset($USERINFO['name'])) { echo "<p>현재 로그인한 사용자 이름: **" . hsc($USERINFO['name']) . "**</p>"; } else { echo "<p>로그인하지 않았습니다.</p>"; } // 사용자 권한 확인 예시 (admin 그룹인지) if (checkSecurityToken() && auth_isadmin()) { // 보안 토큰 확인 및 관리자 여부 echo "<p>당신은 관리자입니다!</p>"; } else { echo "<p>관리자가 아닙니다.</p>"; } ?>
6. 결론
이 가이드라인은 DokuWiki 환경에서 PHP를 사용하여 플러그인을 개발하고 DokuWiki 기능을 확장하는 데 필요한 기본적인 지식과 모범 사례를 제공했습니다. PHP의 핵심 문법부터 DokuWiki의 특정 API와의 상호작용, 그리고 보안 고려사항에 이르기까지 전반적인 내용을 다루었습니다.
DokuWiki는 강력한 확장성을 제공하며, PHP에 대한 이해는 이 잠재력을 최대한 활용하는 데 필수적입니다. 이 문서를 바탕으로 더욱 견고하고 유용한 DokuWiki 플러그인을 개발하고, DokuWiki 커뮤니티에 기여하시기를 바랍니다. 지속적인 학습과 실험을 통해 DokuWiki 개발 역량을 향상시킬 수 있습니다.