본문 바로가기

Common Gateway Interface/Perl

Perl(CGI)에서 POST 방식, GET 방식으로 파라미터 얻기

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

Perl(CGI)에서 POST 방식, GET 방식으로 파라미터 얻기

PHP 등 현대적인 웹 언어와 달리 Perl은 POST/GET 방식으로 파라미터를 얻는 방식은 다소 번거롭다. 이 포스팅을 통해 정리해보고자 한다.

 

1. POST 방식으로 데이터를 주고 받기

먼저 주소창에 데이터가 나타나지 않는 POST 방식으로 데이터를 주고 받아보는 예제이다.


 

1-1. post-send.cgi

POST 방식으로 웹 페이지로 데이터를 전송하기 위한 폼을 구성한다. 일반 텍스트를 입력받아 전달하는 member_id 매개변수와, 암호형 텍스트를 입력받아 전달하는 member_pw 매개변수를 정의한다.


#!/usr/bin/perl

print "Content-type: text/html\n\n";
print<<EndOfHTML;
<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Send by POST</title>
    </head>
    <body>
        <form method="post" action="post-receive.cgi">
            <label>ID: <input type="text" name="member_id" /> </label>
            <label>PW: <input type="password" name="member_pw" /> </label>
            <input type="submit" />
        </form>
    </body>
</html>

EndOfHTML

 

웹 브라우저로 실행 시 다음과 같이 입력 폼이 나타날 것이다.

$ lynx http://localhost/cgi-bin/post-send.cgi

 

1-2. post-receive.cgi

앞서 작성한 post-send.cgi로부터 POST 방식으로 전달된 member_id 매개변수와 member_pw 매개변수를 이 페이지에서 받고자 한다. POST 방식으로 전달된 데이터는 Perl 페이지에서 STDIN 객체를 통해 읽을 수 있다. STDIN 객체로 전달된 데이터는 read 함수를 통해 변수로 옮긴다.


POST 방식으로 전달된 데이터의 크기는 아래의 환경변수로써 구할 수 있다.

$ENV{'CONTENT_LENGTH'}

 

우선 POST 방식으로 전달된 데이터의 크기를 출력해본다.

#!/usr/bin/perl

print "Content-type: text/html\n\n";
print<<EndOfHTML;
<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Receive by POST</title>
    </head>
    <body>
        <p>Parameter received by POST method (total $ENV{'CONTENT_LENGTH'} byte(s).) :</p>
    <body>
<html>

EndOfHTML

 

웹 브라우저로 실행한 결과이다.

post-send.cgi의 화면 :

 

post-receive.cgi의 화면 :

 

POST 데이터의 크기를 확인하였다면, POST 데이터를 실제로 읽어온다. 읽어오는 방법은 다음과 같다.

read(STDIN, <지역변수>, <데이터의 길이>);

 

데이터의 길이는 $ENV{'CONTENT_LENGTH'}임을 확인하였으므로,

read(STDIN, <지역변수>, $ENV{'CONTENT_LENGTH'});

 

POST 방식으로 전달된 데이터의 크기와 그 내용을 출력해본다.

#!/usr/bin/perl

my $paramPOST = undef; # POST 방식으로 전달된 데이터를 보관할 임시 변수

# 위 변수에 POST 데이터를 읽어옵니다.
read(STDIN, $paramPOST, $ENV{'CONTENT_LENGTH'});

print "Content-type: text/html\n\n";
print<<EndOfHTML;
<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Receive by POST</title>
    </head>
    <body>
        <p>Parameter received by POST method (total $ENV{'CONTENT_LENGTH'} byte(s).) :</p>
        <!-- 이 곳에 POST 데이터가 출력됨 -->
        <p>$paramPOST</p>
    </body>
</html>

EndOfHTML

 

웹 브라우저로 실행한 결과이다.

post-receive.cgi의 화면 :

 

위에서 읽은 POST 데이터는 매개변수의 이름과 매개변수의 값이 분리되어 있지 않아서 처리가 어렵다. Perl 기본 연산자들을 활용하여 POST 데이터의 매개변수 이름과 그 값을 따로따로 분리해보도록 한다. '&' 기호를 기준으로 하여 '이름=값'의 쌍을 분리한 다음 각 쌍에 대해 '=' 기호를 기준으로 하여 다시 이름과 값을 분리하는 절차로 이루어진다.

문자열을 특정 문자를 기준으로 분할하는 함수는 다음과 같다.

@반환배열 = split(/문자/, $문자열);

그리고 이렇게 분할된 "이름=값" 쌍이 총 몇 개인지를 세는 방법은 다음과 같다. 아무거나 편한 방식을 쓰면 된다.

1. 배열을 구성하는 원소들의 개수를 얻기 (1)
$개수 = scalar @배열;

또는,

print scalar @배열;
2. 배열을 구성하는 원소들의 개수를 얻기 (2)
$개수 = @배열;
print $개수;
3. 배열의 가장 마지막 원소의 index 번호를 얻기
$마지막인덱스 = $#배열;
$개수 = $마지막인덱스 + 1;

 

