안녕하세요. 이곳 하우투 블로그에 글을 처음 쓰게 된 daybreaker입니다. :)

이번에 소개드릴 팁은 텍스트큐브를 웹디렉토리에 바로 설치하지 않고 하위 디렉토리에 설치하신 경우(예: example.com이 블로그 주소가 아니고 example.com/blog가 블로그 주소일 때) 다른 블로그에 댓글을 달 때 그 하위 경로까지 다 적어주지 않으면 댓글알리미를 받지 못하는 것을 해결하는 방법입니다. 즉 example.com이라고만 적어도 댓글알리미를 받을 수 있게 하는 것이지요.

TC1.6부터 추가된 댓글알리미 백업 기능을 작성한 게 저입니다만 막상 제가 daybreaker.info/blog에 블로그를 운영하고 있고 댓글 달 때마다 daybreaker.info까지만 적어왔기 때문에 태터툴즈/텍스트큐브 블로그 운영 3년이 넘었음에도 테스트 데이터가 단 한 개도(-_-) 없다는 것이 디버깅의 걸림돌이었습니다.; 그래서 생각 난 김에 뿔도 뽑아버리자 하고 이 팁을 작성하게 되었습니다.

댓글알리미의 동작 원리

텍스트큐브의 댓글알리미는 해당 블로그 주소로 HTTP POST 요청을 보내어 interface/index.php가 POST 요청에 mode=fb라는 인자가 들어있는지 확인하여 댓글알리미 등록 함수를 호출하는 방식으로 이루어집니다. 트랙백처럼 댓글알리미용으로 존재하는 별도의 주소는 존재하지 않고 블로그 주소 자체가 댓글알리미 수신 주소가 되지요.

댓글알리미 Redirection 방법

다만 현재 텍스트큐브에서 공식적으로 지원하는 기능이 아니기 때문에 약간 복잡한 과정을 거쳐야 합니다.

  1. 먼저 웹디렉토리 루트에 다음과 같은 .htaccess 파일을 작성해야 합니다. 댓글알리미 요청은 POST method를 사용하여 전송되기 때문에 그냥 웹브라우저에 주소를 입력한 경우나 다른 곳에서 링크된 경우(이때는 GET method를 사용합니다)는 원래 홈페이지가 보여야 하니 그것을 필터링해주기 위한ㅈ것입니다.

    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_METHOD} ^POST
    RewriteRule ^$ tc_commentnotify.php [QSA,L]
    </IfModule>
    
  2. 위에서 보신 것처럼 tc_commentnotify.php를 작성해야겠죠? (이 파일 이름은 원하시는대로 바꿔도 상관 없습니다.)

    <?php
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        if (!empty($_POST['mode']) && $_POST['mode'] = 'fb') {
            define('ROOT', './blog');
            include ROOT.'interface/index.php';
            exit;
        }
    }
    # To prevent unintended accesses
    header('HTTP/1.1 404 Not Found');
    echo 'This URL does not exist.';
    ?>
    
  3. 이 부분에 대해선 약간 논란의 여지가 있습니다만, 텍스트큐브 소스코드를 일부 고쳐야 제대로 동작합니다. lib/suri.php를 열어서 19번째 줄 즈음을 다음과 같이 고쳐주세요.

    if ($depth > 0) {
        if (preg_match('@^((/+[^/]+){' . $depth . '})(.*)$@', $url, $matches))
            $url = $matches[3];
        else { // 앞뒤로 중괄호를 쳐줍니다.
            // respond::NotFoundPage(); # 이 부분을 주석처리합니다.
            // Comment Notifier Customization Patch!
            $url = '/'; $depth = 0; $interfacePath='/';
        }
    }
    

    이 패치가 정식 버전에 적용될지, 아니면 다른 방식으로 구현될지는 아직 정해지지 않았습니다만 일단 댓글알리미가 급하신 분들은 저렇게 사용하셔도 큰 무리가 없을 것 같습니다.

이올린에 북마크하기(0) 이올린에 추천하기(0)
2008/04/07 20:56 2008/04/07 20:56
daybreaker 이 작성.

오랜만이네요. 그동안 개인적으로 조금 바빠서 Howto 사이트에 글을 쓸 시간이 나지 않았습니다.

저번 시간에는 정말 개론적인 내용만 말씀드렸지만, 이번 시간에는 PCRE, 즉 Perl-Compatible Regular Expression의 기초에 대해 좀 더 자세하게 이야기해볼까 합니다. 처음에는 정규 표현식 문법에 대해 먼저 이야기하려고 했는데, PHP에서 정규 표현식을 쓰는 방법을 알아야 배운 내용을 활용할 수 있기 때문에 어떻게 정규 표현식을 사용하는지에 대해 먼저 알아보는 것이 좋을 것 같습니다 :)

PHP에서 PCRE를 사용하는 방법


PHP에서 정규식을 사용하는 방법은 사실 두 가지가 있지만(PCRE나 POSIX Extend 라이브러리를 사용하는 것), 이전 글에서 말씀드렸던 것처럼 앞으로는 PCRE만 사용할 것이기 때문에 PCRE를 사용하는 방법에 대해 알아보겠습니다.

