본문 바로가기

Web Development/PHP

[PHP] 방명록 프로그램 구현

방명록이 무엇인가?

행사장·식장·기념관 등에서 방문하거나 참석한 사람의 이름을 적어 기념이 되도록 하기 위해
마련해 둔 공책이 우리가 알고있는 방명록의 정의입니다.

온라인에서의 방명록이란
내 홈페이지에 들어와서 여러 페이지를 구경한후
방문소감이나 다녀간흔적을 남길수 있는 프로그램을 말합니다.

 

※ 한예로 네이버 블로그의 안부게시판이 대표적인 방명록에 해당합니다.

 

방명록을 만들려면 뭐가 필요할까?

1. PHP를 지원하는 서버

2. MySQL DB서버

3. 에디터플러스와 같은 에디터프로그램

4. 만들 방명록의 설계

 

방명록프로그램에는 어떤 기능이 필요한가?

0. 글보기 기능

1. 글쓰기 기능

2. 글수정 가능

3. 글삭제 가능

4. 글쓸때 수정/삭제을 위한 비밀번호 입력하여 삭제/수정에 사용

5. 방명록글을 페이지단위로 볼수있는 페이지알고리즘 적용

 

방명록프로그램 개발 기술적인 절차

1. 방명록프로그램은 PHP언어와 MySQL DBMS를 이용해 만든다.

2. 방명록프로그램은 DB와 연동해서 개발하므로 DB에 TABLE을 생성한다.

3. MySQL DBMS에 만들어진 TABLE을 이용해 PHP언어로 DB와 연동하여 프로그램을 개발한다.

4. 개발후 프로그램안정성및 신뢰성을위해 테스트를 한다.

 

다시한번 MySQL이 뭔지 알아보자

예전의 게시판이나 방명록의 데이터는 대개 파일에 저장하였습니다.

예를 들면 누군가 글을 쓰면 sample.txt 라는 파일을 만들고
거기다가 이름, 이메일, 글의 내용등을 써 넣어서 저장을 하였습니다.
그리고 나서 글을 볼때면 이 파일을 읽은후 출력해주고는 했습니다.


그런데 글의 수와 입력 값등이 많아지자
이 데이터들 중에서 정말 원하는 데이터를 찾기가 어려워졌습니다. 
한마디로 데이터 관리가 어려워진겁니다.

그래서 보다 많은 데이터를 보다 효율적으로 관리하고자 해서
데이터베이스에 데이타를 저장하게 되었습니다.
MySQL도 이런 데이터베이스의 하나입니다.

그래서 달링은 방명록의 데이터를 보다 효율적으로 관리하기 위해 MySQL을 쓰기로 한것임!



MySQL에 방명록프로그램에 필요한 TABLE을 생성하자!
 

아래와같은 구조로 테이블을 만듭니다.

TableName : GUESTBOOK

+----------+-------------+------+-----+---------------------+----------------+
| Field           | Type           | Null | Key | Default                     | Extra               |
+----------+-------------+------+-----+---------------------+----------------+
| IDX             | int(11)         |          | PRI | NULL                    | auto_increment |
| NAME         | varchar(30)  | YES  |       | NULL                    |                        |
| COMMENT  | text             | YES  |       | NULL                    |                        |
| PW               | varchar(10)| YES   |       | NULL                    |                        |
| IP               | varchar(15) | YES   |       | NULL                    |                        |
| REG_DATE  | datetime      | YES  |       | 0000-00-00 00:00:00 |                         |
+----------+-------------+------+-----+---------------------+----------------+

 

아래 생성 SQL 쿼리가 있지만 한번 보지 말고 만들어 보세요.

 

CREATE TABLE GUESTBOOK
(
IDX INT(11) PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(30) NULL,
COMMENT TEXT NULL,
PW VARCHAR(10) NULL,
IP VARCHAR(15) NULL,
REG_DATE DATETIME DEFAULT '0000-00-00 00:00:00'
);

 

생성후 desc GUESTBOOK; 명령으로 테이블을 구조를 보고 제대로 생성되어 확인합니다.

방명록 글리스트_내용보기/글쓰기/글수정/글삭제를 해보겠습니다

방명록 프로그램 파일 구성

guestbook.php(방명록 리스트 보기/쓰기 페이지)

※ 방명록의 특성상 리스트마다 글의 내용이 모두 출력됩니다.

process.php(방명록 글쓰기/글수정/글삭제 처리페이지)

guestbook_pw.php(방명록 패스워드 체크페이지)

guestbook_modify.php(방명록글 수정 페이지)

 

방명록 프로그램 실행파일 실행 절차

방명록 프로그램 내/외부 처리 절차

방명록 프로그램 소스 내용

 

guestbook.php 소스

<?
 //# DB 설정 정보 #//
 $connect = mysql_connect("localhost","byc","freely21c") or die("SQL server에 연결할 수 없습니다.");
 mysql_select_db("byc", $connect);
?>

<HTML>

<HEAD>
<TITLE>GuestBook</TITLE>

