[MySQL & PHP] 21장 실용적인 게시판 만들기

MySQL & PHP 학습/정리 그리고 체크! 2016. 3. 29. 00:23

728x90
반응형

1. 조금은 실용적인 게시판 만들기

여기에서의 마지막 장에서는 어느 정도 실용적인 게시판을 소개하겠습니다. 어디까지나 MySQL + PHP를 이해하는 것이 목적이긴 하지만, 인트라넷에서 사용하는 게시판용으로는 충분히 활용할 수 있을 것입니다. 지금까지 이 블로그를 통해 배운 모든 지식을 사용해서 이 게시판을 제작해 보겠습니다. 중간중간 주석을 입력해 놓았으니 차근차근 읽어가며 소스 코드의 의미와 역할을 생각해 보기 바랍니다. 앞으로 여러분이 웹 응용프로그램을 만드는 데 필요한 다양한 팁이 포함되어 있습니다.


다음은 '실용 게시판'을 만드는 데 필요한 PHP 스크립트 파일의 구성입니다.


여기서 만드는 게시판은 보통의 웹 사이트 게시판과는 약간 다릅니다. 게시판 메인 화면에는 스레드 라고 불리는 주제별 글들을 모아놓은 목록이 있습니다. 메인 화면의 스레드 목록 중에서 하나의 스레드(주제)를 클릭하면, 해당하는 스레드에는 입력한 순서대로 댓글(메시지)들이 표시됩니다. 지금 만들려는 게시판의 구조를 생각하면서 다음 내용을 살펴보기 바랍니다.




board_top.php

게시판의 메인 화면입니다. 현재 존재하는 스레드 제목과 작성 날짜 및 시간을 표시합니다. 스레드 제목에는 하이퍼링크가 설정되어 있어 클릭하면 해당하는 '스레드별 댓글 목록'으로 이동합니다.


스레드 제목을 입력하여 새로운 스레드를 만들 수도 있습니다. 또한, 메시지를 검색하는 board_search.php에도 하이퍼링크가 설정되어 있습니다.


board.php

스레드별 댓글을 표시합니다. 해당 스레드에 있는 모든 댓글 정보(작성자 이름, 작성 날짜와 시간, 메시지)를 표시합니다. 새롭게 스레드에 댓글을 입력할 수도 있습니다.


board_search.php

키워드를 입력하면 모든 스레드 중에서 해당 키워드를 포함하는 메시지를 검색하여 그 목록을 표시합니다.


메인 화면의 스레드 목록(board_top.php)으로 이동할 수 있는 하이퍼링크가 있습니다.


board_reset.php

데이터를 초기화하기 위한 화면입니다. 이 화면을 호출하면 현재 이용하는 2개의 테이블에 있는 데이터를 삭제하고, 연속 번호 기능을 초기화합니다(AUTO_INCREMENT=0). 링크로 이동할 수 없는 단독 화면으로 실행되도록 만듭니다.


db_info.php

서버 이름과 사용자 이름, 비밀번호, 데이터베이스 이름이 입력된 스크립트 파일입니다. 여기서에서는 비공개 폴더 data에 저장되어 있습니다.


참고로, 여기에서 사용하는 기능은 모두 이 블로그에서 배운 내용입니다.



1.1 실용 게시판에서 사용할 이미지 준비하기

여기에서는 이미지 파일 parent.gif를 사용하고 있습니다. 공유 폴더(여기에서는 c:\xampp\htdocs)에 내려받은 pic 폴더를 복사해 둡니다.


예제 이미지

pic.zip


참고로, 이미지가 없어도 게시판을 실행하는 데에는 아무런 지장이 없습니다. 또한, 자신이 좋아하는 다른 이미지 파일을 사용해도 상관없습니다.



2. 실용 게시판에서 사용할 테이블 만들기

실용 게시판에서 사용할 테이블은 다음과 같은 구조의 tbj0과 tbj1입니다. PHP 스크립트를 작성하기 전에 4장의 내용을 참고로 테이블을 만들어 두기 바랍니다.



2.1 스레드용 테이블 tbj0


테이블 tbj0의 칼럼

