웹마스터 팁

교육용 메모장 #4

2000.07.10 15:33

zero

Lib.php3에서 사용하는 함수는 위에서 알아보았죠?
그럼 memo.php3 파일을 만들어봅시다.
memo.php3 파일은 리스트를 보여주는 부분과 글입력 폼만 있으면 됩니다.

그럼 하나 하나의 구현방법을 알아보도록 합시다.

리스트를 보여주기 위해서는 MySQL DB에서 자료를 가져와야 합니다.

$result=mysql_query("select * from memo order by no desc", $connect)  or die(mysql_error());

위의 한줄이면 자신의 DB에서 memo라는 테이블의 모든 자료를 가져 옵니다.
select * from memo 는 memo라는 테이블에서 모든 것, 즉 *를 가져오라는 쿼리입니다.
뒤에 있는 order by no desc 는 no 라는 데이터의 순서를 역순으로 하라는 겁니다.
no는 앞에서 정의할 때 숫자로 하고 차례대로 1씩 증가하는 데이터입니다.
그렇기 때문에 가장 나중에 저장된 글 같은경우는 가장 큰값을 가지게 되죠.
그렇기 때문에 desc 라는 쿼리를 주어서 order by no를 하게 되면 역순, 즉 최근 글 순서대로 자료를 가져오게 됩니다.

뒤에 있는  or die(mysql_error());는 만약 자료를 DB로부터 가져올 때 에러가 생기면 화면에 출력을 하고 프로그램을 종료시킵니다.
mysql_error()이라는 함수는 DB 사용시 일어나는 에러값중 최근값을 가지고 있습니다.

위와 같이 하면 memo 테이블에 있는 모든 자료는 $result 라는 변수안에 저장이 되어 있는 상태입니다.
그런데 이 $result 변수안에는 우리가 바로 쓸수 있는 형태로 자료가 저장되어 있지 않습니다.
그렇기 때문에 mysql_fetch_array() 라는 함수를 이용해서 우리가 직접 쓸수 있는 데이터로 변환을 하여야 합니다.
그런데 DB에서 뽑아온 자료는 여러행이 있겠죠?
그렇기 때문에 mysql_fetch_array()는 첫 번째 행을 우리가 쓸수 있는 배열 형태로 바꾸어서 Return 해준다음 다음행으로 포인터를 이동합니다.
그럼 다음과 같이 사용을 해주면 되겠죠.

while($data=mysql_fetch_array($result))
{
// 출력
}

whilie() 문은 괄호 안의 값이 0이 아닐 경우, 즉 어떤 값이 라도 있으면 계속 실행이 됩니다.
$data라는 변수에는 mysql_fetch_array($result)에서 넘겨받은 값을 가지게 되죠.
그 값이 0이 아니면, 즉 빈 값이 아니면 계속해서 while 문을 실행하게 됩니다.
그럼 우리는 { } 안에 $data의 값을 출력하게 하면 되는거죠.

그럼 이 데이터를 어떻게 출력할까요?

$data 라는 변수안에는 배열의 형태로 no, name, memo, reg_date 의 값이 들어가 있습니다.

즉, $data[no], $data[name], $data[memo], $data[reg_date] 로 사용할수 있습니다.
출력은 echo ""; 문을 이용하면 됩니다.

echo "이름 : $data[name]";

이런식으로요.
그런데 여기서 중요한 것 하나!
만약 저장되어 있는글이 수십개, 수백개가 되면 그걸 모두 보여줄수가 없죠?
페이지로 나누어야 할 필요가 있습니다.

페이지를 나누는 알고리즘은 생각만 조금 깊게 하게 되면 매우 간단합니다.
우선 전체 자료의 개수를 구해야 합니다.
현재 emo 테이블에 등록된 전체 갯수를 $total 이라는 변수에 저장을 합니다.

$temp=mysql_fetch_array(mysql_query("select count(*) from memo", $connect));
$total=$temp["count(*)"];

위에서 보면 mysql_query()를 mysql_fetch_array() 함수안에 넣어서 사용합니다.
하나의 자료만 가져올때는 위와 같이 해버리면 한줄로 쿼리를 해결할수 있기 때문에 편리합니다.

mysql_query("select count(*) from memo", $connect) 는  memo 테이블에서 count(*), 즉 개수를 가져오는 쿼리를 실행합니다.
그 가져온 데이터를 바로 mysql_fetch_array() 함수로 넣어버리는 겁니다.
그럼 해석된 결과가 $temp라는 변수에 저장이 됩니다.
이 $temp변수에서 $temp["count(*)"]의 값이 전체 값이 되는거죠.
이 값을 간편하게 $total 이라는 변수에 대입합니다.