<script language="javascript">
<!--

 function guestbook_write()
 {
  form = document.write;
  if (form.name.value == "")
  {
   alert("이름 입력 요망");
   form.name.focus();
  }
  else if(form.passwd.value == "")
  {
   alert("비밀번호 입력 요망");
   form.passwd.focus();
  }
  else if(form.comment.value == "")
  {
   alert("내용 입력 요망");
   form.comment.focus();
  }
  else
  {
   form.submit();
  }
 }
-->
</script>

</HEAD>


<BODY BGCOLOR="#006699" TEXT="#FFFFFF">

 <FORM name='write' method='post' action="process.php">
  <input type=hidden name=mode value='write'>
  <TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="390" style="border:skyblue dotted1px">
   <TR >
    <TD align="center" bgcolor='#5485B6' width="100">이름</TD>
    <TD><P>&nbsp;<INPUT type='text' name='name' SIZE=6 width="290"></TD>
   </TR>
   <TR>
    <TD align="center" bgcolor='#5485B6'>패스워드</TD>
    <TD><P>&nbsp;<INPUT type='password' name='passwd' size=20 ></TD>
   </TR>
   <TR>
    <TD align="center" bgcolor='#5485B6'>남기실 말씀</TD><!--TEXTAREA필드속성에 wrap="hard" 추가-->
    <TD><P>&nbsp;<TEXTAREA name='comment' rows='4' cols='37' wrap="hard"></TEXTAREA></TD>
   </TR>
   <TR>
    <TD colspan="2" align="center"><P>&nbsp;<INPUT type='button' value='글남기기' onClick="guestbook_write();"></TD>
   </TR>
  </TABLE>
 </FORM>
<?

 //# $query1 = " SELECT * FROM GUESTBOOK ORDER BY IDX DESC "; #//

 $query1 = " SELECT IDX, NAME, COMMENT, PW, IP, DATE_FORMAT(REG_DATE,'%Y년 %m월 %d일') AS REG_DATE ";
 $query1 .= " FROM  GUESTBOOK ORDER BY IDX DESC ";

 $result = mysql_query($query1, $connect);
 $total = mysql_affected_rows();

 //# 첫페이지라면 0 부터 시작 #//
 if (!$start)
 {
  $start = 0;
 }
 
 //# 페이지당 10개의 방명록 글을 출력하기 #//
 $scale = 10;

 for($i = $start ; $i < $start + $scale ; $i++)
 {
  if ($i < $total)
  {
   mysql_data_seek($result, $i); //# 검색된 자료중 $i 번째글을 찾고 #//
   $row = mysql_fetch_array($result); //# $i번째글의 내용을 $row 변수에 배열로 저장합니다. #//
 ?>
 <TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="390">
  <TR>
   <TD align="center" bgcolor='#5485B6' width="100" height="25">이름</TD>
   <TD width="290"><P>&nbsp;<?=$row[NAME]?></TD>
  </TR>
  <TR>
   <TD align="center" bgcolor='#5485B6' height="70">남기실 말씀</TD>
   <TD valign="top"><?=$row[COMMENT]?></TD>
  </TR>
  <TR><!--사용자IP 작성날짜 항목 소스 추가-->
   <TD align="center" bgcolor='#5485B6' width="100" height="25">작성날짜</TD>
   <TD width="290"><P>&nbsp;<?=$row[REG_DATE]?></TD>
  </TR>
  <TR>
   <TD align="center" bgcolor='#5485B6' width="100" height="25">사용자 IP</TD>
   <TD width="290"><P>&nbsp;<?=$row[IP]?></TD>
  </TR>
   <TR align="center">
   <TD colspan="2" bgcolor='#5485B6'><input type="button" value="수정하기" onClick="location.href='guestbook_pw.php?idx=<?=$row["IDX"]?>&mode=modify';"> <input type="button" value="삭제하기" onClick="location.href='guestbook_pw.php?idx=<?=$row["IDX"]?>&mode=delete';"></TD>
  </TR>

  <TR>
   <TD colspan="2"><HR size='1' noshade color="white"></TD>
  </TR>
 </TABLE>
<?
  } //# if ($i < $total)
 }
?>
</BODY>
</HTML>

 

process.php 소스

<?
 //# DB 설정 정보 #//
 $connect = mysql_connect("localhost","byc","freely21c") or die("SQL server에 연결할 수 없습니다.");
 mysql_select_db("byc", $connect);
 
 //# 글쓰기 처리 #//
 if($mode == "write")
 {
  //# $REMOTE_ADDR은 PHP에서 미리 정의한 변수입니다. #//
  $query1 = " INSERT INTO GUESTBOOK VALUES (null,'$name','$comment','$passwd','$REMOTE_ADDR',now()) ";
  mysql_query($query1, $connect);
 }
 //# 글수정 처리 #//
 else if($mode == "modify")
 {
  $query1 = " UPDATE GUESTBOOK SET NAME = '$name' , PW = '$passwd' , COMMENT = '$comment' , REG_DATE = now() WHERE IDX = '$idx' ";
  mysql_query($query1, $connect);
 }
 //# 글삭제 처리 #//
 else if($mode == "delete")
 {
 
  $pw1 = " SELECT * FROM GUESTBOOK WHERE IDX = '$idx' AND PW = '$passwd' ";
  mysql_query($pw1, $connect);
  $pw1_num = mysql_affected_rows();
  if( $pw1_num == 0)
  {
   echo "<script>alert('패스워드 확인');history.go(-1);</script>";
   exit; //# 프로그램 종료함수
  }
  
  $query1 = " DELETE FROM GUESTBOOK WHERE IDX = '$idx' ";
  mysql_query($query1, $connect);
 }
 
 //# 해당페이지이동(Header앞에 공백,출력문자열 있으면 에러) #//
 Header("Location:guestbook.php");
 
