이 게시물은 지금은 폐쇄되어 접속되지 않는 Kim Young Soo(http://hours.interpia98.net/~unisoo/)님의 웹 사이트에 2001년경 게시된 내용을 바탕으로 오늘날 웹 환경에 맞게 내용을 덧붙였습니다.
Perlprog - BBS 9
Description
게시판 만들기 9 - 검색
BBS 만들기 9
게시판 만들기 아홉 번째 입니다. 휴... 어느덧 여기까지.... 이제 검색만 프로그램하면, 게시판의 모든 형태는 다 나오게 되네여... 그럼 검색에 대해 생각해 봐여. '이름', '제목', '본문' 이렇게 세 개의 조건으로 검색을 하겠습니다. 물론 동시 검색은 지금하지 않겠습니다. 그건 여러분들이 직접 해보시구여.... 우리가 지금까지 해온 것을 잠깐 보면.. board.idx파일이 있죠. 여기에 '이름'과 '제목'으로 검색을 할 수 있습니다. 그러니 위 두개의 조건이라면 idx파일만 열어서, 해당항목과 검색어를 비교하면 되구여.
'본문'으로 검색을 한다면 각각의 파일을 열어야죠. 열어서 본문에 해당하는 데이터와 검색어를 비교를 합니다. 이 때, 해당 검색어와 조건이 일치하는 줄이 여러 줄에 걸쳐서 나올 수 있습니다. 그러므로, 한 번만 조건이 일치하면 루프를 바로 빠져나오도록 해야 됩니다. 또한 '이름', '제목'으로 검색을 했을 때, 해당 검색어를 빠알간색으로 처리하는 것도 괜찮겠죠. 물론 본문도 그렇게 할 수 있지만, 여기서는 하지 않겠습니다. 그럼 시작합니다.
아.. 참고로, 함수 별로 살펴보겠습니다. 이 함수들을 합해서 하나의 프로그램으로 완성하는 것은 여러분의 몫으로 하겠습니다.(^^;)
board_search.cgi - 데이터 검색
SearchData()
sub SearchData { ### 먼저 검색어가 입력되지 않았을 경우를 처리합니다. if (!$input{'word'}) { &error_message("입력된 검색어가 없습니다."); exit 0; } ### 유효한 검색어인지 검사합니다. ### 이 특수문자에 대해서는 디코딩과정없이, 바로 걸렀습니다. ### 이 특수문자들로 검색을 해보세요. 아주 재밌는 현상이 생깁니다. ### 꼭 해보세요. else { if(($input{'word'} =~ /^\./) || ($input{'word'} =~ /^\\/) || ($input{'word'} =~ /^\(/) || ($input{'word'} =~ /^\*/) || ($input{'word'} =~ /^\$/) || ($input{'word'} =~ /^\|/) || ($input{'word'} =~ /^\^/) || ($input{'word'} =~ /^\)/) || ($input{'word'} =~ /^\+/) || ($input{'word'} =~ /^\[/) || ($input{'word'} =~ /^\) || ($input{'word'} =~ /^\>/) || ($input{'word'} =~ /^\?/)) { ### 위의 조건에 맞다면, 검색결과가 없다는 메세지를 출력합니다. $s_i변수는 검색결과의 개수입니다. $s_i = 0; &search_html($s_i); &search_bottom; exit 0; } } ### 위의 조건을 모두 만족할 경우, 검색항목이 '이름', '제목', '본문'에 따라서 ### 검색을 수행할 'get_search_word()' 함수에 어떤 항목으로 검색하라는 걸 넘겨 줍니다. if ($input{'search_list'} eq 1) { $search_case = 1; &get_search_word($search_case); } elsif ($input{'search_list'} eq 2) { $search_case = 2; &get_search_word($search_case); } else { $search_case = 3; &get_search_word($search_case); } }
get_search_word()
sub get_search_word { ## 위 함수(SearchData()) 함수에서 넘겨준 검색항목을 받습니다. local ($sr_case) = @_; ## 검색결과의 개수를 초기화하고, 검색어를 받습니다. $s_i = 0; $sword = $input{'word'}; ## 검색항목이 '이름' 또는 '제목' 일 경우입니다. ## board.idx 파일을 열어서 '::'로 분리를 한 다음, '이름'은 배열의 2번째, ## '제목'은 배열의 3번째 값이므로, 그 값과 검색어를 비교합니다. ## 조건이 일치하는 경우, %SearchResult 라는 해쉬에 검색결과에 해당하는 ## $s_i변수를 'key'로, 그리고 해당하는 'idx'번호를 'value'로 저장합니다. ## 이렇게 저장을 해두면, 나중에 검색결과에 일치하는 항목은 해쉬배열에 해당하는 값을 불러오면 됩니다. ## $s_i 변수가 처음엔 '0'이지만, 조건이 일치할때 마다, 하나씩 증가 시킵니다. if (($sr_case eq 1) || ($sr_case eq 3)) { open (FILE, "$DB_idx") || die &error_message("$DB_idx을 열수 없습니다."); @SearchData =; close (FILE); foreach (@SearchData) { ($sidx, $sname, $stitle, $scount, $sdate) = split(/::/, $_); if ($sr_case eq 1) { if ($stitle =~ /$sword/i) { $SearchResult{$s_i} = $sidx; $s_i++; } } elsif ($sr_case eq 3) { if ($sname =~ /$sword/i) { $SearchResult{$s_i} = $sidx; $s_i++; } } } } ## 검색항목이 '본문'일 경우입니다. ## idx 파일을 열고, 인덱스 번호에 맞게, 데이터 파일을 엽니다. ## 데이터 파일에서 본문에 해당하는 데이터에서만 검색작업을 하고, ## 위에서 말씀드린 것처럼, 해당하는 항목이 한 번 나타나면 바로 루프를 빠져 나옵니다. ## 검색결과의 저장방식은 위와 같습니다. else { open (FILE, "$DB_idx") || die &error_message("$DB_idx을 열수 없습니다."); @s_idx = ; close (FILE); foreach(@s_idx) { @s_idx_number = split(/::/, $_); $search_file = "$DB_data_dir/"."board".$s_idx_number[0].".dat"; open (FILE, "$search_file") || die &error_message("$search_file을 열 수 없습니다."); @s_body = ; close (FILE); ($sidx_temp, $sidx) = split(/=/, $s_body[0]); chomp($sidx); for (8..$#s_body) { if ($s_body[$_] =~ /$sword/i) { $SearchResult{$s_i} = $sidx; $s_i++; last; } } } } ## 위의 루프에서 검색결과개수와 조건에 일치하는 데이터가 저장되었습니다. 출력만 하면 됩니다. ## 먼저 머리부분을 출력합니다. 모두 몇개의 검색결과가 있다는 메세지를 보여 줍니다. &search_html($s_i); ## 그리고 가상번호를 정합니다. 그리고 해쉬배열의 0번부터 불러와야 하니깐, ## $s_i변수를 '0'으로 합니다. $s_count_number = $s_i; $s_i = 0; ## 인덱스 파일을 열어서, 해쉬배열에 저장된 인덱스번호와 일치하는 항목을 ## 화면에 뿌려줍니다. 이 일을 맏는건 'build_table()'함수가 맡게 됩니다. ## 가상번호를 하나씩 줄이면서 1이되면, 작업을 마칩니다. open (FILE, "$DB_idx") || die &error_message("$DB_idx을 열 수 없습니다."); @SearchData = ; close (FILE); foreach (@SearchData) { ($sidx, $sname, $stitle, $scount, $sdate) = split(/::/, $_); if ($sidx eq $SearchResult{$s_i}) { &build_table; $s_i++; last if ($s_count_number == '1'); $s_count_number--; } } ## 마지막부분의 HTML을 출력합니다. 이러면 모든 작업이 끝나게 됩니다. &search_bottom; }
build_table()
build_table()
함수는 view_list.cgi에서 각각의 테이블 모냥으로, 데이터를 출력만 하면 됩니다.
search_html()
search_html()
함수는 검색 결과 개수를 받아서 전체 폼의 머리 부분의 출력을 담당합니다. 검색결과가 몇 개이고, 테이블의 번호, 이름 등... 을 출력합니다.
search_bottom()
search_bottom()
함수는 우리가 게시판을 처음 눌렀을 때 나타나는 그 폼 그대로죠. view_list.cgi의 아래 부분 출력과 같습니다.
NOTES
여기까지입니다. 위의 각 함수들을 하나의 프로그램으로 묶는 작업이 여러분이 해야될 일이고, 숙제가 되겠져?(^^;) 여기까지 오셨으면... 충분히 하실 수 있으실 겁니다.
'Common Gateway Interface > Perl' 카테고리의 다른 글
[옛 강좌] 32. Perlprog - BBS 11 (0) | 2015.04.29 |
---|---|
[옛 강좌] 31. Perlprog - BBS 10 (0) | 2015.04.29 |
[옛 강좌] 29. Perlprog - BBS 8 (0) | 2015.04.29 |
[옛 강좌] 28. Perlprog - BBS 7 (0) | 2015.04.29 |
[옛 강좌] 27. Perlprog - BBS 6 (0) | 2015.04.29 |