본문 바로가기

Common Gateway Interface/Perl

[옛 강좌] 31. Perlprog - BBS 10

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 이 게시물은 지금은 폐쇄되어 접속되지 않는 Kim Young Soo(http://hours.interpia98.net/~unisoo/)님의 웹 사이트에 2001년경 게시된 내용을 바탕으로 오늘날 웹 환경에 맞게 내용을 덧붙였습니다.

Perlprog - BBS 10

Description

게시판 만들기 10 - 좀더 발전된 게시판을 위해서...


BBS 만들기 10

 어느덧... 게시판 만들기 열번째 입니다. 이제 기본적인 사항들은 모두 끝이 났습니다. 지금까지의 내용을 가지고, 잘 활용하신다면 머찐 게시판이 나올거라 생각합니다. 물론 자바스크립트, 스타일시트등 DHTML을 같이 이용하시면, 보기도 좋고, 성능도 좋은 게시판이 될겁니다. 이번엔 지금까지 해온 게시판에서 좀더 향상된 게시판에 대한 이야기를 하고자 합니다. 다중게시판, 파일 업로드 등을 이야기 하겠습니다.

Multi Board(다중 게시판)

 우선 다중게시판에 대해서 생각해 보겠습니다. 지금까지 했던 프로그램을 가지고서도 다중 게시판을 구현할순 있죠.. 물론 일일이 파일을 다 복사하고, 게시판 이름 따로 주고, 환경파일등을 조절한다면, 가능은 합니다. 하지만... 이건 자원의 낭비죠. 우리가 원하는 건 하나의 실행 파일로 여러 개의 게시판을 운영할 수 있는 것입니다.

DB 변수

 다중 게시판을 가능케 하기 위해선 우선, 게시판의 이름을 변수화 하는겁니다. 지금까진 view_list.cgi 이렇게만 실행을 시켰습니다. 하지만 view_list.cgi?db=free 이렇게 db라는 변수명으로 우리가 사용하고자 하는 게시판을 프로그램에 넘겨주고, 프로그램은 해당 db를 열어서 작업을 하게 하면 됩니다.

 이렇게 하기 위해선 각각의 db(예 : qna, free, pds....)에 따라서 디렉토리가 존재 해야죠. 일일이 손으로 하기 힘이 드니깐, 관리자 모드라는걸 만들어서, 필요한 절차(디렉토리 생성, 인덱스파일 및 각종 파일)를 거치게 됩니다. 프로그램 안에서도, 읽기, 쓰기, 편집등의 작업을 처리할때 이 DB변수를 항상 같이 넘겨야 함은 물론 입니다. 그래야 각 게시판의 각종 환경파일 및 데이터파일을 혼란없이 처리할수 있습니다.

 프로그램 내에서 모든 판별은 이 DB 변수를 가지고 하게 됩니다. 예를 들어서 'qna'라는 게시판이 있다면, (물론 이 디렉의 이름 또한 qna입니다)

view_list.cgi?db=qna

이렇게 넘겨주게 되고, 각각의 환경 파일은

$fields{'db'}."/".$fields{'db'}."conf/$fields{'db'}".".conf";

라고 되겠죠. 이건 qna/qna.conf/qna.conf 파일을 가리키게 됩니다. 다른 환경들도 마찬가지로 설정을 하면 됩니다.

 하지만, 전체 변수명 또한 준비해 둬야 합니다. 각 DB가 생성되는, 그러니깐 각 게시판이 생성되는 부모 디렉토리 같은 건 글로벌 변수로 둬야 합니다.

 가장 최상위가 되는 디렉토리(DB가 생성되는), 아이콘이 들어 있는 디렉, CGI프로그램이 있는 디렉토리, 기준이 되는 디렉토리등... 각각의 게시판의 환경은 최상위 환경파일로부터 기본적인 사항들을 물려받고, 각 DB 변수로 자신들만의 필요한 환경들을 가지게 됩니다. 이 각각의 환경들을 조금만 조작하면, 게시판마다 특색있은 모양새나 기능들의 제한을 둘수도 있죠.

etc

 여기선 기본적인 이해만을 얘기하도록 하겠습니다. 지금까지 해온 것을 바탕으로 머찐 게시판을 만들어 보시기 바랍니다. 물론! 만들면 제게도 나누어 주세요. ^_^

File Upload(파일 올리기)

 파일을 올리는건 어렵지 않습니다. cgi-lib.pl 이라는 좋은 라이브러리가 있으니깐요. 이 라이브러리 안에는 변수의 파싱과 에러 처리, 그리고 파일을 업로드 할 수 있는 함수가 미리 만들어져 있습니다. 클라이언트와 서버가 어떻게 어떤 원리로 파일이 업로드 되는지 몰라도, 우리는 우리가 하고자 하는 작업(파일 업로드)을 쉽게 처리할 수 있습니다. http://www.bio.cam.ac.uk/cgi-lib에 가시면 cgi-lib.pl 에 관한 정보를 보실 수 있습니다.

HTML에서의 태그

 파일을 업로드 하기 위해선

<form action=upload.cgi method=post ENCTYPE="multipart/form-data">

이렇게 form 태그를 정의 해주셔야 합니다. 그리고 반드시 ENCTYPE="multipart/form-data" 를 넣어주셔야 하고, POST방식으로 서버에 정보를 주셔야 합니다.

<input type=file name=upfile size=30>

그리고 input 방식을 file 로만 주시면 업로드 폼은 완료됩니다. 이렇게 하시면, 업로드될 파일의 '찾기' 버튼까지 자동으로 만들어 줍니다. 이제 업로드할 준비가 되었습니다.

cgi-lib.pl 사용

 이젠 프로그램을 해야죠. 하기전에 cgi-lib.pl의 내용을 잠시 보겠습니다. 필요에 따라서 우린 이 라이브러리를 수정해야죠. 하지만 파일의 업로드 크기를 결정하는것 외에는 별루 만져줄 건 없습니다. 프로그램 내에선 &ReadParse; 만 해주시면 됩니다.

업로드 크기(size)

 우선, 제 자료실에 있는걸 다운받으셔서 보시면 처음에 설명부분이 꽤 깁니다. 하지만 요 중간중간에 변수가 설정이 되어 있습니다. 하지만 우리가 볼 건,

$cgi_lib'maxdata    = 1310720;    # 업로드될 파일의 크기

 요거 하나면 됩니다. 그 아래는 '웬만하면 건드리지 말것' 이라고 써있구여... 위 수치는 바이트(byte) 단위로 되어 있습니다. 이것을 적절히 바꾸어 주시면 됩니다.

파일명 얻기(GetFileName)

 *incfn이라고 되어 있는 변수가 보이실 겁니다. 우리가 브라우저에서 파일을 선택해서 올리면, 경로명과 함께 위의 변수에 파일명이 저장됩니다. 서버에 저장할 때 경로명까지 한꺼번에 저장할 필요는 없죠. 우리는 파일명만을 추려냅니다.

$UpFileName = $incfn{'upfile'};
$UpFileName =~ s/.+\\([^\\]+)$|.+\/([^\/]+)$/\1/;
						

 경로가 포함된 파일명을 얻어서, 파일 이름만을 추려내는 과정입니다.

서버에 파일 쓰기(Write)

 그럼 파일을 선택하고, 보내기 버튼을 눌렀으니깐, 서버에 저장만 하면 됩니다.

open (UPF, ">$UpDir/$UpFileName") || die;
binmode UPF;
print UPF $input{'upfile'};
close (UPF);
						

 이게 끝입니다. 이러면 파일이 서버에 저장이 됩니다. $Updir은 파일이 저장될 디렉이구여, $input{'upfile'}은 서버에 저장할 파일명이죠. 위의 태그에서 저장한 그 이름입니다. binmode 는 쓸려는 파일을 바이너리 모드로 바꾸어 주는 함수 입니다. 만약 binmode를 사용하지 않고, 바이너리 파일을 올렸을 경우, 파일이 깨지는 현상을 보실 수 있습니다.

 끝났습니다. 서버에 파일이 올려졌습니다.

DownLoad(다운로드)

 업로드가 이 정돈데..... 다운로드는 더 쉽습니다.

  1. 파일명 얻기
  2.  물론 다운을 수행하는 프로그램에 파일명은 변수로 들어 가겠죠. down.cgi?file=파일명 디렉토리를 구분하고 있었다면, 디렉토리를 포함, 그래서 파일명을 얻으면 됩니다.

    $down_file_name = $UpDir."/".$input{'file'};

    이런식으로요.

  3. 다운시 필요한 헤더 찍기
  4. print "Content-type: text/html\n\n";

     위의 것은 '지금부터 보내는 정보는 일반 텍스트 정보다' 라고 알려주는 거죠. 지금까지 많이도 썼습니다. 물론 위의 타입은 서버의 MIME 타입에 이미 지정되어 있는거구요.

     파일을 다운받기 위해서는 다른 헤더를 보내야 합니다.

    print "Content-type: application/BlackUni\n\n";

    위와 같은 헤더를 보내게 됩니다. application/BlackUni타입은 서버에 지정되지 않은 타입입니다. 서버에서 실행이 되지 않고, 다운이 되게 해 주죠.

     application 헤더는 특정 응용 프로그램에서만 처리되는 특수한 포맷의 파일들의 형식을 나타내는 헤더입니다.

    print "Content-type: application/octet-stream\n\n";
  5. 파일쓰기
  6. open (DOWN, "$down_file_name") || die print "Error! $!\n";
    binmode(DOWN);
    binmode(STDOUT);
    binmode(STDERR);
    print <DOWN>;
    close (DOWN);
    						

     위와 같이 하면 파일을 본인의 하드에 쓰게 됩니다. binmode 를 사용해서, 파일과 표준 출력, 표준 에러를 바이너리로 사용할 수 있게 바꿉니다. 안 그러면, 바이너리 파일도 텍스트로 전송이 됩니다.

 다운을 받기위해 링크를 누르게 되면 '다운로드 창'이 뜹니다. 늘 보던 화면이죠. 이게 끝입니다.


NOTES

 이번엔 게시판의 좀 더 향상된 기능을 위한 것을 보았습니다. 이것으로 관리자모드를 제외한 게시판 만들기의 부분은 끝났습니다. 다음에 관리자를 위한 프로그램을 만들어 보겠습니다.


이 문서는 Perl 패키지내의 pod2html를 이용하여 만들었습니다. - Kim Young Soo