?>

 

guestbook_pw.php

<?
 //# mode별로 설정
 if($mode == "modify")
 {
  $msg = "수정하시려면";
  $action = "guestbook_modify.php";
 }
 else
 {
  $msg = "삭제하시려면";
  $action = "process.php";
 }

?>
<HTML>

<HEAD>
<TITLE>GuestBook</TITLE>

<script language="javascript">
<!--

 function guestbook_pw()
 {
  form = document.write;
  if (form.passwd.value == "")
  {
   alert("비밀번호 입력 요망");
   form.passwd.focus();
  }
  else
  {
   form.submit();
  }
 }
 
-->
</script>

</HEAD>

<BODY BGCOLOR="#006699" TEXT="#FFFFFF">
 <FORM name='write' method='post' action="<?=$action?>">
  <input type="hidden" name="idx" value="<?=$idx?>"><!--순서값-->
  <input type="hidden" name="mode" value="<?=$mode?>"><!--처리종류-->
  <TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="400" style="border:skyblue dotted1px">
   <TR align="center" height="30">
    <TD bgcolor='#5485B6' colspan="2"><?=$msg?> 정확한 패스워드를 입력해주십시오.</TD>
   </TR>
   <TR align="center" height="30">
    <TD bgcolor='#5485B6'>패스워드</TD>
    <TD><INPUT type='password' name="passwd"> <INPUT type='button' value='확인' onClick="guestbook_pw();"></TD>
   </TR>
   <TR align="center" height="30">
    <TD bgcolor='#5485B6' colspan="2"><a href="guestbook.php">방명록 이동</a></TD>
   </TR>
  </TABLE>
 </FORM>
</BODY>
</HTML>

 

guestbook_modify.php

<?
 //# DB 설정 정보 #//
 $connect = mysql_connect("localhost","byc","freely21c") or die("SQL server에 연결할 수 없습니다.");
 mysql_select_db("byc", $connect);

 //# 패스워드 체크 #//
 $pw1 = " SELECT * FROM GUESTBOOK WHERE IDX = '$idx' AND PW = '$passwd' ";
 mysql_query($pw1, $connect);
 $pw1_num = mysql_affected_rows();
 if( $pw1_num == 0)
 {
  echo "<script>alert('패스워드 확인');history.go(-1);</script>";
  exit;
 }
 
 //# 방명록 글 읽어오기 #//
 $qry1 = " SELECT * FROM GUESTBOOK WHERE IDX = '$idx' ";
 $result = mysql_query($qry1, $connect);
 $qry1_row = mysql_fetch_array($result);
?>

<HTML>

<HEAD>
<TITLE>GuestBook</TITLE>

<script language="javascript">
<!--

 function guestbook_modify()
 {
  form = document.write;
  if (form.name.value == "")
  {
   alert("이름 입력 요망");
   form.name.focus();
  }
  else if(form.passwd.value == "")
  {
   alert("비밀번호 입력 요망");
   form.passwd.focus();
  }
  else if(form.comment.value == "")
  {
   alert("내용 입력 요망");
   form.comment.focus();
  }
  else
  {
   form.submit();
  }
 }
-->
</script>

</HEAD>


<BODY BGCOLOR="#006699" TEXT="#FFFFFF">

 <FORM name='write' method='post' action="process.php">
  <input type=hidden name=idx value='<?=$idx?>'><input type=hidden name=mode value='modify'>
  <TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="390" style="border:skyblue dotted1px">
   <TR >
    <TD align="center" bgcolor='#5485B6' width="100">이름</TD>
    <TD><P>&nbsp;<INPUT type='text' name='name' SIZE=6 width="290" value="<?=$qry1_row["NAME"]?>"></TD>
   </TR>
   <TR>
    <TD align="center" bgcolor='#5485B6'>패스워드</TD>
    <TD><P>&nbsp;<INPUT type='password' name='passwd' size=20 value="<?=$qry1_row["PW"]?>"></TD>
   </TR>
   <TR>
    <TD align="center" bgcolor='#5485B6'>남기실 말씀</TD><!--TEXTAREA필드속성에 wrap="hard" 추가-->
    <TD><P>&nbsp;<TEXTAREA name='comment' rows='4' cols='37' wrap="hard"><?=$qry1_row["COMMENT"]?></TEXTAREA></TD>
   </TR>
   <TR>
    <TD colspan="2" align="center"><P>&nbsp;<INPUT type='button' value='수정하기' onClick="guestbook_modify();"></TD>
   </TR>
  </TABLE>
 </FORM>
</BODY>
</HTML>


방명록 페이징 출력을 해보자.