이제 한페이지당 보여줄 목록의 개수를 정해야 겠죠?
$page_num=10;
로 하여서 10개만 보여주게합시다.
이값을 나중에 수정하기 편하게 $page_num 이라는 변수에 담아두죠.
그리고 지금이 현재 어떤 페이지인지를 알아야겠죠?
이 값을 $page 라는 변수를 이용해서 알아봅시다.
그런데 만약 처음 로딩할 때, 즉 $page 에 아무값도 없다면 당연히 1 페이지로 지정해야겠죠?

if(!$page) $page=1;

만약 $page에 아무값도 없다면, 즉 !$page 이면 $page변수에 1이라는 값을 입력하는 거죠.

그럼 이제 현재 페이지에서 보열줄 글의 목록을 지정해야겠죠?
현재 페이지에서 보여줄 목록의 처음 글만 알아보면 됩니다.

$start_num=($page-1)*$page_num;

$start_num 이라는 변수에 (현재페이지-1)*한페이지당 보여줄 개수의 값을 넣어줍니다.

이렇게 생각해보세요.
만약 한번에 10개의 글이 보여야 하고 현재 1페이지이면 첫 번째 목록은 0번이겠죠?
2번째 페이지이면 첫 번째 목록은 10이 되구요~

첫 번재 목록이 되는 이유는 MySQL Query에서 limit 라는 쿼리를 이용하기 때문입니다.
limit의 사용법은

limit 시작번호, 개수

시작번호를 0부터 지정해야 합니다.
그런 다음 개수에는 $page_num을 입력하면 되겠죠?
그러면 현재 페이지의 첫 번째 목록에서 $page_num만큼만 자료를 가져오게 됩니다.

limit를 지정하지 않는 다면 전체 데이터를 가져오기 때문에 서버의 부하도 많이 생기도 속도도 느리게 되죠.

그럼 전체 페이지의 개수를 구하는 계산입니다.

$total_page=(int)(($total-1)/$page_num)+1;

전체갯수가 11개이면 2의 값이 $total_page 변수에 저장이 됩니다.

그럼 이제 위에서 사용한
$result=mysql_query("select * from memo order by no desc", $connect) or die(mysql_error());
를 페이지 분할하기 위한 형식으로 변환해 봅시다.
그냥 뒤에다가 limit를 지정만 해주면 된답니다.

$result=mysql_query("select * from $table_name order by no desc limit $start_num,$page_num", $connect) or die(mysql_error());

간단하죠?

그럼 이제 아랫부분에 페이지를 표시해주어야 겠죠?

우선 페이지를 보여줄 개수를 정해주어야 합니다.

$show_page_num=10;

$show_page_num 이라는 변수에 한번에 보여줄 페이지 표시의 개수를 10개라고 지정해 놓습니다.

이걸 정하는 이유는 다음과 같습니다.
만약 1~10페이지중의 한 페이지를 보고 있다면 [1][2]~~~[9][10] 으로 보여주면 되죠.
만약 13페이지라면 [11][12]13[14][15]~[20] 로 보여주어야 하기 때문입니다.
즉 $show_page_num의 단계만큼 이동이 되는겁니다.

그런다음 [1], [11], [21] 등의 페이지 표시중 첫 번째 값을 구하여야 합니다.

$start_page=(int)(($page-1)/$show_page_num)*$show_page_num;

현재페이지에서 1을뺀후, 한번에 보이는 페이지 표시의 수만큼 나눕니다.
1을 빼는 이유는 1에서 10일경우에 0이라는 값을 얻기 위해서입니다.
즉, 1~10페이지를 크게 1단계, 11~20페이지를 크게 2단계식으로 나누기 위해서입니다.
그런다음 *$show_page_num을 합니다.
2단계 일 때 시작값은 11페이지부터이기 때문입니다.
왜 뒤에 +1을 더하지 않는 이유는 아래 루프를 돌릴 때 1부터 돌리기 때문입니다.

그럼 이제 페이지 출력하는 부분을 알아보도록 합시다.

// 루프변수 $i의 초기값을 1로 지정해 놓습니다.
$i=1;

// 만약 현재 페이지가 10페이지보다 클 때, 즉 11, 12이상의 페이지일 때 이전 페이지 보기를 출력합니다.
if($page>$show_page_num)
{
$prev_page=$start_page-1;
echo"<a href=$PHP_SELF?page=$prev_page>[prev]</a>";
}

// 아래 while부분이 [1]~[10]등의 페이지를 출력하는 부분입니다.
while($i+$start_page<=$total_page&&$i<=$show_page_num)
{
$move_page=$i+$start_page;
if($page==$move_page) echo" $move_page ";
else echo"<a href=$PHP_SELF?page=$move_page> [$move_page] </a>";
$i++;
}