칼럼 이름

내용 

 gnum 

 스레드의 그룹 번호를 저장한다. INT형이며, 연속 번호 기능을 설정해서 번호가 자동으로 부여되도록 한다. 

 thread 

 스레드의 제목을 저장한다. 

 date 

 스레드를 작성한 날짜와 시간을 저장한다. MySQL의 NOW()함수를 이용해서 자동으로 입력한다. 자료형은 DATETIME으로 설정한다. 

 ipaddr 

 전달된 클라이언트의 IP주소를 저장한다. 브라우저에는 표시하지 않고 만일을 위해 기록을 저장한다. 자료형은 20ㅜ문자의 문자열인 VARCHAR(20)으로 설정한다. 


테이블 tbj0의 구성

칼럼 이름

gnum 

thread 

date 

ipaddr 

 속성 

 INT

 AUTO_INCREMENT

 PRIMARY KEY 

 VARCHAR(30) 

 DATETIME 

 VARCHAR(20) 


CREATE TABLE tbj0 (gnum INT AUTO_INCREMENT PRIMARY KEY, thread VARCHAR(30), date DATETIME, ipaddr VARCHAR(20));



2.2 메시지용 테이블 tbj1

테이블 tbj1은 모든 스레드에 입력된 내용을 통합해서 저장합니다.


테이블 tbj1의 칼럼

칼럼 이름

내용 

 number 

 모든 스레드의 일련번호를 저장한다. INT형이며, 연속 번호 기능을 설정한다. 

 name 

 작성자의 이름을 저장한다. 자료형은 VARCHAR(30)이다. 

 mess 

 메시지를 저장한다. 자료형은 TEXT이다. 

 date 

 레코드를 추가한 날짜와 시간을 저장한다. 테이블 tbj0과 마찬가지로 MySQL의 NOW()함수로 자동 입력한다. 

 gnum 

 그룹 번호를 저장한다. 테이블 tbj0과 결합(조인)할 때 키로 사용한다. 자료형은 INT이다. 

 ipaddr 

 테이블 tbj0과 마찬가지로 전달된 클라이언트의 IP주소를 저장한다. 


테이블 tbj1의 구성

칼럼 이름

number 

name 

mess 

date 

gnum 

ipaddr 

 속성 

 INT

 AUTO_INCREMENT

 PRIMARY KEY

 VARCHAR(30) 

 TEXT 

 DATETIME 

 INT 

 VARCHAR(20) 


CREATE TABLE tbj1 (number INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(30), mess TEXT, date DATETIME, gnum INT, ipaddr VARCHAR(20));



3. 메인 화면 만들기 - 스레드 생성과 목록 표시

그럼, 메인 화면 board_top.php를 만들어 보겠습니다.


board_top.php에 접속하면 스레드 목록이 표시됩니다. 화면 아래쪽의 텍스트 상자에 새로운 스레드 제목을 입력하고 <확인> 단추를 누르면 자기 자신(board_top.php)을 호출해서 스레드를 작성합니다.


또한, 아래쪽의 링크를 클릭하면 검색 화면인 board_search.php로 이동합니다. 참고로, /* ... */은 주석 부분이기 때문에 입력하지 않아도 상관없습니다.


3.1 board_top.php의 내용


예제 21-1 board_top.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?php 
    /* 데이터베이스 정보 등을 읽어온다. */
    require_once("data/db_info.php");
 
    /* 데이터베이스 접속과 데이터베이스 선택 */
    $s = mysql_connect($SERV$USER$PASS) or die("실패입니다.");
    mysql_select_db($DBNM);
 
    /* 타이틀과 화면 표시 */
print <<<eot1
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>SQL 블로그 화면</title>
</head>
<body bgcolor='lightsteelblue'>
    <img src='pic/parent.gif'>
    <font size='7' color='indigo'>SQL 블로그 게시판입니다~</font>
    <br><br>
    확인하고자 하는 스레드 번호를 누르세요.
    <hr>
    <font size='5'>(스레드 목록)</font>
    <br>