스스로 소스 코딩해보고 실행해서 동작하는거 보고 다음시간에 설명해줄께요.

 

<?
 //# DB 설정 정보 #//
 $connect = mysql_connect("localhost","byc","freely21c") or die("SQL server에 연결할 수 없습니다.");
 mysql_select_db("byc", $connect);
?>

<HTML>

<HEAD>
<TITLE>GuestBook</TITLE>
<!-- 인코딩 언어를 한국어로 설정 -->
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">

<script language="javascript">
<!--
 function guestbook_write()
 {
  form = document.write;
  if (form.name.value == "")
  {
   alert("이름 입력 요망");
   form.name.focus();
  }
  else if(form.passwd.value == "")
  {
   alert("비밀번호 입력 요망");
   form.passwd.focus();
  }
  else if(form.comment.value == "")
  {
   alert("내용 입력 요망");
   form.comment.focus();
  }
  else
  {
   form.submit();
  }
 }
-->
</script>

</HEAD>


<BODY BGCOLOR="#006699" TEXT="#FFFFFF">

 <FORM name='write' method='post' action="process.php">
  <input type=hidden name=mode value='write'>
  <TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="390" style="border:skyblue dotted1px">
   <TR >
    <TD align="center" bgcolor='#5485B6' width="100">이름</TD>
    <TD><P>&nbsp;<INPUT type='text' name='name' SIZE=6 width="290"></TD>
   </TR>
   <TR>
    <TD align="center" bgcolor='#5485B6'>패스워드</TD>
    <TD><P>&nbsp;<INPUT type='password' name='passwd' size=20 ></TD>
   </TR>
   <TR>
    <TD align="center" bgcolor='#5485B6'>남기실 말씀</TD><!--TEXTAREA필드속성에 wrap="hard" 추가-->
    <TD><P>&nbsp;<TEXTAREA name='comment' rows='4' cols='37' wrap="hard"></TEXTAREA></TD>
   </TR>
   <TR>
    <TD colspan="2" align="center"><P>&nbsp;<INPUT type='button' value='글남기기' onClick="guestbook_write();"></TD>
   </TR>
  </TABLE>
 </FORM>
<?

 $query1 = " SELECT IDX, NAME, COMMENT, PW, IP, DATE_FORMAT(REG_DATE,'%Y년 %m월 %d일') AS REG_DATE ";
 $query1 .= " FROM  GUESTBOOK ORDER BY IDX DESC ";

 $result = mysql_query($query1, $connect);
 $total = mysql_affected_rows();

 //# 첫페이지라면 기본으로 0 부터 시작 #//
 if (!$start)
 {
  $start = 0;
 }
 
 //# 페이지당 출력할 방명록글 갯수 #//
 $scale = 3;
 
 for($i = $start ; $i < $start + $scale ; $i++)
 {
  if ($i < $total)
  {

   mysql_data_seek($result, $i); //# 검색된 자료중 $i 번째글을 찾고 #//
   

   $row = mysql_fetch_array($result); //# $i번째글의 내용을 $row 변수에 배열로 저장합니다. #//
   
   $comment = str_replace(" ","&nbsp; ",$row[COMMENT]); //# 공백을 &nbsp; 문자로 변경 #//
   
   /*
   str_replace()함수를 저장할때 사용하면 공백을 &nbsp;로 변경시켜 저장하여 출력때 공백을 다 표현해주지만
   수정하고 나서 글을 출력하면 공백부분이 *nbcp;로 나와버린다. 그래서 저장할때가 아닌 글을 출력할때 사용하자
   글을 출력할때만 사용해도 제대로 사용할수 있다.
   */

   $comment = nl2br($comment); //# 개행문자를 <br>태그로 변경 #//
   
   /*
   nl2br()함수를 db에 저장할때 사용하면 개행문자가 <br/>로 변경되어 저장된다.
   문제는 수정할때 <br/>이 다 나와버려서 좀 지저분해진다.그래서 저장할때 사용하지 않고
   해당 글을 볼때사용하자. 저장할때 nl2br()함수를 사용하지 않아도 출력할때 nl2br()함수만
   사용하면 문제없이 처리 가능하다.
   */
 ?>
 <TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="390">
  <TR>
   <TD align="center" bgcolor='#5485B6' width="100" height="25">이름</TD>
   <TD width="290"><P>&nbsp;<?=$row[NAME]?></TD>
  </TR>
  <TR>
   <TD align="center" bgcolor='#5485B6' height="70">남기실 말씀</TD>
   <TD valign="top"><?=$comment?></TD>
  </TR>
  <TR><!--사용자IP 작성날짜 항목 소스 추가-->
   <TD align="center" bgcolor='#5485B6' width="100" height="25">작성날짜</TD>
   <TD width="290"><P>&nbsp;<?=$row[REG_DATE]?></TD>
  </TR>
  <TR>
   <TD align="center" bgcolor='#5485B6' width="100" height="25">사용자 IP</TD>
   <TD width="290"><P>&nbsp;<?=$row[IP]?></TD>
  </TR>
  <TR align="center">
   <TD colspan="2" bgcolor='#5485B6'><input type="button" value="수정하기" onClick="location.href='guestbook_pw.php?idx=<?=$row["IDX"]?>&mode=modify';"> <input type="button" value="삭제하기" onClick="location.href='guestbook_pw.php?idx=<?=$row["IDX"]?>&mode=delete';"></TD>
  </TR>
  <TR>
   <TD colspan="2"><HR size='1' noshade color="white"></TD>
  </TR>
 </TABLE>
<?
  }//# if ($i < $total)
 }//# for($i = $start ; $i < $start + $scale ; $i++)