// 만약 전체 페이지 수가 지금 나타나 있는 페이지리스트보다 클 때 다음 페이지 보기를 출력합니다.
if($total_page>$move_page)
{$next_page=$move_page+1;
echo"<a href=$PHP_SELF?page=$next_page>[next]</a>";}

* 페이지 출력하는 알고리즘은 생각하기 나름입니다.
  그렇기 때문에 여기에는 제가 생각해서 사용하는 방법을 적었습니다.
  잘 연구해보시고 더 좋은 방법을 찾아서 자신만의 페이지 표시방법을 만들어 보세요.

그럼 이제 memo.html을 만들기 위한 기본지식과 구현방법에 대한 이야기는 끝났습니다.

실제 소스를 보도록 하겠습니다.
실제 소스에는 간단학 주석처리만 하겠습니다.

---- memo.php3 ----------------------------------------------------------------------
메모 리스트를 보여주고 글쓰기 폼을 보여줍니다.
-------------------------------------------------------------------------------------
<?
// lib.php3 파일을 불러 들입니다
require "lib.php3"

// 페이지 관련 변수값 정함
$temp=mysql_fetch_array(mysql_query("select count(*) from memo", $connect));
$total=$temp["count(*)"];
$page_num=10;  // 한 페이지당 출력될 갯수
if(!$page) $page=1; // 만약 $page라는 변수에 값이 없으면 임의로 1 페이지 입력
$start_num=($page-1)*$page_num; // 페이지 수에 따른 출력시 첫번째가 될 글의 번호 구함
$total_page=(int)(($total-1)/$page_num)+1; // 전체 페이지 구함

// MySQL DB로부터 자료를 가져옵니다.
$result=mysql_query("select * from $table_name limit $start_num,$page_num order by no desc ", $connect) or die(mysql_error());
?>
<!-- HTML 태그입니다. 표그리기와 윗줄의 제목출력입니다. -->
<div align=center>
<table border=1>
<tr>
   <td align=center>번호</td>
   <td align=center>이름</td>
   <td align=center>내용</td>
   <td align=center>날자</td>
</tr>
<!-- 표그리기와 윗줄 제목출력 끝입니다 -->

<?
  // 이제 $result 변수에 있는 자료를 출력하는 부분입니다.
  // $num은 실제적인 번호가 아닌 가상의 번호입니다.
  // 100개의 글이 있다면 100부터 1씩 빼서 보기좋은 번호를 매기기 위해서 사용합니다.
  $num=$total-($page-1)*$page_num;
  while($data=mysql_fetch_array($result))
  {
    // $data[reg_date]에 저장되어 있는 시간을 연월일로 바꾸는 부분입니다.
    $date=date("Y. m. d ");
    echo"<tr>
            <td align=center>$num</td>
            <td align=center>$data[name]</td>
            <td align=center>$data[memo]</td>
            <td align=center>$date</td>
          </tr>";
    // $num의 값을 1씩 빼주어야 합니다.
    $num--;
  }
?>

<!-- 이제 표그리기를 마무리 하고 글쓰기 폼을 출력합시다. -->
<form method=post action=reg_memo.php3>
<tr>
    <td align=center colspan=4>
       이름 : <input type=text name=name size=8 maxlength=8>
       내용 : <input type=text name=memo size=40 maxlength=255>
       <input type=submit value="입력">
    </td>
</tr>
</form>
</table>

<?
// 페이지를 출력하는 부분입니다
$show_page_num=10;
$start_page=(int)(($page-1)/$show_page_num)*$show_page_num;
  $i=1;
// 만약 현재 페이지가 10페이지보다 클 때, 즉 11, 12이상의 페이지일 때 이전 페이지 보기를 출력합니다.
If($page>$show_page_num)
{
  $prev_page=$start_page-1;
  echo"<a href=$PHP_SELF?page=$prev_page>[prev]</a>";
}

// 아래 while부분이 [1]~[10]등의 페이지를 출력하는 부분입니다.
while($i+$start_page<=$total_page&&$i<=$show_page_num)
{
  $move_page=$i+$start_page;
  if($page==$move_page) echo" $move_page ";
  else echo"<a href=$PHP_SELF?page=$move_page> [$move_page] </a>";
  $i++;
}

// 만약 전체 페이지 수가 지금 나타나 있는 페이지리스트보다 클 때 다음 페이지 보기를 출력합니다.
if($total_page>$move_page)
{$next_page=$move_page+1;
  echo"<a href=$PHP_SELF?page=$next_page>[next]</a>";}
?>
----------------------------------------------------------------------------------------------------------------