[강좌] php+mysql 게시판 만들기 #쉬-1
안녕하세요. 디망쉬입니다.
이제 기반 위주의 이론은 끝나고 실습 위주의 이론이 나오는군요. ^^
자 그런 의미에서 힘내서 이얍!
아참. 2000년 7월 4일자로 '쉬'편이 모두 다시 올라왔습니다. 그 이전에 갈무리 하신 분은 새로 갈무리하세요.
------------------------------------------------------------------------------------------------ '쉬'편은 모든 편이 서로 약간씩 관련이 되어 있으므로 모두를 한꺼번에 받으셔서 이 편 저 편 이동하시며 같이 읽는것이 좋습니다.^^;
이유가 각 부분마다 사용하는 변수가 많기 때문에 하나 하나 보시면 이 변수가 뭐에 쓰이는건지 헷갈릴 수 있거든요. 그래서 '쉬-짠1'편에서는 각 부분마다 사용되는 변수를 설명해놓고 있지만, 역시나 더 좋은 방법은 다른 편들을 이동하시며 보는 것입니다. :) '쉬'편의 짠들은 다음과 같으니 별도로 준비하셔서 참조하세요. ^^;
쉬-짠1 : 게시판 만들면서 사용되는 변수 정리 문서 쉬-짠2 : 게시판 만드는데 필요한 약간의 html tag 쉬-짠3 : 게시판 만들면서 만든 사용자 정의 함수 쉬-짠4 : 게시판 만드는데 사용된 php 함수 정리 쉬-짠5 : 게시판 만들면서 필요한 SQL 명령어 정리 ------------------------------------------------------------------------------------------------
쉬. 기능 붙이기
a. 글 입력 하기 이전 강좌에서 우린 게시판을 기능 별로 파일 단위로 자른다고 했었습니다. :) 그런데 게시물 입력 폼은 fill.php3 였죠. 이제 fill.php3 를 클릭하면 글 쓰기 입력 폼이 나옵니다.
일단 글 쓰기 입력 폼을 디자인 해볼까요?
<html>
<head> <title>글 입력</title> </head>
<body> 글쓰기 폼 <p> <form method="post" action="run.php3" enctype="multipart/form-data"> 작성자명 : <input type="text" name="fil[name]"><br>
작성자email : <input type="text" name="fil[email]"><br>
작성자homepage : <input type="text" name="fil[homepage]"><br>
비밀번호 : <input type="password" name="fil[pw]"><br>
제목 : <input type="text" name="fil[title]"><p>
<textarea name="fil[text]" cols="36" rows="10"></textarea><p>
<input type="submit" value="저장하자"> <input type="reset" value="재작성"> </form> </body>
</html>
|
무할할. 무척 간단하군요. 일단은 작동 되게하는 것이 중요하니 디자인은 생략핟록 하죠. ^^;
혹시 html tag 잘 모르시는 분이 계실수도 있겠죠? 그 분들은 '쉬-짠2' 편을 참조하세요. 게시판 짤 때, 특히 form 관련 tag 에 대해 다루고 있어요.
그런데 몇 가지 정보가 부족합니다.
몇 번 강좌에서 적었듯이 우리는 기능별로 게시판을 여러 파일로 나눴습니다. 글 쓰기는 fill.php3 , 게시물 읽기는 view.php3, 게시물 처리는 run.php3 등으로요.
그런데 글 쓰기 폼에서 입력된 데이터들을 어디로 넘겨주죠? 네~ <form> tag 에 action 으로 지정되어 있듯이 run.php3 로 넘겨집니다. 그런데 게시물 입력만 run.php3 이 처리하지 않습니다. 게시물 수정도 처리하겠고 삭제도 하겠죠. 때문에 run.php3 이 어떻게 처리해줘야 할 지 지정해줄 필요가 있습니다.
그것을 위해 우리는 $mode 라는 변수를 사용할 것입니다. run.php3 이 넘어온 명령을 처리할 때 $mode 변수에 어떤 값이 들어있냐에 따라 데이터를 처리하는거죠. 그럼 이 $mode 변수는 어디서 선언 해주느냐. 바로 명령을 내리기 전의 파일이겠죠. 게시물 입력이라면 fill.php3 에서 선언해주고, 수정이라면 edit.php3 에서 선언해주죠.
으흠. 게시물 입력할 때 $mode 변수에 어떤 값을 넣어줘야 알아보기 좋을까요? 일반적으로 쓰이는 단어를 쓰죠 뭐. write.
이로서 run.php3 는 $mode 변수의 값이 write 일 경우 '아~! 게시물 입력하라는거군'으로 이해하고 처리하겠죠.
그런데 $mode 변수를 각 부분의 파일에 선언하라는 말만 했지 구체적으로 어떻게 해줘야할지 안썼죠? html 소스부터 볼까요?
<html>
<head> <title>글 입력</title> </head>
<body> 글쓰기 폼 <p> <form method="post" action="run.php3" enctype="multipart/form-data"> <input type="hidden" name="mode" value="write"> 작성자명 : <input type="text" name="fil[name]"><br>
작성자email : <input type="text" name="fil[email]"><br>
작성자homepage : <input type="text" name="fil[homepage]"><br>
비밀번호 : <input type="password" name="fil[pw]"><br>
제목 : <input type="text" name="fil[title]"><p>
<textarea name="fil[text]" cols="36" rows="10"></textarea><p>
<input type="submit" value="저장하자"> <input type="reset" value="재작성"> </form> </body>
</html> |
어느 부분에 한 줄 추가되었습니다. 예이. 바로 <form> tag 와 작성자명 : 사이에
<input type="hidden" name="mode" value="write"> |
가 추가되었습니다. <input> tag 에서 name 옵션을 통해 mode 라는 변수명을 지정하고 value 옵션을 통해 mode 변수에 들어갈 내용이 write 라는 걸 선언했습니다. 그리고 이걸 이용자가 고치지 못하게 <input> 를 화면에 안보이게 hidden 타입으로 했구요.
자. 일단 글 입력때 필요한 기본적인 정보는 위와 같습니다. 그런데 우리는
" 게시판 cgi 하나 " = " 게시판 하나 "
라는 단순한 방식이 아닙니다. :) 게시판 cgi 하나로 여러 개의 게시판으로 이용이 가능해야하죠.
그러기 위해서는 위의 정보로 부족합니다. 무엇이 더 필요할까요?
이것을 맞추기 위해서는 '망-2'편을 살짝 상기하시면 됩니다. 뭐냐구요? 이전에 제가 DB 에서 테이블 하나는 게시판 하나라고 언급했었죠? 네. 바로 그겁니다.
글을 처리할 때 글이 처리될 테이블명을 run.php3 에게 알려주고 run.php3 는 통보받은 테이블명을 참조하여 해당 테이블에서 글을 처리하면 되겠죠.
그럼 어떻게 알려주죠? ^^; 역시 간단하죠? <input> tag 를 이용하면 됩니다. 글을 어떻게 처리할 것인지 선택해준 방식과 동일한 방법입니다.
<input type="hidden" name="board" value="test"> |
이거 보면 이제 아시겠죠? 네. $board 라는 변수를 통해 run.php3 는 어떠한 테이블에서 작업할 것인지 알 수 있죠. $board 변수에는 처리할 테이블명이 들어가있으면 되구요.
그런데 문제가 하나 있습니다. 만약 위와 같이 value 값을 test 로 해버리면 아무리 다중 게시판 이라고 해도 항상 test 게시판만 글이 입력되고 수정되고 삭제되는 등의 작업이 있을 겁니다. 그래서 약간의 수정이 필요합니다.
어떻게 하면 fill.php3 파일이 어떤 게시판(테이블) 에서건 작동될 수 있게 할 수 있을까요? 어떻게 해야
<input type="hidden" name="board" value="test"> |
에서 value 값을 사용자가 사용 중인 게시판 이름으로 알아서 바뀔 수 있을까요?
방법은 여럿이 있겠지만 가장 대중적인 방법은 fill.php3 파일이 읽혀올 때 아예 해당 테이블명을 알려주면 되겠죠? 방법은 간단합니다. fill.php3 가 실행될 때 get 방식(form tag 에서 post 방법 중 get 입니다)으로 게시판명을 함께 선언하면 되죠. 바로 요렇게.
쉽게 말하자면 웹 브라우저의 주소창에 board=게시판명 을 추가하면 된다는 거죠. 그런 뒤
<input type="hidden" name="board" value="test"> |
에서 value 부분에 들어갈 내용을 fill.php3?board=test 처럼 딸려온 board 라는 폼 변수의 값을 출력해주면 될 것입니다. 이렇게요.
<input type="hidden" name="board" value="<? echo "$board"; ?>"> |
echo 함수가 뭘까요? 간단히 말씀드리자면 출력 함수랍니다. php 명령을 쓰려면 html 문서 안에 <? 로 열고 ?> 로 닫아줘야하기 때문에 <? 를 열었고 echo 함수로 $board 변수의 내용을 출력시키는거죠. 물론 $board 변수의 내용이 출력될 위치가
<input type="hidden" name="board" value="test"> |
에서 value 부분이기 때문에 value=" 와 " 사이에 <? echo "$board"; ?> 가 들어간 거랍니다.
그런데 왜 하필 $board 냐구요? 말씀드렸잖아여 ^^; fill.php3?board=test 식으로 값이 넘어오기 때문이라고.
그럼 html 소스는 이렇게 되겠군요.
<html>
<head> <title>글 입력</title> </head>
<body> 글쓰기 폼 <p> <form method="post" action="run.php3" enctype="multipart/form-data"> <input type="hidden" name="board" value="<? echo "$board"; ?>"> <input type="hidden" name="mode" value="write"> 작성자명 : <input type="text" name="fil[name]"><br>
작성자email : <input type="text" name="fil[email]"><br>
작성자homepage : <input type="text" name="fil[homepage]"><br>
비밀번호 : <input type="password" name="fil[pw]"><br>
제목 : <input type="text" name="fil[title]"><p>
<textarea name="fil[text]" cols="36" rows="10"></textarea><p>
<input type="submit" value="저장하자"> <input type="reset" value="재작성"> </form> </body>
</html> |
물론 위처럼 안하고 좀 더 확장성있고 차후 관리가 편하게(?) 우리는 다음과 같이 소스를 최종 정리하겠습니다. 아래에서 <? 에서 ?> 부분까지가 fill.php3 의 내용입니다.
<? /*-------------------------- filename : fill.php3 --------------------------*/
echo (" // 전체 화면 출력
<html>
<head> <title>글 입력</title> </head>
<body>
글쓰기 폼 <p> <form method="post" action="run.php3" enctype="multipart/form-data"> <input type="hidden" name="board" value="$board"> <input type="hidden" name="mode" value="write"> 작성자명 : <input type="text" name="fil[name]"><br>
작성자email : <input type="text" name="fil[email]"><br>
작성자homepage : <input type="text" name="fil[homepage]"><br>
비밀번호 : <input type="password" name="fil[pw]"><br>
제목 : <input type="text" name="fil[title]"><p>
<textarea name="fil[text]" cols="36" rows="10"></textarea><p>
<input type="submit" value="저장하자"> <input type="reset" value="재작성"> </form> </body>
</html> "); // 전체 화면 출력 완료 ?> |
짠! 드디어 글 입력폼 설명이 끝났습니다! -_-; 이제 입력받아 넘어오는 데이터를 MySQL 서버에 저장시키는 걸 짜볼까요? 여지껏 해왔던 것처럼 초 간단 소스부터 보고 분석해보겠습니다. ^^;
<? /*-------------------------- filename : run.php3 --------------------------*/ $connect = mysql_connect("localhost","아이디","비번"); mysql_select_db("사용DB명",$connect);
if ($mode == "write") { $result = mysql_query(" SELECT MAX(num) AS num, MAX(idx) AS idx, MAX(no) AS no FROM $board", $connect);
$ist[num] = mysql_result($result, 0, "num"); $ist[num] += 1; $ist[idx] = mysql_result($result, 0, "idx"); $ist[idx] += 1;
mysql_free_result($result);
$intime = time(); $passwd = crypt($fil[pw]);
$result = mysql_query("INSERT INTO $board VALUES('', $ist[num], $ist[idx], '$fil[title]', '$fil[text]', 0, 0, 0, 0, 0, '', '', 0, '$fil[name]', '$passwd', '$fil[email]', '$fil[homepage]', $intime)", $connect); } ?> |
매우 간단하군요. 저 위에서 썼지만 run.php3 가 작동될 방식을 지정하는 역할을 $mode 라는 변수가 담당합니다. 그런데 $mode 변수에 write 가 들어가 있으면 run.php3 은 글 입력을 시키라는 명령으로 이해하죠. 그걸 해주기 위해서
를 쓴 것입니다.
if 문에 대해서 알고 싶으시다구요? 그렇다면 쉬-짠4 편을 참조하세요. :]
그런 뒤 mysql_query 함수를 이용하여 쿼리, 즉 명령어를 mysql 서버로 보낸 뒤 결과 데이터를 $result 가 갖습니다.
자. 그렇다면 mysql query 문을 한 번 볼까요?
SELECT MAX(num) AS num, MAX(idx) AS idx, MAX(no) AS no FROM $board", $connect); |
일단 SELECT 문이 뭔지는 '쉬-짠5'를 참조하시면 됩니다. 그런데 거기에는 SELECT 문에서 MAX 에 대해서 안나왔지요.
MAX() 같은 것을 컬럼 함수라고 한답니다. MAX() 는 지정한 컬럼의 가장 큰 값을 찾아서 가져오죠.
만약 hohe 라는 컬럼(attribute)에 값이 70개가 있고 가장 큰 값이 75이 있다고 하죠. (즉 숫자 중간 중간이 비었다는 의미입니다). 이럴 경우
SELECT MAX(hohe) FROM test; |
라고 하면 75 가 나옵니다. 그런데 attribute 명이 hohe 가 아닌 MAX(hohe) 식으로 나온답니다. 문제겠죠? 그래서 AS 문을 써서 MAX(hohe) 는 hohe 라고 해준겁니다.
이렇게요. 그래서
SELECT MAX(num) AS num, MAX(idx) AS idx, MAX(no) AS no FROM $board", $connect); |
에서 MAX(num) AS num 식으로 된 거랍니다. 쉽죠?
그런데 의문. 왜 게시판 테이블에서 num 과 idx attribute(컬럼)에서 가장 큰 값을 가져왔을까요? 간단하죠? 글을 입력할 때 가장 큰 번호에서 1을 더한 숫자가 새로운 글의 num 과 idx 이어야 하기 때문이죠. 그렇다면 글 번호와 관련있는 no attribute(컬럼)의 가장 큰 값은 왜 안가져 왔을까요? 그건 이미 설명했죠? 테이블 생성할 때 no 컬럼은 auto_increment 를 통해 값 증가때마다 자동으로 값이 추가되게 했기 때문입니다.
이렇게 해서 나온 값이 $result 에 저장되겠죠. 그리고 이걸 사용할 수 있게 mysql_result() 문을 이용하여 데이터를 구합니다. 그런 뒤 구한 데이터에서 1 을 더합니다. 왜? 새로 입력되는 글의 num 과 idx 느 이전 글보다 1씩 커야하니까요. 그것이 바로
$ist[num] = mysql_result($result, 0, "num"); $ist[num] += 1; $ist[idx] = mysql_result($result, 0, "idx"); $ist[idx] += 1; |
이 부분이죠. mysql_result 함수는 역시나 '쉬-짠4'를 참조하시구요. :]
이때 주의해야할 점이 있습니다. mysql_query 를 실행시킨 뒤 결과값이 반환되죠? 보통 프로그래밍 언어에서는 리턴(return) 된다고 합니다. 그런데 mysql_query 는 어떤 명령을 내렸느냐에 따라 리턴되는 형태가 다릅니다.
mysql_query 에서 INSERT 문이나 UPDATE 문을 넣으면 리턴되는 값은 1 아니면 0 입니다. 왜냐하면 해당 쿼리가 성공적으로 이뤄졌는지만 알면 되거든요. 하지만 SELECT 문은 다릅니다. SELECT 문은 성공적으로 이뤄지면 성공적으로 이뤄진 결과값이 리턴됩니다. 만약 리턴되는 값이 $result 에 들어가게 했다면 $result 변수는 어떤 명령어를 쿼리로 날려줬냐에 따라 저장된 값이 달라지지요.
그래서 리턴된 값, 즉 여기서는 $result 변수의 값을 시스템으로(?) 반환시켜줄 필요가 있습니다. 안그러면 어떤 부작용이 일어날지 모르죠. 그걸 해주는 함수가 바로 mysql_free_result() 입니다.
mysql_free_result($result); |
바로 이거. 함수 이름에서 눈치챌 수 있겠죠? result 를 자유롭게 하라! ^^;
이제 글 입력 시간을 저장시켜볼까요?
이거에요. time 함수죠.
사용자가 입력한 비밀 번호 자체를 암호화할 필요가 있습니다. 보안상요. 이때 암호화해주는 함수가 바로 crypt 입니다. :]
$passwd = crypt($fil[pw]); |
이걸로 사용자가 입력한 비밀 번호가 저장된 $fil[pw] 를 암호화해서 $passwd 에 저장했심다.
자아. 이제 입력받아온 값을 저장하는데 필요한 준비는 끝났습니다. 저장해볼까요?
$result = mysql_query("INSERT INTO $board VALUES('', $ist[num], $ist[idx], '$fil[title]', '$fil[text]', 0, 0, 0, 0, 0, '', '', 0, '$fil[name]', '$passwd', '$fil[email]', '$fil[homepage]', $intime)", $connect); |
바로 이겁니다. INSERT 문은 '쉬-짠5' 에 있습니다. 워낙 쉬운 내용이라. ^^; 단지 살짝 봐야할 부분이 두 군데인데 한 군데는 VALUES('', 이 부분이고 또 다른 한 군데는 $fil 로 시작하는 것들입니다.
일단 VALUES('', 가 무엇을 의미할까요. 아무것도 넣지 않는다는 의미겠죠? 그럼 뭐길래 글을 새로 추가하는데도 아무것도 저장하지 않을까요. 바로 no 입니다. no 는 테이블 만들 때 auto_increment 를 통해 INSERT 될 때마다 자동으로 1씩 증가되기로 했었죠? 그래서 따로 지정할 필요가 없습니다.
그럼 $fil 로 시작하는 것들, 즉 $fil[title], $fil[text], $fil[name] 등등은 뭘까요. 뭐긴요. 글쓰기 입력폼에서 날라오는 데이터가 저장된 변수지요. :]
이렇게 해서 글 입력의 가장 기본이 끝났답니다. 하지만 뭔가 석연찮군요. 문제가 있습니다. 그건 '는' 편에서 다루기로 해요. 일단은 개념부터 잡아야 하니까요.
요즘 칭찬과 격려의 소리를 많이 받는답니다. 감동이 주룩~ 허접한 제 강좌가 도움이 되신다는 여러분들의 격려에 제법 빛을 발하는 기분이더라구요. ^^;
이 글과 거의 동시에 올라올 다음 편은 우리가 입력한 글을 확실할 수 있게 게시물 리스트를 구현하겠습니다~! 아마 '쉬'편에서 가장 분량이 많지 않을까하는 걱정이 드는군요. T_T
아.무.튼. 글 쓰기 관련은 이것으로 끄읕!
다음 강좌에서 뵈요.
---------------------------- 함께하면 즐거운 사이트들 (-_-; 광고임 -_-;) http://game.creple.com/delthia http://creple.com http://coco.st ----------------------------
- ?! 디망쉬
|