?>

<TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="390">
  <TR>
   <TD align="center" bgcolor='#5485B6'>
   <?
    
    $p_p = $start - $scale ; // 이전 페이지는 현재 페이지에서 $scale을 뺀값부터
    $n_p = $start + $scale ; // 다음 페이지는 현재 페이지에서 $scale을 더한값부터
    
    if ($p_p >= 0 )
    {
     echo "<a href='$PHP_SELF?start=$p_p'>◁◀◁</a> ";
    }
    else
    {
     echo "◁◀◁";

    }
    if ($n_p < $total)
    {
     echo "<a href='$PHP_SELF?start=$n_p'>▷▶▷</a></center>";
    }
    else
    {
     echo "▷▶▷";

    }
   ?>
   </TD>
  </TR>
 </TABLE>


</BODY>
</HTML>

<?
 //# DB 설정 정보 #//
 $connect = mysql_connect("localhost","byc","freely21c") or die("SQL server에 연결할 수 없습니다.");
 mysql_select_db("byc", $connect);
?>



<HTML>

<HEAD>
<TITLE>GuestBook</TITLE>
<!-- 인코딩 언어를 한국어로 설정 -->
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">

<script language="javascript">
<!--
 function guestbook_write()
 {
  form = document.write;
  if (form.name.value == "")
  {
   alert("이름 입력 요망");
   form.name.focus();
  }
  else if(form.passwd.value == "")
  {
   alert("비밀번호 입력 요망");
   form.passwd.focus();
  }
  else if(form.comment.value == "")
  {
   alert("내용 입력 요망");
   form.comment.focus();
  }
  else
  {
   form.submit();
  }
 }
-->
</script>

</HEAD>


<BODY BGCOLOR="#006699" TEXT="#FFFFFF">

 <FORM name='write' method='post' action="process.php">
  <input type=hidden name=mode value='write'>
  <TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="390" style="border:skyblue dotted1px">
   <TR >
    <TD align="center" bgcolor='#5485B6' width="100">이름</TD>
    <TD><P>&nbsp;<INPUT type='text' name='name' SIZE=6 width="290"></TD>
   </TR>
   <TR>
    <TD align="center" bgcolor='#5485B6'>패스워드</TD>
    <TD><P>&nbsp;<INPUT type='password' name='passwd' size=20 ></TD>
   </TR>
   <TR>
    <TD align="center" bgcolor='#5485B6'>남기실 말씀</TD><!--TEXTAREA필드속성에 wrap="hard" 추가-->
    <TD><P>&nbsp;<TEXTAREA name='comment' rows='4' cols='37' wrap="hard"></TEXTAREA></TD>
   </TR>
   <TR>
    <TD colspan="2" align="center"><P>&nbsp;<INPUT type='button' value='글남기기' onClick="guestbook_write();"></TD>
   </TR>
  </TABLE>
 </FORM>
<?

 $query1 = " SELECT IDX, NAME, COMMENT, PW, IP, DATE_FORMAT(REG_DATE,'%Y년 %m월 %d일') AS REG_DATE ";
 $query1 .= " FROM  GUESTBOOK ORDER BY IDX DESC ";

 $result = mysql_query($query1, $connect);
 $total = mysql_affected_rows();

 //# 첫페이지라면 기본으로 0 부터 시작 #//
 if (!$start)
 {
  $start = 0;
 }
 
 //# 페이지당 출력할 방명록글 갯수 #//
 $scale = 3;
 
 for($i = $start ; $i < $start + $scale ; $i++)
 {
  if ($i < $total)
  {

   mysql_data_seek($result, $i); //# 검색된 자료중 $i 번째글을 찾고 #//
   

   $row = mysql_fetch_array($result); //# $i번째글의 내용을 $row 변수에 배열로 저장합니다. #//
   
   $comment = str_replace(" ","&nbsp; ",$row[COMMENT]); //# 공백을 &nbsp; 문자로 변경 #//
   
   /*
   str_replace()함수를 저장할때 사용하면 공백을 &nbsp;로 변경시켜 저장하여 출력때 공백을 다 표현해주지만
   수정하고 나서 글을 출력하면 공백부분이 *nbcp;로 나와버린다. 그래서 저장할때가 아닌 글을 출력할때 사용하자
   글을 출력할때만 사용해도 제대로 사용할수 있다.
   */

   $comment = nl2br($comment); //# 개행문자를 <br>태그로 변경 #//
   
   /*
   nl2br()함수를 db에 저장할때 사용하면 개행문자가 <br/>로 변경되어 저장된다.
   문제는 수정할때 <br/>이 다 나와버려서 좀 지저분해진다.그래서 저장할때 사용하지 않고
   해당 글을 볼때사용하자. 저장할때 nl2br()함수를 사용하지 않아도 출력할때 nl2br()함수만
   사용하면 문제없이 처리 가능하다.
   */
 ?>
 <TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="390">
  <TR>
   <TD align="center" bgcolor='#5485B6' width="100" height="25">이름</TD>
   <TD width="290"><P>&nbsp;<?=$row[NAME]?></TD>
  </TR>
  <TR>
   <TD align="center" bgcolor='#5485B6' height="70">남기실 말씀</TD>
   <TD valign="top"><?=$comment?></TD>
  </TR>
  <TR><!--사용자IP 작성날짜 항목 소스 추가-->
   <TD align="center" bgcolor='#5485B6' width="100" height="25">작성날짜</TD>
   <TD width="290"><P>&nbsp;<?=$row[REG_DATE]?></TD>
  </TR>
  <TR>
   <TD align="center" bgcolor='#5485B6' width="100" height="25">사용자 IP</TD>
   <TD width="290"><P>&nbsp;<?=$row[IP]?></TD>
  </TR>
  <TR align="center">
   <TD colspan="2" bgcolor='#5485B6'><input type="button" value="수정하기" onClick="location.href='guestbook_pw.php?idx=<?=$row["IDX"]?>&mode=modify';"> <input type="button" value="삭제하기" onClick="location.href='guestbook_pw.php?idx=<?=$row["IDX"]?>&mode=delete';"></TD>
  </TR>
  <TR>
   <TD colspan="2"><HR size='1' noshade color="white"></TD>
  </TR>
 </TABLE>
<?
  }//# if ($i < $total)
 }//# for($i = $start ; $i < $start + $scale ; $i++)
