이 게시물은 지금은 폐쇄되어 접속되지 않는 Kim Young Soo(http://hours.interpia98.net/~unisoo/)님의 웹 사이트에 2001년경 게시된 내용을 바탕으로 오늘날 웹 환경에 맞게 내용을 덧붙였습니다.
Perlprog - GuestBook 1
Description
방명록 만들기 1 - 폼, 입력, 저장
GuestBook 만들기 1
최소한의 기능만을 갖춘 방명록을 만들어 보죠. 폼에서 데이타를 받아서 저장하고, 그것을 읽어서 일정한 폼에 되돌려 줄수 있는 방명록을 만들어 보도록 하겠습니다. 세번에 나누어서 하겠습니다. 궁금하신점은 게시판을 이용해 주세요.
HTML Form
<form action="../cgi-bin/guest_book.cgi" method=post> <table border=0 bgcolor=white width=550> <tr> <td align=right width=100 bgcolor=#d2eefe><font size=2 color=#376eda><b>Name :</b></font></td> <td><input type=text name="username" size=20 maxlength=20></td> </tr> <tr> <td align=right bgcolor=#d2eefe><font size=2 color=#376eda><b>하실말씀 :</b></font></td> <td><textarea name="body" rows=10 cols=40></textarea></td> </tr> <tr> <td colspan=2><input type=submit value="Submit"><input type=reset value="Clear"></td> </tr> </table> </form>
위의 폼은 방명록 입력양식이지요. 많이 넣지 않았습니다. 이름과 내용을 넣을수 있는 자리만 만들었어요. 이 글을 읽는 분은 <form>태그에 대해서 어느정도 아신다는 가정하에 합니다. 모르시면 게시판에 질문남겨 주세요.
GET 전송방식
CGI에서는 변수를 서버로 보내는 방법이 POST와 GET 두 가지가 있습니다. 저는 여기서 POST 방법을 썼구여, 이 두 가지 타입에 대해 간단히 알아보겠습니다.
여러분들이 심마니나 야후에서 정보검색을 하신적이 있으실 겁니다. 그 때 주소부분의 URL을 보시면 그게 무쟈게 길어요. www.simmani.com/........./...../ 이러면서 나갑니다. 이것은 GET방식으로 데이터를 전송한겁니다.
GET방식을 이용하면 사용자가 입력한 내용이 변형되어(공백은 '+'로 특수문자는 아스키값으로...) 긴 문자열이 된후 서버로 전송이 됩니다.
이 전송된 데이터는 %ENV환경변수의 'QUERY_STRING'에 접근함으로서 사용할 수 있지요.
만약에 위의 폼에서 방식을 GET으로 바꾸고 이름에 'uni'를, 내용에 'hahaha'를 입력했을경우, 브라우저의 주소란에는 'http://..../cgi-bin/....?username=uni&body=hahaha' 라고 나올겁니다. CGI파일이름과 변수사이에는 '?'가 변수명과 변수 사이에는 '='가 또 그 값들 사이는 '&'가 들어 값니다. 이 값을 받아서 우리는 CGI 프로그램을 할 때 사용할 수 있죠.
이 방식의 단점은 그 데이터의 길이가 제한되었다는 것과, 비밀번호와 같은 내용을 입력 할 경우 그 내용이 그대로 노출된다는 거죠.
POST 전송방식
POST 방식은 이거와는 다르게 사용자가 입력한 변수의 내용들이 브라우져에 출력되지 않습니다. POST방식으로 보내면, 그 내용을 품어서 인코딩되어서 서버로 보내지죠.
그러면 우리는 환경변수 'CONTENT_LENGHT'를 써서 이 변수들을 사용할 수 있습니다. 위 환경변수는 보내진 데이터의 총 길이를 담고 있습니다.
GET으로 보내진 데이터를 받을 때:
$temp = $ENV{'QUERY_STRING'}; # <-- 보내진 데이터를 바로 받습니다.
POST로 보내진 데이터를 받을 때:
read(STDIN, $temp, $ENV{'CONTENT_LENGHT'}; # <-- 표준입력(STDIN)으로 들어온 값을 CONTENT_LENGTH의 길이만큼 읽어서 $temp에 저장하라는 내용입니다.
그 다음의 프로그램 과정은 동일합니다.
guest.cgi - 데이터 저장
그럼 이제 guest.cgi라는 파일을 만들어서 시작하겠습니다.
#! /usr/perl/bin # <-- 이건 아시죠? read(STDIN, $temp, $ENV{'CONTENT_LENGTH'}); # <-- $temp에 넘어온 변수를 저장합니다. @guest = split(/&/, $temp); # <-- 넘어온 변수를 '&'를 기준으로 분리해서 @guest에 차례로 저장합니다. # ...
이 split() 함수는 기준이 되는 문자('&')로해서 문자열을 나누어 주는 역할을 합니다. 위에서 변수가 서버로 넘어 올때 값1=내용1&값2=내용2&값3=내용3... 이렇게 넘어온다고 했죠. 이렇게 하게되면 @guest에는 '값=내용'의 값이 차례로 저장됩니다.
foreach $item(@guest) { ($key, $value) = split(/=/, $item); $value =~ tr/+/ /; $value =~ s/%(..)/pack("c", hex($1))/ge; $fields{$key} = $value; }
위의 내용을 차근히 보죠.
foreach 에서는 @guest
의 값을 차례로 ($guest[0], $guest[1]..) $item
변수에 저장합니다. 더 이상 @guest
에 값이 없을 때까지 순환을 하게 됩니다.
($key, $value) = split(/=/, $item); 는 넘어온 $item
문자열을 '='를 기준으로 $key, $value에 저장합니다. 이렇게 되면, $key에는 username을 $value에는 uni가 들어가게되죠.
$value =~ tr/+/ /;는 위에서 분리된 value의 값에서 '+' 기호를 공백으로 바꾸어줍니다. 위에서 얘기했죠? 서버로 넘어올때 공백은 '+'로 바뀌어서 넘어온다구여. 이걸 다시 원래대로 바꾸어 주는 겁니다.
$value =~ s/%(..)/pack("c", hex($1))/ge; 는 아스키값으로 바뀐 특수문자들을 원래대로 바꾸어주는 라인입니다.
위에서 쓰인 tr///과 s/// 는 치환이나 대치를 할때 쓰입니다. 처음//사이에는 치환할 문자, 그 다음//사이에는 치환할 문자가 오게 되죠. tr과 s의 차이는 tr에는 그냥 바꿀 문자가 오는 거지만, s에는 ///사이에 문서패턴이나 정규표현이 오게되죠. 패턴에 대해서는 기초문법강의를 참조 하세요.
순환문의 마지막에 오는 $fields{$key} = $value;
는 %fields라는 결합배열에 키값과 그 키값에 대응하는 값을 저장하는 과정입니다.
흠... 위 6라인으로 넘어온 데이터를 원래대로 환원하였습니다. 데이타가 아무리 많아도 위 여섯 라인이면 깨끗하게 해결이 되죠. 위 6라인은 두고두고 쓰입니다. 이해하시고 기냥 외워두시는게 더 좋은거 같아여....
$fields{'body'} =~ s/\n\n/ /g; $fields{'body'} =~ s/\n/ /g;
위의 세 라인은 body의 내용에서 엔터가 들어간 곳을 공백으로 바꾸어 주는 역할을 합니다. '\n'는 개행문자죠. 기초 문법을 참조 하세요.
이제 데이터를 사용할 준비가 끝났군요. 그럼 파일에 저장을 할까요?
open (FILE, ">guestbook.txt") || die "Can't use DBM file"; print FILE "$fields{'username'}::$fields{'body'}\n"; close (FILE);
위의 내용은 잘 아시겠죠? 단 FILE에 프린트 할때 각각의 내용사이에 '::'를 넣어주었습니다. 일종의 분리자죠. 이 내용을 다시 읽을 때 :: 를 기준으로 읽게 됩니다.
이번엔 여기까지만 하겠습니다. 아직 더 붙일 내용이 많아여. 사용자가 입력을 제대로 했는지 확인도 해야되고, 누군가 ::를 입력했다면 다음에 읽을 때 이상한 결과가 나오겠죠. 그리고 입력한 날짜도 넣구 싶고, 이어서 계속 합니다.
NOTES
이번엔 여기까지만 하겠습니다. 아직 더 붙일 내용이 많아여. 사용자가 입력을 제대로 했는지 확인도 해야되고, 누군가 ::를 입력했다면 다음에 읽을때 이상한 결과가 나오겠죠. 그리고 입력한 날짜도 넣구 싶고, 흠.... 이런 내용은 다음에 하도록 하겠습니다.
'Common Gateway Interface > Perl' 카테고리의 다른 글
[옛 강좌] 21. Perlprog - GuestBook 3 (0) | 2015.04.29 |
---|---|
[옛 강좌] 20. Perlprog - GuestBook 2 (0) | 2015.04.29 |
[옛 강좌] 18. Perlprog - Counter (0) | 2015.04.29 |
[옛 강좌] 17. Perlfunc - 펄 함수 12 (0) | 2015.04.29 |
[옛 강좌] 16. Perlfunc - 펄 함수 11 (0) | 2015.04.29 |