eot1;
 
    /* 클라이언트의 IP 주소 가져오기 */
    $ip = getenv("REMOTE_ADDR");
 
    /* 스레드 제목(th)에 데이터가 있으면 테이블 tbj0에 대입 */
    $th_d = isset($_GET["th"])? htmlspecialchars($_GET["th"]):null;
    if ($th_d<>"") {
        mysql_query("INSERT INTO tbj0 (thread, date, ipaddr) VALUES('$th_d', now(), '$ip')");
    }
 
    /* tbj0의 모든 데이터 추출 */
    $re = mysql_query("SELECT * FROM tbj0");
    while ($result = mysql_fetch_array($re)) {
print <<<eot2
    <a href="board.php?gn=$result[0]">$result[0$result[1]</a>
    <br>
    $result[2]작성
    <br><br>
eot2;
    }
 
    /* 데이터베이스 접속 종료 */
    mysql_close($s);
 
/* 스레드 제목 입력과 메인 화면으로 이동하는 링크 등 */
print <<<eot3
    <hr>
    <font size="5">스레드 작성</font>
    <br>
    여기에 새로운 스레드를 작성합니다!
    <br>
    <form method="get" action="board_top.php">
        새로 작성할 스레드의 제목
        <input type="text" name="th" size="50">
        <br>
        <input type="submit" value="확인">
    </form>
    <hr>
    <font size="5">메시지 검색</font>
    <a href="board_search.php">검색을 하려면 여기를 누르세요</a>
    <hr>
eot3;
 ?>
cs


문자 코드 설정하기 14번 라인

화면의 문자 코드를 설정할 때에는 <meta> 태그를 사용합니다. 여기에서는 UTF-8을 설정하고 있습니다.


<meta charset="UTF-8">


이미지 추가하기 18번 라인

<img> 태그에는 이미지를 설정합니다. src속성에 이미지 파일의 위치를 입력합니다. 여기에서는 pic폴더에 있는 parent.gif파일을 표시하겠습니다. 이미지 파일을 표시하려면 사전에 pic폴더에 이미지 파일을 복사해 두어야 합니다.


이미지 파일이 제대로 복사되었다면 브라우저에 http://localhost/pic/parent.gif라고 입력해서 다음과 같이 이미지가 표시되는지 확인합니다.


<img src='pic/parent.gif'>




스레드 제목 저장하기 31번 라인

name="th"라고 설정한 텍스트 상자(57~62 라인)에는 새로운 스레드의 제목을 입력합니다. 이 form의 <확인> 단추를 누르면 get방식으로 board_top.php에 데이터가 전송됩니다. 이때, 새로운 스레드 제목에 입력된 문자열을 $_GET["th"]로 가져와서 변수 $th_d에 대입합니다. 부정한 입력을 방지하기 위해 htmlspecialchars() 함수를 사용해서 태그가 입력되면 무효로 합니다.


isset()은 변수에 값이 들어 있는지를 확인하는 함수입니다. 변수에 값이 대입되어 있으면 TRUE를 반환합니다. 데이터가 전송되었다면 $_GET["th"]에는 변수가 설정되어 있을 것입니다. 이 부분은 $_GET["th"]에 값이 설정되어 있다면 자기 자신(board_top.php)에게 전송한 것으로 간주해서 thmlspecialchars($_GET["th"])의 값을 변수 $th_d에 대입하고, 값이 설정되어 있지 않다면 전송이 없는 것으로 간주해서 변수 $th_d에는 null이 대입됩니다. 즉, 다음과 같은 처리가 이루어 집니다.


if isset($_GET["th"]){

$th_d = htmlspecialchars($_GET["th"]);

}else{

$th_d = null;

}


이러한 내용을 간략하게 기술하면 다음과 같습니다. 물음표(?)와 쌍점(:)의 사용법에 주의합니다.


$th_d = isset($_GET["th"])? htmlspecialchars($_GET["th"]):null;


스레드에 링크 표시하기 40번 라인

href 속성을 이용해서 board.php의 링크에 ?gn = $result[0]을 추가로 작성합니다. 이렇게 하면 GET 메서드를 이용하여 그룹 번호를 전송할 수 있습니다.


$result[0]은 SELECT * FROM tbj0의 실행결과 중, 1번째 칼럼인 gnum(스레드의 그룹 번호)값이고, $result[1]은 2번째 칼럼인 thread(스레드 제목)의 값입니다.


<a href="board.php?gn=$result[0]">$result[0] $result[1]</a>에 의해 $result[0](그룹 번호)과 $result[1](스레드 제목)이 표시됩니다. 이렇게 그룹 번호에 스레드 제목을 붙인 문자열에 board.php의 링크가 설정됩니다.


예를 들어, 그룹 번호가 3인 스레드에 접속할 때에는 주소창에 http://localhost/board.php?gn=3이라고 표시됩니다.


다음은 스레드의 목록을 출력하는 부분입니다.




새로운 스레드 작성하기 57~62번 라인

이 form은 스크립트 board_top.php 자체를 호출해서(재귀적으로) 데이터를 전송하는 부분입니다. name='th'의 텍스트 상자에 새롭게 작성할 스레드의 제목을 입력하고 <확인> 단추(type="submit")를 누르면, board_top.php에 GET 방식으로 데이터를 전송합니다. 전송된 데이터는 31번 라인의 $_GET["th"]에 저장됩니다.


<form method="get" action="board_top.php">


검색 실행하기 65번 라인

<a href="board_search.php">검색을 하려면 여기를 누르세요.</a>는 검색 기능이 있는 PHP 스크립트 board_search.php에 링크됩니다.



3.2 board_top.php의 구조

board_top.php의 구조를 다시 한번 살펴보겠습니다. 어느 스크립트가 어떤 역할을 하는지 확인해 보겠습니다.



4. 스레드별 화면 만들기 - 댓글 입력과 목록 표시

스레드별로 메시지를 표시하는 화면 board.php를 작성합니다.


이 화면에 접속하면 해당 스레드의 메시지가 표시됩니다. 화면 아래쪽의 텍스트 상자에 이름과 메시지를 입력하고 단추를 누르면 자기 자신(board.php)을 호출해서 새로운 메시지를 작성할 수 있습니다.


또한, 아래쪽의 링크를 클릭하면, 스레드 목록을 표시하는 스크립트 board_top.php로 이동할 수 있습니다.



4.1 board.php의 내용


예제 21-2 board.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<?php 
    /* 데이터베이스 정보 등을 읽어온다. */
    require_once("data/db_info.php");
 
    /* 데이터베이스 접속과 데이터베이스 선택 */
    $s = mysql_connect($SERV$USER$PASS) or die("실패입니다.");
    mysql_select_db($DBNM);
 
    /* 스레드의 그룹 번호(gn)를 가져와서 $gn_d에 대입 */
    $gn_d = $_GET["gn"];
 
    /* $gn_d에 숫자 이외의 값이 포함되어 있으면 처리 중단 */
    if (preg_match("/[^0-9]/"$gn_d)) {
print <<<eot1
    부정한 값이 입력되었습니다.<br>
    <a href="board_top.php">스레드 목록으로 돌아가려면 여기를 누르세요.</a>
eot1;
    
    /* $gn_d에 숫자만 포함되어 있으면 정상 처리 */
    } elseif (preg_match("/[0-9]/"$gn_d)) {
 
        /* 이름과 메시지를 가져오고 태그는 삭제 */
        $na_d = isset($_GET["na"])? htmlspecialchars($_GET["na"]):null;
        $me_d = isset($_GET["me"])? htmlspecialchars($_GET["me"]):null;
 
        /* IP 주소 가져오기 */
        $ip = getenv("REMOTE_ADDR");
 
        /* 스레드의 그룹 번호(gn)와 일치하는 레코드를 표시한다. */
        mysql_query("INSERT INTO tbj1 VALUES(0,'$na_d','$me_d',now(),$gn_d,'$ip')");
        $result = mysql_fetch_array($re);
 
        /* 스레드의 댓글을 표시하는 문자열 $thread_com을 작성한다. */
        $thread_com = "┌".$gn_d." ".$result[0]."┘";
 
        /* 스레드를 표시하는 제목 등을 출력한다. */
print <<<eot2
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>SQL 블로그 $thread_com 스레드</title>
</head>
<body bgcolor='darkgray'>
    <font size='7' color='indigo'>$thread_com 스레드!</font>
    <br><br>
    확인하고자 하는 스레드 번호를 누르세요.
    <font size='5'>$thread_com 의 메시지</font>
    <br>
eot2;
 
        /* 이름($na_d)이 입력되면 tbj1에 레코드를 추가한다. */
        if ($na_d<>"") {
            mysql_query("INSERT INTO tbj1 VALUES(0, '$na_d', $'$me_d', now(), $gn_d, '$ip'");
        }
 
        /* 수평선 표시 */
        print "<hr>";
 
        /* 날짜와 시간순으로 댓글(메시지)을 표시 */
        $re = mysql_query("SELECT * FROM tbj1 WHERE gnum=$gn_d ORDER BY date");
 
        $i = 1;
        while ($result = mysql_fetch_array($re)) {
            print "$i($result[0]): <u>$result[1]</u>: $result[3] <br>";
            print nl2br($result[2]);
            print "<br><br>";
            $i++;
        }
 
        /* 데이터베이스 접속 종료 */
        mysql_close($s);
 
print <<<eot3
    <hr>
    <font size="5">$thread_com 에 메시지를 작성하세요.</font>
    <form method="get" action="board.php">
        이름 <input type="text" name="na"><br>
        메시지<br>
        <textarea name="me" rows="10" cols="70"></textarea>
        <br>
        <input type="hidden" name="gn" value=$gn_d>
        <input type="submit" value="확인">
    </form>
    <hr>
    <a href="board_top.php">스레드 목록으로</a>
    </body>
</html>
eot3;
 
    /* $gn_d에 숫자 이외의 문자가 있거나 숫자가 포함되어 있지 않을 때 처리 */
    } else {
        print "스레드를 선택하세요.<br>";
        print "<a href='board_top.php'>스레드 목록으로 돌아가려면 여기를 누르세요.</a>";
    }
 ?>
cs


그룹 번호와 이름, 메시지 가져오기 10, 23, 24번 라인

메인 화면 board_top.php에서 이 화면으로 이동했을 때에는 gn이, 이 화면(board.php)에서 이동했을 때에는 gn과 na, me라는 데이터를 식별하는 이름이 GET 전송됩니다. 이렇게 전송된 데이터는 $gn_d = $GET["gn"];에 전달되어 변수 $gn_d에 대입됩니다. 참고로, 데이터를 식별하는 이름인 gn과 na, me로 전송된 정보는 테이블 tbj1의 칼럼 gnum과 name, mess에 저장되는 데이터 입니다. 이름(na)과 메시지(me)는 부정 입력을 막고자 htmlspecialchars() 함수를 이용해서 태그를 무효로 하고 있습니다. 그리고 자기 자신(board.php)으로부터 데이터가 전송되지 않은 때에는 $_GET["na"]와 $_GET["me]에는 변수가 설정되지 않습니다. 여기에서는 isset() 함수를 사용해서 변수가 설정되어 있으면 board.php에서 데이터가 전송된 것으로 간주하고, htmlspecialchars($_GET["na"])의 값을 변수 $na_d에, htmlspecialchars($_GET["me"])의 값을 변수 $me_d에 대입합니다. 변수가 설정되어 있지 않으면 데이터가 전송되지 않은 것으로 보고 null을 대입합니다.


$gn_d = $_GET["gn"];

$na_d = isset($_GET["na"])? htmlspecialchars($_GET["na"]):null;

$me_d = isset($_GET["me"])? htmlspecialchars($_GET["me"]):null;



SELECT 문 실행하기 30번 라인

$gn_d는 스레드의 그룹 번호입니다. 전달된 그룹 번호와 일치하는 번호를 테이블 tbj0에서 검색하여, 스레드 제목(칼럼 thread)을 표시하는 SQL 문을 실행합니다.


$re = mysql_query("SELECT thread FROM tbj0 WHERE gnum=$gn_d"); 



그룹 번호와 스레드 제목 가져오기 34번 라인

$gn_d는 그룹 번호, $result[0] 은 칼럼 thread의 스레드 제목입니다. 이 두 문자를 온점(.)으로 결합한 문자열이 $thread_com입니다.


$thread_com = "┌".$gn_d." ".$result[0]."┘";



문자 코드 설정하기 41번 라인

문자 코드를 설정할 때에는 <meta> 태그를 사용합니다. 여기에서는 UTF-8을 설정합니다.


<meta charset="UTF-8">



INSERT 문 실행하기 54번 라인

테이블 tbj의 칼럼 number와 name, mess, date, gnum, ipaddr에 각각 0, 이름($na_d), 메시지($me_d), 현재 날짜와 시간 (now()), 그룹 번호($gn_d), IP 주소($ip)를 저장합니다. AUTO_INCREMENT가 설정된 number에는 0을 입력하면 연속 번호가 자동으로 입력됩니다.


mysql_query("INSERT INTO tbj1 VALUES(0,'$na_d','$me_d',now(),$gn_d,'$ip')");



메시지 표시하기 66번 라인

$result[2]는 텍스트 영역에 입력된 메시지의 내용입니다. 이 문자열에 줄바꿈이 포함되어 있을 때, 실제 화면에도 줄바꿈이 반영되도록 하는 것이 nl2br() 함수입니다.


print nl2br($result[2]);



텍스트 영역 배치하기 80번 라인

<textarea> ~ </texxtarea>는 텍스트 영역에 입력된 메시지의 내용입니다. 속성 name에는 데이터를 식별하는 이름을, rows에는 행수, cols에는 한 행에 입력되는 문자 수를 설정합니다. 텍스트 영역 안에 입력된 줄바꿈에는 nl2br() 함수를 사용해서 줄바꿈 태그를 입력하도록 합니다.


<textarea name="me" rows="10" cols="70"></textarea>



그룹 번호 전송하기 82번 라인

type속성에 'hidden'을 설정하면 브라우저에는 아무것도 표시되지 않지만, value속성에 설정된 값이 전송됩니다. 이 예에서는 gn이라는 데이터를 식별하는 이름으로, $gn_d의 값(그룹 번호)이 자동으로 전송됩니다.


<input type="hidden" name="gn" value=$gn_d>



5. 메시지 검색 화면 만들기

이번에는 모든 스레드의 메시지 중에 포함된 키워드를 검색하는 화면 board_search.php입니다. 텍스트 상자에 키워드를 입력하고, 단추를 누르면 자기 자신(board_search.php)을 호출해서 검색을 실행하고 결과 레코드를 표시합니다.


또한, 아래쪽의 링크를 클릭하면 스레드 목록을 표시하는 스크립트 board_top.php로 이동합니다.


5.1 board_search.php의 내용


예제 21-3 board_search.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php 
    /* 데이터베이스 등의 정보 읽어오기 */
    require_once("data/db_info.php");
 
    /* 데이터베이스 접속과 데이터베이스 선택 */
    $s = mysql_connect($SERV$USER$PASS) or die("실패입니다.");
    mysql_select_db($DBNM);
 
    /* 타이틀 등 표시 */
print <<<eot1
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>SQL 블로그 검색 화면</title>
</head>
<body bgcolor='orange'>
    <hr>
    <font size="5">(검색 결과는 여기에)</font>
    <br>
eot1;
 
    /* 검색 문자열을 가져와서 태그 삭제 */
    $se_d = isset($_GET["se"])? htmlspecialchars($_GET["se"]): null;
 
    /* 검색 문자열($se_d)에 데이터가 있으면 검색 처리 */
    if ($se_d<>"") {
 
/* 검색 SQL 문. 테이블 tbj1에 tbj0을 결합(조인) */
$str=<<<eot2
    SELECT tbj1.number, tbj1.name, tbj1.mess, tbj0.thread FROM tbj1 JOIN tbj0 ON tbj1.gnum=tbj0.gnum WHERE tbj1.mess LIKE "%$se_d%"
eot2;
 
        /* 검색 질의 실행 */
        $re = mysql_query($str);
        while ($result = mysql_fetch_array($re)) {
            print " $result[0] : $result[1] : $result[2] ( $result[3] )";
            print "<br><br>";
        }
    }
 
    /* 데이터베이스 접속 종료 */
    mysql_close($s);
 
/* 검색 문자열 입력란, 메인 화면에 링크 */
print <<<eot3
    <hr>
    메시지에 포함되는 문자를 입력하세요!
    <br>
    <form method="get" action="board_search.php">
        검색할 문자열
        <input type="text" name="se">
        <br>
        <input type="submit" value="검색">
    </form>
    <br>
    <a href="board_top.php">스레드 목록으로 돌아가기</a>
</body>
</html>
eot3;
 ?>
cs



문자 코드 설정하기 14번 라인

문자 코드를 설정할 때에는 <meta> 태그를 사용합니다. 여기에서는 UTF-8을 설정합니다.


<meta charset="UTF-8">



검색 키워드 대입하기 24번 라인

데이터를 식별하는 이름인 se로 전송된 검색 키워드를 전달받아 변수 $se_d에 대입합니다.


$se_d = isset($_GET["se"])? htmlspecialchars($_GET["se"]): null;



SELECT 문 실행하기 31번 라인

테이블 tbj1과 tbj0을 결합해서 일련번호와 이름, 메시지, 스레드 제목을 검색합니다. 결합에 이용되는 키는 그룹 번호 gnum입니다. 변수 $se_d는 검색 키워드로서 앞뒤에 %를 설정하면 이 키워드를 포함한 모든 메시지를 검색합니다.


SELECT tbj1.number, tbj1.name, tbj1.mess, tbj0.thread FROM tbj1 JOIN tbj0 ON tbj1.gnum=tbj0.gnum WHERE tbj1.mess LIKE "%$se_d%"



6. 데이터베이스 정보를 저장하는 파일 만들기

서버 이름과 사용자 이름, 비밀번호, 데이터베이스 이름이 입력된 파일 db_info.php를 만들어 보겠습니다. 자신이 사용하는 환경에 맞춰 적당하게 데이터를 변경합니다. 여기에서는 비공개 폴더인 data에 저장하겠습니다.


21-4 db_info.php

1
2
3
4
5
6
<?php 
    $SERV = "localhost";
    $USER = "root";
    $PASS = "1234";
    $DBNM = "db1";
 ?>
cs


저는 윈도우 의 경우엔 htdocs폴더의 하위 폴더로 생성하여 만들었고 OS X의 경우엔 Applications폴더의 하위 경로로 만들었습니다.



7. 데이터 초기화용 화면 만들기

데이터를 초기화하는 구조도 만들어 보겠습니다. 다음 스크립트는 테이블 tbj0과 tbj1의 모든 레코드를 삭제하고, AUTO_INCREMENT를 초기화하는 내용입니다.


7.1 board_reset.php의 내용


예제 21-5 board_reset.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php 
    require_once("data/db_info.php");
    $s = mysql_connect($SERV,$USER,$PASS) or die("실패입니다.");
 
    mysql_select_db($DBNM);
 
    mysql_query("DELETE FROM tbj0");
    mysql_query("DELETE FROM tbj1");
    mysql_query("ALTER TABLE tbj0 AUTO_INCREMENT=0");
    mysql_query("ALTER TABLE tbj1 AUTO_INCREMENT=0");
 
    print "SQL 블로그의 테이블을 초기화했습니다.";
 
    mysql_close($s);
 ?>
cs




정리

1. 실용 게시판의 구성

2. 스레드를 처리하는 기능

3. 댓글을 처리하는 기능

4. 실용 게시판에서 할 수 있는 최소한의 보안 대책


체크!

★ board_top.php를 중심으로 작성한 게시판의 구조를 이해하고 있다.

★ board_top.php의 처리 과정을 이해하고 있다.

★ board.php의 처리 과정을 이해하고 있다.

★ board_search.php의 처리 과정을 이해하고 있다.

★ 테이블 tbj0과 tbj1을 초기화 하는 방법을 이해하고 있다.

반응형