?>

<TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="390">
  <TR>
   <TD align="center" bgcolor='#5485B6'>
   <?
    
    $p_p = $start - $scale ; // 이전 페이지는 현재 페이지에서 $scale을 뺀값부터
    $n_p = $start + $scale ; // 다음 페이지는 현재 페이지에서 $scale을 더한값부터
    
    if ($p_p >= 0 )
    {
     echo "<a href='$PHP_SELF?start=$p_p'>◁◀◁</a> ";
    }
    else
    {
     echo "◁◀◁";

    }
    if ($n_p < $total)
    {
     echo "<a href='$PHP_SELF?start=$n_p'>▷▶▷</a></center>";
    }
    else
    {
     echo "▷▶▷";

    }
   ?>
   </TD>
  </TR>
 </TABLE>


</BODY>
</HTML>


방명록 프로그램에 사용되는 페이징 알고리즘이란

페이징 알고리즘은 전체 게시물을 복수의 페이지로 나눈후
페이지단위로 이동하면서 열람할수 있는 알고리즘으로 Web에서 가장많이 사용하는 알고리즘이다
 

페이징 하는 방식은 2가지 있다.

방명록에서 사용하는 순서대로 한페이지씩 이동하는 순차적 이동 페이징 방식

게시판에서의 사용하는 마음대로 페이지를 이동하는 무차별 이동 페이징 방식이 있다.

 

사용목적

사용목적은 전체 게시물을 한번에 다루게 되면 서버에 대한 부담도 커지고
사용자 또한 늦은 처리결과에 장시간 기다려야 하는 결과를 초래한다.

하지만 전체 게시물을 페이지단위로 처리하게 되면 서버에 대한 부담도 줄고
사용자 또한 좀더 빠른 처리결과를 볼수 있어 효율적인면이나
처리속도면에서 많은 이점이 생기기 때문에 페이징알고리즘을 사용한다.

 

순차적 이동 페이징 방식 사용 예제

<?
/*
 **********************************************************************
 * 페이지명  : 방가게시판 페이징 출력
 * 버전        : V 1.0.0.0
 * 작성자     : 
 * 이메일     : 
 * 작성일     : 
 ***********************************************************************
 #### 수정 내역 리스트 ####
 ***********************************************************************
 수정일       |수정자    |수정내용
 ***********************************************************************
 파일생성
 ***********************************************************************
*/

 include "./lib/include.php";

 $total_count = 50; //# 전체 자료 갯수

 $page_count = 4; //# 페이지당 출력 자료 갯수

 if(empty($start))//# $start값 없을시 기본값으로 0 대입
 {
  $start = 0;
 }
 

 for($num = $start; $num < $start + $page_count; $num++)
 {
  if( $num < $total_count)
  {
   echo $num . "<br>";
  }
 }


 $p_p = $start - $page_count; //# 이전 페이지 시작 순서값 구하기
 $n_p = $start + $page_count; //# 다음 페이지 시작 순서값 구하기
 
 //# 이전페이지 시작 순서값이 0보다 크거나 같으면 링크 설정
 //# 이전페이지 시작 순서값이 0보다 작으면 링크 설정 안함
 if ($p_p >= 0 )
 {
  echo "<a href='$PHP_SELF?start=$p_p'>◁◁◁</a> ";
 }
 else
 {
  echo "◀◀◀";
 }
 
 //# 다음페이지 시작 순서값이 전체 자료 갯수 보다 작으면 링크 설정
 //# 다음페이지 시작 순서값이 전체 자료 갯수 보다 크거나 같으면 링크 설정 안함
 if($n_p < $total_count)
 {
  echo "<a href='$PHP_SELF?start=$n_p'>▷▷▷</a></center>";
 }
 else
 {
  echo "▶▶▶";
 }