문자열 분할과 개수 세는 방법을 위의 소스에 적용하여 POST를 "이름=값"의 쌍으로 분리해본다.

#!/usr/bin/perl

my $paramPOST = undef; # POST 방식으로 들어온 데이터 원문
my @pairPOST = undef; # '&' 기호를 기준으로 분할한 문자열("이름 = 값"의 쌍)
my $countPOST = undef; # 위 배열의 원소 개수, 즉 쌍의 수

read(STDIN, $paramPOST, $ENV{'CONTENT_LENGTH'}); # POST 데이터 읽기
@pairPOST = split(/&/, $paramPOST); # '&' 기호를 기준으로 분할
$countPOST = scalar @pairPOST; # 위 배열의 원소 개수 구함

print "Content-type: text/html\n\n";
print "<!doctype html>";
print "<html>";
print "<head>";
print "<meta charset=\"utf-8\" />";
print "<title>Receive by POST</title>";
print "</head>";
print "<body>";
print "<p>Parameter received by POST method (total $ENV{'CONTENT_LENGTH'} byte(s).) : </p>";
print "<p>$paramPOST</p>";
print "<p> </p>";
print "<p>Splitted parameter (total $countPOST pair(s).) : </p>";
print "<p>";
#foreach $임시변수(@배열)
foreach $pair(@pairPOST)
{
    ($name, $value) = split(/=/, $pair);
    print "name: $name ... value: $value<br />";
}
print "</p>";
print "</body>";
print "</html>";

 

다음과 같이 이름와 값의 쌍이 분리되어서 출력됨을 확인할 수 있다. 이를 통해 POST 데이터 중 특정 매개변수를 찾을 수 있다.

 

위와 같은 POST 데이터 읽기는 매우 번거롭다. 이를 단순화 하여 원하는 매개변수를 바로 가져오는 방법으로 CGI 모듈을 사용할 수 있다. 다음은 CGI 모듈을 통해 POST 방식으로 들어온 데이터를 간편하게 가져오는 예이다.

#!/usr/bin/perl

use CGI qw/:standard/;

$objCGI = CGI->new; # CGI 객체를 초기화하고 STDIN으로부터 알아서 데이터들을 읽어온다.
$memberID = $objCGI->param('member_id'); # post-send.cgi에서 보낸 'member_id' 이름의 매개변수를 가져온다.
$memberPW = $objCGI->param('member_pw'); # post-send.cgi에서 보낸 'member_pw' 이름의 매개변수를 가져온다.

print "Content-type: text/html\n\n";
print<<EndOfHTML;
<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Receive by POST</title>
    </head>
    <body>
        <p>member_id == '$memberID'</p>
        <p>member_id == '$memberPW'</p>
    </body>
</html>

EndOfHTML

 

post-receive.cgi의 화면 :

 

2. GET 방식으로 데이터를 주고 받기

다음은 주소를 통해 데이터를 주고받는 GET 방식으로 데이터를 교환한다.

 

2-1. get-send.cgi

POST 방식으로 웹 페이지로 데이터를 전송하기 위한 폼을 구성한다. 일반 텍스트를 입력받아 전달하는 member_id 매개변수와, 암호형 텍스트를 입력받아 전달하는 member_pw 매개변수를 정의한다.


#!/usr/bin/perl

print "Content-type: text/html\n\n";
print<<EndOfHTML;
<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Send by GET</title>
    </head>
    <body>
        <form method="get" action="get-receive.cgi">
            <label>ID: <input type="text" name="member_id" /> </label>
            <label>PW: <input type="password" name="member_pw" /> </label>
            <input type="submit" />
        </form>
    </body>
</html>

EndOfHTML

 

2-1. get-receive.cgi


GET 방식으로 전달된 파라미터를 읽어오는 환경변수는 다음과 같다.

$ENV{'QUERY_STRING'}

 

#!/usr/bin/perl

print "Content-type: text/html\n\n";
print<<EndOfHTML;
<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Receive by GET</title>
    </head>
    <body>
        <p>Parameter received by GET method :</p>
        <!-- 이 곳에 GET 데이터가 출력됨 -->
        <p>$ENV{'QUERY_STRING'}</p>
    </body>
</html>

EndOfHTML

 

웹 브라우저로 실행한 결과이다.

get-receive.cgi의 화면 :

 

환경 변수를 통해 읽은 쿼리 문자열을 이름과 값으로 분할하는 것은 위의 POST 방식과 같다. 또한 CGI 모듈을 통해 POST 방식에서와 동일한 방법으로 데이터를 읽어올 수 있다.

#!/usr/bin/perl

$objCGI = CGI->new;
$memberID = $objCGI->param('member_id');
$memberPW = $objCGI->param('member_pw');

print "Content-type: text/html\n\n";
print<<EndOfHTML;
<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Receive by GET</title>
    </head>
    <body>
        <p>Parameter received by GET method :</p>
        <!-- 이 곳에 GET 데이터가 출력됨 -->
        <p>$ENV{'QUERY_STRING'}</p>
        <p>memberID = '$memberID'<br />memberPW = '$memberPW'</p>
    </body>
</html>

EndOfHTML

 

get-receive.cgi의 화면 :