CGI.pm으로 프로그램을 작성할때에는 두가지 프로그래밍 스타일, 즉 개체 지향 스타일과 함수 지향 스타일을 사용할 수 있다. 개체 지향 스타일에서는 하나 이상의 CGI 개체를 생성하고 페이지의 다양한 요소를 생성하기위해 메소드를 사용한다. 각각의 CGI 개체는 서버에의해 CGI로 전달된 기명 매개변수의 목록으로 초기화 된다. 사용자는 이 개체를 변경하고 이들을 파일이나 데이타 베이스에 저장하고 또 이들을 다시 생성할 수 있다. 각 개체는 CGI의 "상태"와 상응하며 각각의 개체의 매개변수 목록은 서로 독립적이기 때문에 이들을 이용해서 스크립트의 상태를 저장하고 나중에 다시 복구할 수 있다.
예로서 개체 지향 스타일을 사용해서 "안녕, 깜직아"를 출력하는 HTML 페이지를 만들어 보자.
함수 지향 스타일에서는 하나의 기본 CGI 개체만 존재하며, 이 개체가 직접 사용되는 것은 아주 드물다. 개체를 사용하는 대신에 CGI 매개변수를 복원하고 HTML 태그를 생성하고 쿠키를 처리하기위해 함수를 호출한다. 이 방법은 보다 분명한 프로그래밍 환경을 제공해 주지만 한번에 하나의 CGI 개체만 사용해야하는 제약이 있다. 다음 예는 위의 예와 동일한 예이지만 함수 지향 환경을 사용하고 있다. 주된 차이는 함수의 집합을 이름 공간(보통 표준 함수)로 가져오기만 하면 된다는 것이다. 굳이 개체를 생성할 필요는 없다.
각각의 인자 이름은 대쉬(-) 다음에 나온다. 인자 목록에서 대소문자는 구분하지 않으며 순서 역시 구분하지 않는다. 즉, -type, -Type, -TYPE 모두 사용할 수 있다. 사실 첫번째 인자만 대쉬(-)로 시작해도 된다. 첫 번째 인자에 대쉬(-)가 존재하면 CGI.pm은 이어지는 인자도 대쉬가 있는 것으로 가정한다.
대쉬를 사용하고 싶지 않다면 대쉬를 전혀 사용하지 않아도 된다. 개체를 생성한 후 "0"이 아닌 값으로 use_named_parameters()를 호출함으로서 기명 인자 호출을 사용하지 않겠다는 것을 CGI.pm에 알려줄 수 있다.
$query = new CGI;
$query->use_named_parameters(1);
$field = $query->radio_group('name'=>'OS',
'values'=>['유닉스','윈도그','맥킨토시'],
'default'=>'유닉스');
여러 루틴들은 통상 하나의 인자로 호출된다. 이러한 루틴의 경우에는 인자 이름 없이 하나의 인자만 주면 된다.
header()
는 이러한 루틴들 중 하나이다. 이 경우에 하나의 인자는 문서의 유형이다.
print $q->header('text/html');
다른 이러한 루틴들은 아래에 문서화되어 있다.
때때로 기명 인자들은 스칼라를 참조하며, 가끔 배열이나 연관배열을 참조한다. 어떠한 형태의 인자든지 전달할 수 있으며, 루틴은 전달된 인자가 무엇이든 가장 적당하게 처리한다. 예를들어
param()
루틴은 하나 또는 여러 개의 값으로 CGI 매매변수를 설정하는데 사용된다. 다음은 이 두 경우에대한 예이다.
CGI.pm의 아주 많은 루틴들은 모듈내에 특별히 정의되지 않았지만 필요시 자동적으로 생성된다. 이들은 동적으로 HTML 페이지를 만드는데 사용되는 "HTML 메소드"들이다. HTML 태그는 속성(태그 자체내에서 사용되는 속성=값의 쌍)과 내용(시작 태그와 종료태그 사이에 존재하는 내용)을 모두 갖는다. 속성과 내용을 구분하기위해 CGI.pm은 첫번째 인자를 연관배열로 참조함으로서 HTML 속성을 전달하며 이어지는 인자는 내용을 참조한다.
코드 생성된 HTML
---- --------------
h1() <H1>
h1('무슨','내용일까?'); <H1>무슨 내용일까?</H1>
h1({-align=>left}); <H1 ALIGN="LEFT">
h1({-align=>left},'내용'); <H1 ALIGN="LEFT">내용</H1>
CGI.pm을 처음 사용하는 사람들은 HTML 태그 관련 함수의 호출 규칙(HTML 태그 속성을 중괄호로 감싸는)과 다른 루틴의 호출 규칙(중괄호 없이 속성을 만드는) 사이의 차이 때문에 혼란스러울 것이다. 혼란스러워할 필요는 없다. 중괄호는 모두 옵션이다. 만약 원한다면 기명 인자를 취하는 임의의 루틴을 호출할 때 중괄호를 사용할 수 있다. 예를들어:
-w 스위치를 사용한다면 몇몇 CGI.pm 인자의 이름이 내장된 펄 함수와 충돌을 일으킨다는 경고를 보게될 것이다. 이들중 가장 빈번한 것은 다중 값을 갖는 메뉴(레디오 버튼과 같은)를 생성하는데 사용되는 -values 인자이다. 이 경고를 우회하기위해서는 여러가지 방법이 있다.
가능하다면 다른 이름을 사용한다. 예를들어 -value는 -values의 별칭이다.
대소문자를 변경한다. 예: -Values
인자 이름을 작은 따옴표로 감싼다. 예: '-values'
많은 루틴들에서 루틴이 인식하지 못하는 기명 인자를 사용할 수 있다. 예를들어 인식히지 못하는 인자를 루틴에 제공함으로서 비표준 HTTP 헤더 필드를 생성할 수 있다.
메소드는 매개변수의 이름을 배열로 리턴할 것이다. 스크립트가 <ISINDEX>로 호출되었다면 'keywords'라는 하나의 매개변수가 리턴된다.
주의:
1.5 판에서 처럼 리턴된 매개변수 이름 배열은 브로우저에의해 제출된 순서와 동일한 순서로 저장된다. 보통 이 순서는 매개변수를 폼에서 정의한 순서와 같다(그러나 이 것이 표준은 아니며 따라서 어떠한 것도 보증할 수는 없다).
하나의 기명 매개변수의 값(들) 가져오기
@values = $query->param('foo');
또는
$value = $query->param('foo');
기명 매개변수의 값을 가져오기위해
param()
메소드에 하나의 인자를 전달한다. 매개변수가 다중 값을 가지고 있다면(선택 목록의 다중선택) 배열로 받을 수 있다. 그렇지 않다면 이 메소드는 하나의 값을 리턴한다.
기명 매개변수 값의 설정
$query->param('foo','임의의','배열의','값');
이 것은 리스트로 'foo'라는 매개변수의 값을 설정한다. 이 것이 스크립트가 일단 호출된 후 필드의 값을 변경하는 한 방법이다.(또 다른 방법은 모든 메소드에의해 허용되며 폼 요소를 생성하는데 사용되는 -override 매개변수이다.)
이름과 값은 URL에서 특수문자가 제거된 형식이다. 다중 값을 갖는 CGI 매개변수는 반복적인 이름으로 표현된다. 각각의 기록은 하나의 =에의해 분리된다. 또한 이러한 상태를 여러번 쓰고 new를 여러번 호출함으로서 이들을 다시 읽을 수 있다. 추가 모드로 파일을 오픈함으로서 여러 세션을 저장할 수 있다. 이 방법으로 간단한 방명록을 작성할 수 있으며 사용자의 질의 목록을 유지할 수 있다. 여기 다중 세션 기록을 생성하는 짧은 예가 있다.
1 : #!/usr/local/bin/perl
2 : use CGI;
3 :
4 : open (OUT,">>./save/test.txt") || die;
5 : $records = 5;
6 : foreach (0..$records) {
7 : my $q = new CGI;
8 : $q->param(-name=>'counter',-value=>$_);
9 : $q->save(OUT);
10 : }
11 : close OUT;
12 :
13 : $q = new CGI;
14 : # 읽기위해 다시 파일을 연다.
15 : print $q->header, $q->start_html, $q->pre;
16 :
17 : open (IN,"./save/test.txt") || die;
18 : while (!eof(IN)) {
19 : my $q = new CGI(IN);
20 : print $q->param('counter'),"\n";
21 : }
22 :
23 : print $q->pre, $q->end_html;
저장/복원에서 사용된 파일 형식은 Whitehead Genome Center의 데이타 교환형식, "Boulderio"에의해 사용된 것과 동일하며 Boulderio 유틸리티를 사용해서 조작, DB화 될 수 있다. 보다 자세한 것은 BOULDER을 보기 바란다.
함수 지향 환경에서 이 방법을 사용하려면 save_parameters()을 사용한다.
함수 지향 환경을 사용하기
함수 지향 환경을 사용하기위해 이름 공간으로 가져올 루틴이나 루틴의 집합을 지정해야 한다.
use CGI <메소드의 목록>;
이 방법은 메소드의 목록을 현재의 패키지로 가져오게된다. CGI 개체를 생성하지 않고 직접 이들을 호출할 수 있다. 이 예는 param()과 header()를 가져오는 방법과 이들을 직접 사용하는 방법을 보이고 있다.
use CGI 'param','header';
print header('text/plain');
$zipcode = param('zipcode');
이름에의해 그룹지어진 함수을 공통집합을 가져오는 경우가 많을 것이다. 모든 함수 집합은 ":html3"('HTML 3 표준에 정의된 태그)처럼 ":" 문자로 시작된다.
여기 가져올 수 있는 함수 집합의 목록이 있다.
:cgi
param(), path_info()와 같은 CGI를 처리하는 모든 메소드를 가져온다.
:form
textfield()와 같이 폼을 생성하는 메소드를 가져온다.
:html2
HTML 2.0의 표준 태그를 생성하는 모든 메소드를 가져온다.
:html3
HTML 3.0에서 제안된 태그(<table>, <super>와 <sub>와 갈은)를 생성하는 모든 메소드를 가져온다.
:netscape
넷스케잎에서 정의한 HTML 확장을 생성하는 모든 메소드를 가져온다.
:html
모든 HTML 태그(예:'html2' + 'html3' + 'netscape')를 생성하는 메소드를 가져온다.
:standard
표준 특징, 'html2', 'html3', 'form'과 'cgi'을 가져온다.
:all
사용할 수 있는 모든 메소드를 가져온다. 완전한 목록은 %TAGS가 정의된 CGI.pm의 코드를 본다.
CGI.pm에서 지원하지 않는 함수명을 가져온다면 CGI.pm은 이 것을 새로운 HTML 태그로 처리하며 적당한 서브루틴을 생성한다. 그리고 나서 이 것을 다른 HTML 태그와 같이 사용할 수 있다. 이 것은 급속도로 변하는 HTML 표준을 위해 제공된다. 예를들어 Money$fot는 <GRADIENT>라는 새로운 태그(컴퓨터를 다시 부팅할 때까지 사용자의 데스크탑의 색상을 주기적으로 변경하는)을 발표했다. 이 것을 사용하기위해 CGI.pm의 새버전을 기다릴 필요없이 다음과 같은 방법을 사용하면 된다.
use CGI qw/:standard :html3 gradient/;
print gradient({-start=>'red',-end=>'blue'});
주의:
CGI.pm의 실행속도에 관심이 있다면 읽을 심볼을 지정하는 표준 Exporter 형식을 사용하지 말기 바란다. 이 것은 앞으로 변경될 것이다.
임의의 상태 유지 CGI를 가져오거나 폼을 생성하는 메소드를 가져오면 기본 CGI 개체가 생성되며 임의의 메소드를 처음 사용할 때 자동적으로 초기화된다. 이러한 것에는 param(), textfield(),
submit()와 같은 것들이 있다(CGI 개체를 직접 접근하려면 전역 변수, $CGI::Q를 사용한다). CGI.pm의 메소드를 가져옴으로서 보기에 훨씬 우아한 스크립트를 작성할 수 있다.
함수의 집합외에서 가져올 수 있는 많은 수의 프라그마가 존재한다. 항상 대쉬(-)로 시작하는 프라그마는 CGI.pm의 동작 방법을 변경한다. 프라그마, 함수집합과 개개의 함수는 동일한
use()
행을 통해 가져올 수 있다. 예를들어 다음에 사용한 문장은 함수의 standart집합을 디버깅 모드를 끈 상태(프라그마 -no_debug)에서 가져오게 된다.
use CGI qw/:standard -no_debug/;
프라그마의 현재 목록은 다음과 같다.
-any
CGI -any를 사용하면 질의 개체가 인식하지 못하는 임의의 메소드는 새로운 HTML 태그로 해석된다. 이 것으로 넷스케잎이나 Money$oft의 특별한 HTML 확장을 지원할 수있다.
use CGI qw(-any);
$q=new CGI;
print $q->gradient({speed=>'fast',start=>'red',end=>'blue'});
any을 사용하는 경우 함수의 이름을 잘못입력하면 HTML 태그로 해석되므로 이 것은 가급적 사용하지 않는 것이 좋다.
-compile
이 것은 지시된 자동 적재 매소드가 먼저 컴파일되게 만든다. 이 것은 FastCGI나 mod_perl하에서 확장된 시간주기에대해 실행되는 스크립트에대해 유용하다. 사용하려는 메소드나 메소드 군에대해 이 것을 사용하기 바란다.
use CGI qw(-compile :standard :html3);
또는
use CGI qw(-compile :all);
주의:
이 방법으로 -compile 프라그마는 항상 컴파일된 함수를 현재의 이름공간으로 가져오는 효과를 갖는다. 가져오지 않고 컴파일하려면 대신에
compile()
를 사용한다.
-nph
CGI.pm이 NPH(Non-Parsed Header) 스트립트에대해 적당한 헤더를 생성하도록 만든다. 스크립트가 NPH라는 것을 서버에 통지하는 것외에 다른 것도 할 필요가 있다. NPH 스크립트에대한 논의는 NPH 스크립트 사용하기와 서버 밀기(몰밀지)를 보기 바란다.
-autoload
이 것은 인식하지 못하는 임의의 함수는 CGI.pm에서 가능한 평가되도록 자동 로더를 중첩시킨다. 이 것으로 사용자는 힘수를 심볼 테이블에 추가하지 않고 모든 CGI.pm의 기능을 사용할 수 있다. 이 것은 메모리 소모를 걱정해야 하는 mod_perl 사용자에게는 관심있는 일일 것이다.
경고:-autoload를 사용하는 경우 함수에는 반드시 괄호를 사용해야 한다. 즉, hr보다는 hr()를 사용하거나 스크립트의 시작부분에 use subs qw/hr p header/와 같은 것을 추가해야 한다.
-no_debug
이 것은 명령행 처리 특징을 사용하지 않게 만든다. 동적으로 생성된 HTML을 만들기위해 CGI.pm 스크립트를 명령행에서 기동하면서 표준입력이나 명령행으로부터 CGI 매개변수를 입력하고 싶지 않다면 이 프라그마를 사용한다.
use CGI qw(-no_debug :standard);
표준입력이 아니라 명령행에서만 매개변수를 처리하길 원한다면 다음과 같이 할 수 있다.
use CGI qw(-no_debug :standard);
restore_parameters(join('&',@ARGV));
CGI.pm은 업로드된 파일을 처리할 수 있다. 보통 이 것은 업로드된 파일을 임시 폴더에 저장하고 파일 업로드가 종료됐을 때 파일을 삭제한다. 그러나 이 것은 파일 업로드 절에서 설명하는 것처럼 위험부담이 있다. CGI 스크립트의 저자는 이 데이타가 극비의 정보라고 할 지라도 업로드 하는 동안 이 데이타를 훔처볼 수 있다. Unix 시스템에서 -private_tempfiles 프라그마는 이러한 위험성을 제거하기 위해 임시 파일을 열고, 심지어 임의의 데이타가 임시 파일에 쓰여지기 전에 바로 삭제되도록 만든다.