?>

 

※ 위의 소스는 순차적 이동 페이징 방식을 간단하게 표현한것임.



방명록 프로그램에 간단한 사용자 아이콘(?)을 넣어 봅니다.
 

이 사용자 아이콘이미지는 방명록을 작성한 사용자가 선택할수 있는 아이콘입니다.

 

기능 추가 요건 정의

1. 방명록 쓰기 폼에 사용자 아이콘 선택 항목이 추가된다.

2. 해당 이미지 3개를 웹의 적당한 경로에 업로드 한다. 

3. 방명록 테이블에 아이콘 저장 필드를 추가한다.

4. 방명록 글쓰기 처리 페이지 에서 사용자 아이콘 값도 DB에 입력한다.

5. 방명록 리스트보기 페이지에서 이름앞에 사용자 아이콘을 출력한다.

 

GUESTBOOK TABLE에 필드 추가하기

필드 추가

alter table GUESTBOOK add icon char(1) default '1';

필드 삭제

alter table GUESTBOOK drop icon;

 

기존 소스에서 추가된 소스부분(guestbook.php, process.php)

guestbook.php

<?
 //# DB 설정 정보 #//
 $connect = mysql_connect("localhost","byc","freely21c") or die("SQL server에 연결할 수 없습니다.");
 mysql_select_db("byc", $connect);
?>

<HTML>

<HEAD>
<TITLE>GuestBook</TITLE>
<!-- 인코딩 언어를 한국어로 설정 -->
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">

<script language="javascript">
<!--
 function guestbook_write()
 {
  form = document.write;
  if (form.name.value == "")
  {
   alert("이름 입력 요망");
   form.name.focus();
  }
  else if(form.passwd.value == "")
  {
   alert("비밀번호 입력 요망");
   form.passwd.focus();
  }
  else if(form.comment.value == "")
  {
   alert("내용 입력 요망");
   form.comment.focus();
  }
  else
  {
   form.submit();
  }
 }
-->
</script>

</HEAD>
<BODY BGCOLOR="#006699" TEXT="#FFFFFF">
 <FORM name='write' method='post' action="process.php">
  <input type=hidden name=mode value='write'>
  <TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="390" style="border:skyblue dotted1px">
   <TR >
    <TD align="center" bgcolor='#5485B6' width="100">이름</TD>
    <TD><P>&nbsp;<INPUT type='text' name='name' SIZE=6 width="290"></TD>
   </TR>
   <TR>
    <TD align="center" bgcolor='#5485B6'>패스워드</TD>
    <TD><P>&nbsp;<INPUT type='password' name='passwd' size=20 ></TD>
   </TR>
   <TR>
    <TD align="center" bgcolor='#5485B6'>아이콘 선택</TD>
    <TD>
     <P>&nbsp;
     <input type="radio" name="icon" value="1" checked><img src="lee1.gif">
     <input type="radio" name="icon" value="2"><img src="lee2.gif">
     <input type="radio" name="icon" value="3"><img src="lee3.gif"></TD>
   </TR>
   <TR>
    <TD align="center" bgcolor='#5485B6'>남기실 말씀</TD><!--TEXTAREA필드속성에 wrap="hard" 추가-->
    <TD><P>&nbsp;<TEXTAREA name='comment' rows='4' cols='37' wrap="hard"></TEXTAREA></TD>
   </TR>
   <TR>
    <TD colspan="2" align="center"><P>&nbsp;<INPUT type='button' value='글남기기' onClick="guestbook_write();"></TD>
   </TR>
  </TABLE>
 </FORM>