이전 글에서 말씀드렸지만 PCRE 계열 함수는 preg_라는 단어로 시작합니다. PHP.net의 관련 페이지를 보면 PCRE 계열 함수는 총 8개입니다. 각 함수가 하는 일은 다음과 같습니다.
  • preg_grep : 배열의 요소 중 정규식과 매치되는 요소들을 반환
  • preg_last_error : 정규식을 실행하다가 발생한 마지막 오류를 반환 (PHP 5 이상)
  • preg_match_all : 문자열 중 정규식과 매치되는 부분을 모두 찾아서 배열에 저장
  • preg_match : 문자열 중 정규식과 처음으로 매치되는 부분을 검색 (배열에 저장할 수도 있음)
  • preg_quote : 정규식에 사용되는 특수문자를 이스케이프
  • preg_replace_callback : 정규식을 이용해서 문자열을 검색한 뒤 콜백 함수로 문자열을 치환
  • preg_replace : 정규식으로 문자열을 치환
  • preg_split : 정규식으로 문자열을 여러 개의 덩어리로 나눔
개인적으로 preg_grep이나 preg_last_error는 자주 사용하지 않는 편이며, 가장 자주 사용하는 함수는 preg_match_all과 preg_replace입니다. 이들 함수는 PHP에서 PCRE를 사용할 수 있도록 해주며, preg_last_error(PHP 5.2.0), preg_replace_callback(PHP 4.0.5)을 제외하면 모두 PHP 4, 5에서 별다른 설정 없이 사용할 수 있는 함수들입니다.

PCRE에서 사용되는 용어 정리


PCRE를 사용할 때 자주 사용되지만 익숙하지 않은 몇 가지 단어에 대해 정리해보려고 합니다. 앞으로도 자주 사용될 단어이기 때문에 기억하시는 것이 좋습니다 :)


delimiter(구분자)


delimiter라는 말은 꼭 PCRE에서만 사용되는 단어는 아닙니다. 하지만 PCRE에서는 정규식 부분과 조금 뒤에 나올 modifier 부분을 구분해주는 역할을 하는 문자를 뜻합니다. modifier를 사용하지 않더라도 delimiter는 반드시 사용해야 하며, 정규식의 처음과 끝에 delimiter 역할을 할 문자를 붙여주기만 하면 됩니다. 만약 패턴에 delimiter로 사용한 문자가 포함된다면 \(백슬래시)를 해당 문자 앞에 붙여서 이스케이프해야 합니다. (그래서 편의상 delimiter는 패턴에 포함되지 않는 문자를 고르는 것이 일반적입니다.) 주로 /(슬래시)를 많이 사용하며, HTML의 닫는 태그, URL 등에 슬래시가 자주 포함되기 때문에 이런 경우에는 !(느낌표) 또는 @(at sign)을 사용하기도 합니다. 다음은 모든 문자열을 공백으로 바꾸는 가장 간단한 정규식입니다.

$string = preg_replace('/.+/', '', $string);

preg_replace의 첫 번째 인자로 들어간 /.+/라는 문자열 중 실제 정규식은 .+라는 부분이며 delimiter는 /입니다. 그렇다면 이제 슬래시가 2개 연속으로 있으면 지우는 정규식을 살펴보죠. (delimiter 선택의 중요성을 나타내기 위해 일부러 슬래시를 나열했습니다.)

$string = preg_replace('/\/\/\//', '', $string);

슬래시가 delimiter일 때 패턴에 슬래시가 사용되었기 때문에 슬래시 앞에 \를 붙여서 이스케이프한 것을 볼 수 있습니다. 그런데 만약 delimiter를 @로 하면 어떨까요?

$string = preg_replace('@///@', '', $string);

자, 패턴이 조금 더 간단해졌습니다 :) 이 때문에 delimiter를 패턴에 가장 적게 포함되는 문자를 고르는 것이 일반적인 것입니다. (물론 습관의 차이도 있겠지요)

Pattern Modifier (패턴 변경자)


패턴을 해석하는 옵션을 변경할 수 있는 알파벳을 뜻합니다. 패턴을 모두 작성하고 delimiter를 마지막에 붙인 뒤에 필요한 변경자를 나열하면 됩니다. PCRE에서 지원하는 변경자의 목록은 PHP.net Manual에서 볼 수 있습니다.

예를 들어, 대소문자를 구분하지 않고 abc라는 문자열을 지우고 싶다면 다음과 같이 하면 됩니다. (실제로는 str_ireplace를 이용하는 것이 효율적입니다.)

$string = preg_replace('/abc/i', '', $string);

두 번째 슬래시 뒤에 붙은 i가 PCRE_CASELESS 패턴 변경자입니다. i를 붙였기 때문에 abc, aBc, Abc 등등 대소문자를 구분하지 않고 모두 지워지게 됩니다.

다음 강좌


다음 강좌는 "정말로(!)" 정규 표현식 문법에 대해 알아볼 것입니다. 사실 문법이 그렇게 방대하지는 않기 때문에 금방 알아볼 수 있을 것이라고 생각합니다. 그럼 다음 강좌에서 뵙겠습니다 :)

이올린에 북마크하기(0) 이올린에 추천하기(0)
Writer profile
Creorix입니다. interCreorix(http://blog.creorix.com)라는 웹 관련 블로그를 운영중이며, 정규 표현식에 대해서 글을 씁니다 :)
2008/01/11 20:40 2008/01/11 20:40
Creorix 이 작성.

« Prev : 1 : 2 : 3 : 4 : 5 : ... 7 : Next »