<?
 
 $query1 = " SELECT IDX, NAME, COMMENT, PW, IP, DATE_FORMAT(REG_DATE,'%Y년 %m월 %d일') AS REG_DATE, icon ";
 $query1 .= " FROM  GUESTBOOK ORDER BY IDX DESC ";

 $result = mysql_query($query1, $connect);
 $total = mysql_affected_rows();

 //# 첫페이지라면 기본으로 0 부터 시작 #//
 if (!$start)
 {
  $start = 0;
 }
 
 //# 페이지당 출력할 방명록글 갯수 #//
 $scale = 3;
 
 for($i = $start ; $i < $start + $scale ; $i++)
 {
  if ($i < $total)
  {
   mysql_data_seek($result, $i); //# 검색된 자료중 $i 번째글을 찾고 #//
   
   $row = mysql_fetch_array($result); //# $i번째글의 내용을 $row 변수에 배열로 저장합니다. #//
   
   $comment = str_replace(" ","&nbsp; ",$row[COMMENT]); //# 공백을 &nbsp; 문자로 변경 #//
   
   /*
   str_replace()함수를 저장할때 사용하면 공백을 &nbsp;로 변경시켜 저장하여 출력때 공백을 다 표현해주지만
   수정하고 나서 글을 출력하면 공백부분이 *nbcp;로 나와버린다.

그래서 저장할때가 아닌 글을 출력할때 사용하자
 글을 출력할때만 사용해도 제대로 사용할수 있다.
   */

   $comment = nl2br($comment); //# 개행문자를 <br>태그로 변경 #//
   
   /*
   nl2br()함수를 db에 저장할때 사용하면 개행문자가 <br/>로 변경되어 저장된다.
   문제는 수정할때 <br/>이 다 나와버려서 좀 지저분해진다.
  그래서 저장할때 사용하지 않고 해당 글을 볼때사용하자.
저장할때 nl2br()함수를 사용하지 않아도 출력할때 nl2br()함수만
   사용하면 문제없이 처리 가능하다.
   */

   if( $row[icon] == "1" )
   {
    $user_icon = "<img src='lee1.gif'>";
   }
   else if( $row[icon] == "2" )
   {
    $user_icon = "<img src='lee2.gif'>";
   }
   else if( $row[icon] == "3" )
   {
    $user_icon = "<img src='lee3.gif'>";
   }

 ?>
 <TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="390">
  <TR>
   <TD align="center" bgcolor='#5485B6' width="100" height="25">이름</TD>
   <TD width="290"><P>&nbsp;<?=$user_icon?><?=$row[NAME]?></TD>
  </TR>
  <TR>
   <TD align="center" bgcolor='#5485B6' height="70">남기실 말씀</TD>
   <TD valign="top"><?=$comment?></TD>
  </TR>
  <TR><!--사용자IP 작성날짜 항목 소스 추가-->
   <TD align="center" bgcolor='#5485B6' width="100" height="25">작성날짜</TD>
   <TD width="290"><P>&nbsp;<?=$row[REG_DATE]?></TD>
  </TR>
  <TR>
   <TD align="center" bgcolor='#5485B6' width="100" height="25">사용자 IP</TD>
   <TD width="290"><P>&nbsp;<?=$row[IP]?></TD>
  </TR>
  <TR align="center">
   <TD colspan="2" bgcolor='#5485B6'><input type="button" value="수정하기" onClick="location.href='guestbook_pw.php?idx=<?=$row["IDX"]?>&mode=modify';"> <input type="button" value="삭제하기" onClick="location.href='guestbook_pw.php?idx=<?=$row["IDX"]?>&mode=delete';"></TD>
  </TR>
  <TR>
   <TD colspan="2"><HR size='1' noshade color="white"></TD>
  </TR>
 </TABLE>
<?
  }//# if ($i < $total)
 }//# for($i = $start ; $i < $start + $scale ; $i++)
?>

<TABLE border='0' cellspacing='1' cellpadding="0" align="center" width="390">
  <TR>
   <TD align="center" bgcolor='#5485B6'>
   <?
    
    $p_p = $start - $scale ; // 이전 페이지는 현재 페이지에서 $scale을 뺀값부터
    $n_p = $start + $scale ; // 다음 페이지는 현재 페이지에서 $scale을 더한값부터
    
    if ($p_p >= 0 )
    {
     echo "<a href='$PHP_SELF?start=$p_p'>◁◀◁</a> ";
    }
    else
    {
     echo "◁◀◁";

    }
    if ($n_p < $total)
    {
     echo "<a href='$PHP_SELF?start=$n_p'>▷▶▷</a></center>";
    }
    else
    {
     echo "▷▶▷";

    }
   ?>
   </TD>
  </TR>
 </TABLE>


</BODY>
</HTML>

process.php

<?
 //# DB 설정 정보 #//
 $connect = mysql_connect("localhost","byc","freely21c") or die("SQL server에 연결할 수 없습니다.");
 mysql_select_db("byc", $connect);
 
 //# 글쓰기 처리 #//
 if($mode == "write")
 {
  //# $REMOTE_ADDR은 PHP에서 미리 정의한 변수입니다. #//
  $query1 = " INSERT INTO GUESTBOOK VALUES (null,'$name','$comment','$passwd','$REMOTE_ADDR',now(),'$icon') ";
  mysql_query($query1, $connect);
 }
 //# 글수정 처리 #//
 else if($mode == "modify")
 {
  $query1 = " UPDATE GUESTBOOK SET NAME = '$name' , PW = '$passwd' , COMMENT = '$comment' , REG_DATE = now() WHERE IDX = '$idx' ";
  mysql_query($query1, $connect);
 }
 //# 글삭제 처리 #//
 else if($mode == "delete")
 {
 
  $pw1 = " SELECT * FROM GUESTBOOK WHERE IDX = '$idx' AND PW = '$passwd' ";
  mysql_query($pw1, $connect);
  $pw1_num = mysql_affected_rows();
  if( $pw1_num == 0)
  {
   echo "<script>alert('패스워드 확인');history.go(-1);</script>";
   exit; //# 프로그램 종료함수
  }
  
  $query1 = " DELETE FROM GUESTBOOK WHERE IDX = '$idx' ";
  mysql_query($query1, $connect);
 }
 
 //# 해당페이지이동(Header앞에 공백,출력문자열 있으면 에러) #//
 Header("Location:guestbook.php");
 
?>