HTML을 이용한 공격 방지


HTML을 사용자가 이용하게 된다면 일부 불순한 생각을 가지신분이 자신의 실력을 돋보이게


하기위해서 종종 자바스크립트를 이용한 테러를 하게 됩니다.(무한 팝업 등)


그런 것을 방지하기위해서는 한가지 방법이 있습니다.


방법은 HTML과 자바스크립트를 무시하는 것입니다.


첫 번째 방법을 위해서는 PHP 내장함수중 strip_tags라는 함수를 알아야되는데 이 함수는


문자열에서 태그를 제거하는 함수입니다.


$stirng = strip_tags("<BR>PHP</BR>");


를 쓰면 $string에는 “PHP”만 들어가게 됩니다.


만약에


$stirng = strip_tags("<BR>PHP</BR>", "<BR>");


과 같이 두 번째 인자에 <BR>를 넣게되면 <BR>은 허용한다는 뜻입니다. 그래서


$string에는  “<BR>PHP</BR>”이 들어가게 됩니다.


이렇게 strip_tags를 써서 테러를 방지하는 방법이 있습니다.


그리고 두 번째 방법은 사용자가 입력한 값을 그대로 보여주는 것입니다.




소스 출처 : http://brown.ezphp.net/85



블로그 이미지

가카리

소프트웨어와 하드웨어 프로그래밍, 취업 및 직장생활 전문 블로그

Tag HTML, mysql, php

PHP에서 에러 메시지 처리 방법


에러가 발생하는 경우는


1. 사용자가 잘못된 입력으로 인한 에러

2. 데이터베이스 관련 에러


가 있습니다.


에러 메시지를 처리하는 방법은 한가지는 에러 메시지를 출력하고 이전 페이지로 돌아가는


방법과 나머지는 에러 메시지만 출력하고 PHP 스크립트의 실행을 종료하는 방법입니다.


이 두가지 모두 해결할 수 있는 방법을 위해서 하나의 함수를 만들어 보면


다음과 같이 만들 수 있습니다.


library.php파일


<?
function
ErrorMessage($message, $type = "on")
{
    echo "<script> alert('$message'); ";
   
if ($type == "on") echo " history.back(); ";
   
echo "</script>";
   
exit;
}
?>


사용자의 잘못된 입력으로 인한 에러 처리


1. 필수 항목 미입력 에러

2. 비밀번호 오류 에러


필수 항목 미입력 에러 처리는 방금 위에서 만든 함수를 사용하기위해서

include "library.php";을 추가한다음

다음과 같이 작성하면됩니다.

if(!$_POST[name]) ErrorMessage('이름을 입력하세요.');


이런식으로 심플하게 해결할 수 있습니다.


데이터베이스 관련 에러 처리


데이터베이스 관련 에러는 두가지가 있습니다.

1. 데이터베이스 연결 에러

2. 데이터베이스 쿼리 에러


데이터 베이스 연결 에러는


$conn=@mysql_connect("localhost","아이디" , "비밀번호") or die('데이터베이스 연결 불가‘);


이런식으로 골뱅이(@)를 추가하면 PHP 차원에서 에러 메시지를 출력하지 말고 우리가 지시한 메시지를 출력하기 위한 것입니다.


or die(메시지);를 통해서 에러가 발생하면 메시지를 띄우고 자동적으로 exit가 됩니다.


데이터베이스 쿼리 에러는


$result = mysql_query($query, $conn) or die(mysql_error());


처럼 mysql_error()함수를 이용하면 됩니다.


또는 사용자가 에러메시지를 지정하고 싶으면


include "library.php";을 추가한다음

$result = mysql_query($query, $conn) or ErrorMessage('글 목록 가져오기 실패‘, false);


아까 만든 ErrorMessage 함수를 이용하는 방법이 있겠습니다.


소스 출처 : http://brown.ezphp.net/85




블로그 이미지

가카리

소프트웨어와 하드웨어 프로그래밍, 취업 및 직장생활 전문 블로그

게시판 업그레이드 첫 번째에서 기존의 오름차순으로 인덱스가 정렬된 것을 내림차순으로 바꿔서 속도를 올려봤습니다.


하지만 이렇게 바꿔도 뒷페이지로 갈수록 느려진다는 단점이 있습니다.


쿼리를 하나로 말고 두 개로 쪼개서 해보는 방법으로 개선해 봅시다.


1. 100만개 레코드 중에서 50만 번째 레코드를 찾는다.

2. 찾은 레코드 번호부터 검색하여 10개의 글 목록을 가져온다.


이를 쿼리로 작성해보면 다음과 같습니다.


SELECT thread FROM threadboard ORDER BY thread DESC LIMIT 500000, 1;

위 쿼리의 값을 $thread 변수에 저장하면

SELECT * FROM threadboard WHERE thread <= $thread ORDER BY thread DESC LIMIT 10;

위를 통해서 10개의 글목록을 가져옵니다.


만약 기존의 list.php파일에서


$query = "SELECT * FROM $board ORDER BY thread LIMIT $no,$page_size";


쿼리문을 다음과 같이 두단계로 쪼개면

//1. 글 목록의 첫 번째 글 찾기

$query = "SELECT thread FROM $board ORDER BY thread ASC LIMIT $no, 1";

$result = mysql_query($query, $conn);

$row = mysql_fetch_row($result);

$start_thread = $row[0];


//2. 찾은 thread 값부터 10개의 글을 가져옴.

$query = "SELECT * FROM $board WHERE thread >= '$start_thread' ORDER BY thread ASC LIMIT 10";

$result = mysql_query($query, $conn);


실행화면 


뒤의 게시물을 보아도 속도가 20초가 걸리던 것이 1.54초로 줄어듭니다.



소스 출처 : http://brown.ezphp.net/85



블로그 이미지

가카리

소프트웨어와 하드웨어 프로그래밍, 취업 및 직장생활 전문 블로그

Tag mysql, php

이전에 만든 데이터 베이스에서 100만개의 게시글을 넣어봅시다.


db_info.php


<?

$board="threadboard";

$conn=@mysql_connect("localhost", "디비 아이디","디비 비번") or die('데이터베이스에 연결할 수 없습니다');
@
mysql_select_db("php_brain", $conn) or die('선택한 데이터베이스를 사용할 수 없습니다.');
@
mysql_query("set names euckr");

?>


다음 php파일은 100만개의 게시글을 올리는 소스입니다.


이 소스의 실행시간이 오래 걸리니까 좀 기다려야 할 겁니다.


mil_ins.php


<?
//스크립트 종료할때까지
set_time_limit
(0);

//데이터 베이스 연결하기
include "db_info.php";

// 글 등록에 대한 기본적인 정보
$name = "브라운";
$pass = "1234";
$email = "happybrown@naver.com";

if (ob_get_level() == 0) ob_start();

for ($i=1;$i<=1000000;$i++)
{
    $title = "$i 번째 테스트 게시물";
   
$content = "$i 번째 테스트 게시물 내용";

   
// 답글을 위해 thread 값은 index 값의 1000배
    $max_thread = $i * 1000;

   
$query = "INSERT INTO $board (id,thread,depth,name,pass,email,
    title,view,wdate,ip,content) "
;
   
$query .= "VALUES ('',$max_thread,0,'$name','$pass','$email',
    '$title',0, UNIX_TIMESTAMP(), '$REMOTE_ADDR','$content')"
;
   
$result=mysql_query($query, $conn);

   
if ($result) {
        $success++;
       
print("$i INSERT 성공<BR> ");
   
}
    else {
        $failure++;
       
print("$i INSERT <B>실패</B><BR> ");
   
}
   
   
// 이 프로그램이 시스템 자원을 많이 할당받는것을 막기위해
    // 10000번당 1초씩 쉬어줍니다.
    if(($i%10000) == 0) sleep(1);
}
//데이터베이스와의 연결 종료
mysql_close
($conn);
?>


만약에 위의 실행결과가
















이렇게 검은 화면과 함께 웹브라우저가 멈춘 듯 보이면 이것은 출력 값이 제대로 웹 브라우저


에 출력되지 않아서 생기는 현상입니다. 그 이유는 PHP가 PHP 버퍼에 출력 결과를 저장해두


고 웹 브라우저로 출력 값을 전송하지 않았기 때문에 발생합니다. 윈도우 기반의 웹서버의 경


우 이런경우가 많은데 이때 PHP의 flush()함수를 써서 버퍼의 쌓인 결과 값을 바로 내보내면


이런 현상이 없어질 것 입니다.


sleep()호출전에 flush()를 호출해보세요!









만약 이전의 게시판에서 id가 primary key로 되있는데 thread값 또한 유일한 값이므로


thread 값에도 인덱스를 설정해주는 것이 중요합니다. 만약에 UNIQUE로 설정해두면 실수로


중복되어 thread 값이 중복이 되는 것을 방지해줍니다.


인덱스 추가 방법


ALTER TABLE threadboard ADD UNIQUE thread_index(thread);


인덱스 삭제방법


 DROP index thread_index on threadboard;


인덱스를 사용하지 않았을 때


SELECT name FROM threadboard ORDER BY thread DESC LIMIT 500000, 10; 실행 결과




인덱스를 사용했을 때


SELECT name FROM threadboard ORDER BY thread DESC LIMIT 500000, 10; 실행 결과







속도를 올리는 방법 두번째

ORDER BY thread DESC는 느리다.


ASC가 DESC보다 빠르다. 이유는 가장 최근에 등록된 값이 큰 id와 thread 값을 가지고 있기 때문에 내림차순으로 정렬하려면 불러올 때 다시 거꾸로 뒤집어야한다.


ASC형 게시판을 만들기위해서 다음과 같은 두가지 방법을 사용함.


1. 글 번호를 음수로 하여 1000씩 빼가면서 등록

2. 글 번호를 9999999000과 같은 큰 값에서 1000씩 빼가면서 등록


본격적으로 음수를 사용하는 게시판을 만들기에 앞서 기존의 100만개 레코드를 음수로 변경하도록 합시다.


UPDATE threadboard SET thread = -1*thread;


여기서 thread 는 반드시 int 타입이어야합니다.


그리고 이전 강의때 만들었던 list.php에서


다음과 같이 쿼리문을 바꿔줘야합니다


원래 아래였는데

$query = "SELECT * FROM $board ORDER BY thread DESC LIMIT $no,$page_size";


이걸로 바꿔야합니다.

$query = "SELECT * FROM $board ORDER BY thread LIMIT $no,$page_size";


단순히 DESC만 지워졌습니다.


list.php 파일


<?
//데이터 베이스 연결하기
include "db_info.php";

###################################################################
# LIST 설정
# 1. 한 페이지에 보여질 게시물의 수
$page_size=10;

# 2. 페이지 나누기에 표시될 페이지의 수
$page_list_size = 10;

###################################################################
//$no 값이 안넘어 오거나 잘못된(음수)값이 넘어오는 경우 0으로 처리
$no = $_GET[no];
if (!$no || $no <0) $no=0;
###################################################################

// 데이터베이스에서 페이지의 첫번째 글($no)부터 $page_size 만큼의 글을 가져온다.
$query = "SELECT * FROM $board ORDER BY thread LIMIT $no,$page_size";
$result = mysql_query($query, $conn);

// 총 게시물 수 를 구한다.
//count 를 통해 구할 수 있는데 count(항목) 과 같은 방법으로 사용한다. * 는 모든 항목을 뜻한다.
//총 해당 항목의 값을 가지는 게시물의 개수가 얼마인가를 묻는것이다.
//따라서 전체 글수가 된다. count(id) 와 같은 방법도 가능하지만
//이례적으로 count(*)가 조금 빠르다. 일반적으로는 * 가 느리다.
$result_count=mysql_query("SELECT count(*) FROM $board",$conn);
$result_row=mysql_fetch_row($result_count);
$total_row = $result_row[0];

//결과의 첫번째 열이 count(*) 의 결과다.
###################################################################
# 총 페이지 계산
if ($total_row <= 0) $total_row = 0; // 총게시물의 값이 없거나 할경우 기본값으로 세팅
// 총게시물에 1을 뺀뒤 페이지 사이즈로 나누고 소수점이하를 버린다.

$total_page = floor(($total_row - 1) / $page_size);
# 총페이지는 총 게시물의 수를 $page_size 로 나누면 알수있다.
# 총 게시물이 12개(1을 빼서 11이된다)이고 페이지 사이즈가 10이라면 결과는 1.1 이 나올것이다.
# 1.1 라는 페이지수는 한 페이지를 다 표시하고도 글이 더 남아있다는 뜻이다.
# 따라서 실제의 페이지수는 2가된다. 한 페이지는 2개의 글만 표시될것이다.
# 그러나 내림을 해주는 이유는 페이지수가 0부터 시작하기 때문이다. 따라서 1은 두번째 페이지이다.
# 총 게시물에 1을 빼주는 이유는 10페이지가 되면 10/10 = 1 이기 때문이다.
# 앞에서도 말했지만 1은 2번째 페이지를 뜻한다.
# 그러나 총게시물이 10개인 경우 한페이지에 모두 출력이 되어야 한다.
# 그래서 1을 빼서 10개인 경우 (10-1) / 10 = 0.9 로 한페이지에 출력하게 한다.
# 글이 0개가 있는 경우는 결과가 -1 이 되지만 -1은 무시된다.
# ( floor 는 내림을 하는 수학함수이다.)

###################################################################
# 현재 페이지 계산
$current_page = floor($no/$page_size);
# $no 을 통해서 페이지의 첫번째 글이 몇번째 글인지 전달된다.
# 따라서 페이지 사이즈로 나누면 현재가 몇번째 페이지인지 알수있다.
# $no 이 10이고 페이지사이즈가 10 이라면 결과는 1이다. 앞서 페이지는 0부터
# 시작이라고 했으니 두번째 페이지임을 나타낸다.
# 그렇다면 $no 이 11이라면 1.1 이 되어버린다. 11번째 글도 두번째 페이지에 존재하므로 0.1
# 은 무의미하니 버린다.
# 그런데 $no 이란 값이 $page_size 만큼씩 증가되는 값이기때문에 (0,10,20,30 과 같은
# 등차수열) 내림을 하는것 또한 무의미하다.
# 그러나 내림을 하는 이유는 $no 값에 11과 같은 값이 들어와도 제대로 출력되기를 바라는
# 마음에서 해놓은것이다.
?>
<html>
<head>
<title>계층형 게시판</title>
<style>
<!--
td
{ font-size : 9pt; }
A:link { font : 9pt; color : black; text-decoration : none;
font-family: 굴림; font-size : 9pt;
}
A:visited { text-decoration : none; color : black;
font-size : 9pt;
}
A:hover { text-decoration : underline; color : black;
font-size : 9pt;
}
-->
</style>
</head>
<body topmargin=
0 leftmargin=0 text=#464646>
<center>
<BR>
<!-- 게시물 리스트를 보이기 위한 테이블 -->
<table width=
580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
<!-- 리스트 타이틀 부분 -->
<tr height=
20 bgcolor=#999999>
    <td width=30 align=center>
        <font color=white>번호</font>
    </td>
    <td width=
370 align=center>
        <font color=white>제 목</font>
    </td>
    <td width=
50 align=center>
        <font color=white>글쓴이</font>
    </td>
    <td width=
60 align=center>
        <font color=white>날 짜</font>
    </td>
    <td width=
40 align=center>
        <font color=white>조회수</font>
    </td>
</tr>
<!-- 리스트 타이틀 끝 -->
<!-- 리스트 부분 시작 -->
<?
    while($row=mysql_fetch_array($result))
    {
?>
<!-- 행 시작 -->
<tr>
    <!-- 번호 -->
    <td height=
20 bgcolor=white align=center>
        <a href=
"read.php?id=<?=$row[id]?>&no=<?=$no?>">
       
<?=$row[id]?></a>
    </td>
    <!-- 번호 끝 -->
    <!-- 제목 -->
    <td height=
20 bgcolor=white>&nbsp;
       
<?
       
if ($row[depth] >0)
           
echo "<img height=1 width=" . $row[depth]*7 . ">└";//이부분은 답변을 달때 들여쓰기를 위한 곳. 7씩 늘어나게 들여쓰기함
        ?>
        <a href="read.php?id=<?=$row[id]?>&no=<?=$no?>">
       
<?=strip_tags($row[title]);?></a>
    </td>
    <!-- 제목 끝 -->
    <!-- 이름 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black>
        <a href=
"mailto:<?=$row[email]?>"><?=$row[name]?></a>
        </font>
    </td>
    <!-- 이름 끝 -->
    <!-- 날짜 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
date("Y-m-d",$row[wdate])//여기서는 date 함수를 써서 유닉스 타임 스탬프 값을 날짜 형식으로 출력함. ?></font>
    </td>
    <!-- 날짜 끝 -->
    <!-- 조회수 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
$row[view]?></font>
    </td>
<!-- 조회수 끝 -->
</tr>
<!-- 행 끝 -->
<?
    } // end While

//데이터베이스와의 연결을 끝는다.

mysql_close
($conn);
?>
</table>
<!-- 게시물 리스트를 보이기 위한 테이블 끝-->
<!-- 페이지를 표시하기 위한 테이블 -->
<table border=
0>
<tr>
    <td width=
600 height=20 align=center rowspan=4>
    <font color=gray>
    &nbsp;
<?
###################################################################
# 페이지 리스트
# 페이지 리스트의 첫번째로 표시될 페이지가 몇번째 페이지인지 구하는 부분이다.

$start_page = (int)($current_page / $page_list_size)
    *
$page_list_size;

#현재 페이지를 페이지 리스트 수로 나누면 현재 페이지가 몇번째 페이지리스트에 있는지 알게된다.
# 이또한 0을 기준으로 하기에 형변환(타입 캐스팅)을 해주었다.
# 형변환은 앞 강좌에서 배웠지만 위의 나누어지는 수가 1.2와 같이 유리수로 표시되기때문에
# int(정수) 형으로 형변환을 하게되면 소수점자리가 사라지게 된다.
# 즉, 위에서 사용한 floor 랑 같은 효과를 하게 되는 것이다.
# 여기에 floor 함수를 취하거나 위의 floor 를 형변환을 해도 상관없다.
# 페이지 리스트의 마지막 페이지가 몇번째 페이지인지 구하는 부분이다.

$end_page = $start_page + $page_list_size - 1;
if ($total_page <$end_page) $end_page = $total_page;

# 보여주는 페이지 리스트중에서 마지막 페이지가 되는 경우는 두가지이다.
# 1. 페이지가 페이지리스트 크기보다 더 많이 남아있을때
# 10개씩 뿌려주는데 총 11페이지가 존재한다면 11페이지는 두번째 목록페이지에 뿌려진다.
# 그렇다면 마지막 페이지 리스트는 10페이지 즉, 첫번째 페이지 + 9 번째 페이지이다.
# 2. 10개씩 뿌려주는데 5페이지 밖에 없다면?
# 마지막 리스트 페이지는 5 페이지가 된다.

###################################################################
# 이전 페이지 리스트 보여주기
# 페이지 리스트가 10인데 13번째 페이지에 있다면 두번째 목록페이지를 보고 있는것이다.
# 이전 목록페이지로 가고 싶을 때 사용한다.
# 이전 페이지 리스트가 필요할때는 페이지 리스트의 첫 페이지가 페이지 리스트 수보다 클때다.
# 페이지가 적어도 페이지 리스트 수보다는 커야 이전 페이지 리스트가 존재할테니까 말이다.
# 페이지 리스트의 수가 10인데 총 5페이지밖에 없다면 이전 페이지 리스트는 존재하지 않는다.

if ($start_page >= $page_list_size) {

# 이전 페이지 리스트값은 첫번째 페이지 리스트에서 뒤로 리스트의 수만큼 이동하면된다.
# $page_size 를 곱해주는 이유는 글번호로 표시하기 위해서이다.

    $prev_list = ($start_page - 1)*$page_size;
   
echo "<a href="$PHP_SELF?no=$prev_list">◀</a> ";
}
# 페이지 리스트를 출력
for ($i=$start_page;$i <= $end_page;$i++) {
    $page=$page_size*$i; // 페이지값을 no 값으로 변환.
    $page_num = $i+1; // 실제 페이지 값이 0부터 시작하므로 표시할때는 1을 더해준다.
   
   
if ($no!=$page){ //현재 페이지가 아닐 경우만 링크를 표시
        echo "<a href="$PHP_SELF?no=$page">";
   
}

    echo " $page_num "; //페이지를 표시

    if ($no!=$page){
        echo "</a>";
   
}
}
# 다음 페이지 리스트가 필요할때는 총 페이지가 마지막 리스트보다 클 때이다.
# 리스트를 다 뿌리고도 더 뿌려줄 페이지가 남았을때 다음 버튼이 필요할 것이다.
if($total_page >$end_page)
{
    # 다음 페이지 리스트는 마지막 리스트 페이지보다 한 페이지 뒤로 이동하면 된다.
    $next_list = ($end_page + 1)* $page_size;
   
echo "<a href=$PHP_SELF?no=$next_list>▶</a><p>";
}
?>
</font>
</td>
</tr>
</table>
<a href=write.php>글쓰기</a>
</center>
</body>
</html>


실행 화면


다음은 글 삽입을 담당하는 insert.php 파일입니다.

insert.php


글 삽입시 다음과 같은 알고리즘을 적용하게 됩니다.


1. 글 번호의 최소값을 구한다.

2. 구해진 최소값을 이용하여 일반 글의 번호를 구한다.

3. 일반 글의 번호에 1000을 뺀다.



따라서 글쓰기 소스는 다음과 같이 변경됩니다.


$query = "SELECT max(thread) FROM $board";

$max_thread_result = mysql_query($query, $conn);

$max_thread_fetch = mysql_fetch_row($max_thread_result);

$max_thread = ceil($max_thread_fetch[0]/1000)*1000+1000;


에서


$query = "SELECT min(thread) FROM $board";

$max_thread_result = mysql_query($query, $conn);

$max_thread_fetch = mysql_fetch_row($max_thread_result);

$max_thread = floor($max_thread_fetch[0]/1000)*1000-1000;


로 바뀝니다.


실행 화면






답변달기 파일 수정


답변 달기 알고리즘


1. 부모 글의 번호로부터 일반 글의 번호를 찾는다.

2. 일반 글에 1000을 더해서 바로 아래의 일반 글 번호를 계산한다.

3. 부모 글과 아래의 일반 글 사이에 존재하는 답변 글의 번호에 1씩 더한다.

4. 비워진 자리에 답변 글을 등록한다.



기존의 답변 달기


$prev_parent_thread = ceil($_POST[parent_thread]/1000)*1000 - 1000;//ceil는 올림함수인것을 잊지말자.


$query = "UPDATE $board SET thread=thread-1 WHERE

        thread > $prev_parent_thread and thread < $_POST[parent_thread]";

        $update_thread = mysql_query($query, $conn);


에서


$prev_parent_thread = floor($_POST[parent_thread]/1000)*1000 + 1000;//floor는 내림함수인것을 잊지말자.


        $query = "UPDATE $board SET thread=thread+1 WHERE

        thread < $prev_parent_thread and thread > $_POST[parent_thread]";

        $query .= " ORDER BY thread DESC";

        $update_thread = mysql_query($query, $conn);


($_POST[parent_thread]+1)로 바꿔야됨. 원래 -1임




insert_reply.php


<?
    //데이터 베이스 연결하기
    include "db_info.php";

   
   
$prev_parent_thread = floor($_POST[parent_thread]/1000)*1000 + 1000;//floor는 내림함수인것을 잊지말자.

    //원본글보다는 작고 위값보다는 큰 글들의 thread 값을 모두 1씩 낮춘다.
    //만약 부모글이 2000이면 prev_parent_thread는 1000이므로 2000> x >1000 인 x값을 모두 -1을 한다.
    //만약 부모글이 1950이면 prev_parent_thread는 1000이므로 1950> x >1000 인 x값을 모두 -1을 한다.
    $query = "UPDATE $board SET thread=thread+1 WHERE
    thread <$prev_parent_thread and thread >$_POST[parent_thread]"
;
   
$query .= " ORDER BY thread DESC";
   
$update_thread = mysql_query($query, $conn);

   
//원본글보다는 1작은 값으로 답글을 등록한다.
    //원본글의 바로 밑에 등록되게 된다.
    //depth는 원본글의 depth + 1 이다. 원본글이 3(이글도 답글이군)이면 답글은 4가된다.
    $query = "INSERT INTO $board (thread,depth,name,pass,email";
   
$query .= ",title,view,wdate,ip,content)";
   
$query .= " VALUES ('" . ($_POST[parent_thread]+1) . "'";
   
$query .= ",'" . ($parent_depth+1) ."','$_POST[name]','$_POST[pass]','$_POST[email]'";
   
$query .= ",'$_POST[title]',0, UNIX_TIMESTAMP(),'$_SERVER[REMOTE_ADDR]'";
   
$query .= ",'$_POST[content]')";
   
$result=mysql_query($query, $conn);

   
//데이터베이스와의 연결 종료
    mysql_close($conn);

   
// 새 글 쓰기인 경우 리스트로..
    echo ("<meta http-equiv='Refresh' content='1; URL=list.php'>");
?>
<center>
<font size=
2>정상적으로 저장되었습니다.</font>


실행화면




마지막으로 글 읽기 페이지를 수저해봅시다.


글 읽기의 경우 윗글 아랫글을 수정해야하고 하단에 위치한 관련 글 목록을 새로운 알고리즘에 맞게 수정해야합니다.


 read.php파일에서


기존 값

$query = "SELECT id, name, title FROM $board

WHERE thread > $row[thread] and depth=0 LIMIT 1";

$query=mysql_query($query, $conn);

$up_id=mysql_fetch_array($query);


$query = "SELECT id, name, title FROM $board WHERE

thread < $row[thread] and depth=0  ORDER BY thread DESC LIMIT 1";

$query=mysql_query($query, $conn);

$down_id=mysql_fetch_array($query);

//-- 중략--

$thread_end = ceil($row[thread]/1000)*1000;

$thread_start = $thread_end - 1000;


$query = "SELECT * FROM $board WHERE thread <= $thread_end and

thread > $thread_start ORDER BY thread DESC";

$result = mysql_query($query, $conn);


수정된 값


$query = "SELECT id, name, title FROM $board

WHERE thread < $row[thread] and depth=0 ORDER BY thread DESC LIMIT 1";

$query=mysql_query($query, $conn);

$up_id=mysql_fetch_array($query);


$query = "SELECT id, name, title FROM $board WHERE

thread > $row[thread] and depth=0  LIMIT 1";

$query=mysql_query($query, $conn);

$down_id=mysql_fetch_array($query);


//-- 중략--


$thread_end = floor($row[thread]/1000)*1000;

$thread_start = floor($row[thread]/1000)*1000+1000;


$query = "SELECT * FROM $board WHERE thread >= $thread_end and

thread < $thread_start ORDER BY thread ";

$result = mysql_query($query, $conn);




read.php 소스


<?
//데이터 베이스 연결하기
include "db_info.php";

$no = $_GET[no];
$id = $_GET[id];

// 조회수 업데이트
$query = "UPDATE $board SET view=view+1 WHERE id=$_GET[id]";
$result=mysql_query($query, $conn);

// 글 정보 가져오기
$query = "SELECT * FROM $board WHERE id=$_GET[id]";
$result=mysql_query($query, $conn);
$row=mysql_fetch_array($result);
?>
<html>
<head>
<title>계층형 게시판</title>
<style>
<!--
td
{ font-size : 9pt; }
A:link { font : 9pt; color : black; text-decoration : none;
font-family: 굴림; font-size : 9pt;
}
A:visited { text-decoration : none; color : black;
font-size : 9pt;
}
A:hover { text-decoration : underline; color : black;
font-size : 9pt;
}
-->
</style>
</head>
<body topmargin=
0 leftmargin=0 text=#464646>
<center>
<BR>
<table width=
580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
<tr>
    <td height=
20 colspan=4 align=center bgcolor=#999999>
        <font color=white><B><?=strip_tags($row[title]);?>
        </B></font>
    </td>
</tr>
<tr>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>글쓴이</td>
    <td width=240 bgcolor=white><?=$row[name]?></td>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>이메일</td>
    <td width=240 bgcolor=white><?=$row[email]?></td>
</tr>
<tr>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>
        날&nbsp;&nbsp;&nbsp;짜</td><td width=240 bgcolor=white>
       
<?=date("Y-m-d", $row[wdate])?></td>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>조회수</td>
    <td width=240 bgcolor=white><?=$row[view]?></td>
</tr>
<tr>
    <td bgcolor=white colspan=
4 style="word-break:break-all;">
        <font color=black>
        <pre><?=
strip_tags($row[content]);?></pre>
        </font>
    </td>
</tr>
<!-- 기타 버튼 들 -->
<tr>
    <td colspan=
4 bgcolor=#999999>
    <table width=100%>
    <tr>
        <td width=
280 align=left height=20>
            <a href=
list.php?no=<?=$no?>><font color=white>
           
[목록보기]</font></a>
            <a href=reply.php?id=
<?=$id?>><font color=white>
           
[답글달기]</font></a>
            <a href=write.php><font color=white>
           
[글쓰기]</font></a>
            <a href=edit.php?id=
<?=$id?>><font color=white>
           
[수정]</font></a>
            <a href=predel.php?id=
<?=$id?>><font color=white>
           
[삭제]</font></a>
        </td>
    </tr>
    </table>
    </td>
</tr>
</table>

<table width=
580 bgcolor=white style="border-bottom-width:1;
border-bottom-style:solid;border-bottom-color:cccccc;"
>
<?
// 현재 글보다 thread 값이 큰 글 중 가장 작은 것의 id를 가져온다. depth가 0인것은 글만 찾기위해서임 depth가 1이상이면 그건  RE: 글이다.
$query = "SELECT id, name, title FROM $board
WHERE thread <$row[thread] and depth=0 ORDER BY thread DESC LIMIT 1"
;
$query=mysql_query($query, $conn);
$up_id=mysql_fetch_array($query);

if ($up_id[id]) // 이전 글이 있을 경우
{
    echo "<tr><td width=500 align=left height=25>";
   
echo "<a href=read.php?id=$up_id[id]>△ $up_id[title]</a></td>
    <td align=right>$up_id[name]</td></tr>"
;
}

// 현재 글보다 thread 값이 작은 글 중 가장 큰 것의 id를 가져온다. 오름차순으로하고 thread <$row[thread]로 해도 같다.
$query = "SELECT id, name, title FROM $board WHERE
thread >$row[thread] and depth=0  LIMIT 1"
;//원래 ORDER BY thread DESC 있던것 없어짐
$query=mysql_query($query, $conn);
$down_id=mysql_fetch_array($query);

if ($down_id[id])
{
    echo "<tr><td width=500 align=left height=25>";
   
echo "<a href=read.php?id=$down_id[id]>▽ $down_id[title]</a>
    </td><td align=right>$down_id[name]</td></tr>"
;
}
?>
</table>
<BR>
<?
//리스트 출력을 위해 thread를 계산한다.
//출력될 리스트는 글 전체 리스트가 아니라
//1000의 배수인 새글과 이를 포함한 답변글들의 리스트이다.
//답변글이 없는 경우 원본글만 리스트에 나오고
//답변글이 있으면 답변글 모두가 다 나오게된다.
//현재 글이 답변글이어도 새글부터 전체 답변글까지 나온다.
//그럴려면 1000~2000 과 같이 새글사이에 글들을 모두 뿌려주면 된다.

//만약 원본글이 삭제됬다면 답변글만 있다.
//만약 답변글이 1999라면 1999/1000=1.999 에서 올림을 하면 2가 됨 그리고 *1000을 하면 2000이 됨.
//즉 2000>= x >1000 의 범위의 값을 모두 찾아야됨.
$thread_end = floor($row[thread]/1000)*1000;
$thread_start = floor($row[thread]/1000)*1000+1000;

$query = "SELECT * FROM $board WHERE thread >= $thread_end and
thread <$thread_start ORDER BY thread "
;
$result = mysql_query($query, $conn);
?>
<!-- 게시물 리스트를 보이기 위한 테이블 -->
<table width=
580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
<!-- 리스트 타이틀 부분 -->
<tr height=
20 bgcolor=#999999>
    <td width=30 align=center>
        <font color=white>번호</font>
    </td>
    <td width=
370 align=center>
        <font color=white>제 목</font>
    </td>
    <td width=
50 align=center>
        <font color=white>글쓴이</font>
    </td>
    <td width=
60 align=center>
        <font color=white>날 짜</font>
    </td>
    <td width=
40 align=center>
        <font color=white>조회수</font>
    </td>
</tr>
<!-- 리스트 타이틀 끝 -->
<!-- 리스트 부분 시작 -->
<?
    while($row=mysql_fetch_array($result))
    {
?>
<!-- 행 시작 -->
<tr>
<!-- 번호 -->
    <td height=
20 bgcolor=white align=center>
        <a href=
"read.php?id=<?=$row[id]?>&no=<?=$no?>"><!-- =$noecho $no와 같은 의미 -->
       
<?=$row[id]?></a>
    </td>
    <!-- 번호 끝 -->
    <!-- 제목 -->
    <td height=
20 bgcolor=white>&nbsp;
       
<? //depth 값을 통해서 들여쓰기를 한다. 투명이미지의 가로사이즈를 늘이는 방법
        if ($row[depth] >0)
           
echo "<img src=img/dot.gif height=1 width=" .
           
$row[depth]*7 . ">->";
       
?>
        <a href="read.php?id=<?=$row[id]?>&no=<?=$no?>"><!-- =$noecho $no와 같은 의미 -->
       
<?=strip_tags($row[title], '<b><i>');?></a>
    </td>
    <!-- 제목 끝 -->
    <!-- 이름 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black>
        <a href=
"mailto:<?=$row[email]?>"><?=$row[name]?></a>
        </font>
    </td>
    <!-- 이름 끝 -->
    <!-- 날짜 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
date("Y-m-d",$row[wdate])?></font>
    </td>
    <!-- 날짜 끝 -->
    <!-- 조회수 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
$row[view]?></font>
    </td>
<!-- 조회수 끝 -->
</tr>
<!-- 행 끝 -->
<?
    } // end While
mysql_close
($conn);
?>
</center>
</body>
</html>



실행 화면




지금까지 thread 항목이 오름차순으로 된 것을 속도를 빠르게 하기위해서 내림차순으로 바꿨습니다.



소스 출처 : http://brown.ezphp.net/85



블로그 이미지

가카리

소프트웨어와 하드웨어 프로그래밍, 취업 및 직장생활 전문 블로그

Tag mysql, php

계층형 게시판이란?


다음과 같이 구성되있는 게시판을 뜻합니다. 즉 답변을 달 수 있는 게시판입니다.


번호

깊이

제목

종류

300

0

세 번째 글

새 글

200

0

두 번째 글

새 글

199

1

 RE : 두 번째 글 첫 번째 답변

답변 글

198

2

 RE : 두 번째 글의 두 번째 답변

답변 글

197

1

RE : 두 번째 글의 세 번째 답변

답변 글

100

0

첫 번째 글

새 글



테이블 설계


데이터베이스 스키마를 다음과 같이 작성할 예정입니다.


항목

영어 항목

변수형

크기

비고

글의 번호

id

int

11

글의 번호는 숫자

내부 번호

thread

int

11

일정 값으로 증가하는 값

글의 깊이

depth

int

11

들여쓰기를 위한 값, 답글의 갯수

글쓴이

name

varchar

20

varchar는 많이 길지 않은 문자열

이메일 주소

email

varchar

30

 

글의 비밀번호

pass

varchar

10

 

글의 제목

title

varchar

70

 

글의 내용

content

text

 

충분히 긴 문자열

글 쓴 날짜

wdate

int

 

시간을 UnixTime으로 저장

IP 주소

ip

varchar

16

 

조회 수

view

int

11

 


유닉스 타임이란

1970년 1우러 1일부터 몇초가 흘렀느냐 하는 값


테이블 생성문 만들기


CREATE TABLE threadboard(
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
thread int
(11) UNSIGNED NOT NULL,
depth int
(11) UNSIGNED NOT NULL DEFAULT '0',
name varchar
(20) NOT NULL,
email varchar
(30),
pass varchar
(10) NOT NULL,
title varchar
(70) NOT NULL,
content text
NOT NULL,
wdate int
(11) NOT NULL,
ip varchar
(16) NOT NULL,
VIEW int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (id)
)
ENGINE=MyISAM DEFAULT CHARSET=euckr;



테이블 접근 계정 추가 구문 php_brain 대신에 데이터베이스명 쓰면됨.


grant all privileges on php_brain.guestbook to 'webauth' identified by 'webauth';

flush privileges;


위 구문은 모든 권한을 webauth라는 ID와 webauth라는 비번을 쓰는 사람에게 줌.


grant select on php_brain.* to 'webauth' identified by 'webauth';

flush privileges;


위 구문은 select 권한을 webauth라는 ID와 webauth라는 비번을 쓰는 사람에게 줌.


데이터베이스 연결을 위한 db_info.php 파일


<?
    $board="threadboard";//이 변수는 테이블명 이렇게 하면 sql문을 쓸 때 편함
   
$conn=mysql_connect("localhost","webauth","webauth");
   
mysql_select_db("php_brain", $conn);
   
mysql_query('set names euckr');
?>



글을 쓰기 위한 form인 write.php 파일


<html>
<head>

<title>
초 허접 게시판</title>
<style>

<!--
td { font-size : 9pt; }
A:link { font : 9pt; color : black; text-decoration : none;
font-family: 굴림; font-size : 9pt; }
A:visited { text-decoration : none; color : black;
font-size : 9pt; }
A:hover { text-decoration : underline; color : black;
font-size : 9pt;}
-->
</style>
</head>

<body
topmargin=0 leftmargin=0 text=#464646>
<center>

<BR>

<!-- 입력된 값을 다음 페이지로 넘기기 위해 FORM을 만든다. -->
<form
action=insert.php method=post>
<table
width=580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
<tr>

    <td height=20 align=center bgcolor=#999999>
        <font color=white><B>글 쓰 기</B></font>
    </td>
</tr>
<!-- 입력 부분 -->
<tr>

    <td bgcolor=white>&nbsp;
<table>

<tr>

    <td width=60 align=left >이름</td>
    <td align=left >
        <INPUT type=text name=name size=20 maxlength=10>
    </td>
</tr>

<tr>

    <td width=60 align=left >이메일</td>
    <td align=left >
        <INPUT type=text name=email size=20 maxlength=25>
    </td>
</tr>

<tr>

    <td width=60 align=left >비밀번호</td>
    <td align=left >
        <INPUT type=password name=pass size=8 maxlength=8>
        (수정,삭제시 반드시 필요)
   
</td>
</tr>

<tr>

    <td width=60 align=left >제 목</td>
    <td align=left >
        <INPUT type=text name=title size=60 maxlength=35>
    </td>
</tr>

<tr>

    <td width=60 align=left >내용</td>
    <td align=left >
        <TEXTAREA name=content cols=65 rows=15></TEXTAREA>
    </td>
</tr>

<tr>

    <td colspan=10 align=center>
        <INPUT type=submit value="글 저장하기">
        &nbsp;&nbsp;
        <INPUT type=reset value="다시 쓰기">
        &nbsp;&nbsp;
        <INPUT type=button value="되돌아가기" onclick="history.back(-1)">
    </td>
</tr>
</TABLE>
</td>
</tr>
<!-- 입력 부분 끝 -->
</table>
</form>
</center>
</body>
</html>


동작화면







글쓰기 반영 insert.php


<?
//데이터 베이스 연결하기
include "db_info.php";

//Thread 값을 계산한다. 여기서 max는 테이블에서 가장 큰 Thread 값을 가져오라는 뜻이다.
$query = "SELECT max(thread) FROM $board";
$max_thread_result = mysql_query($query, $conn);
$max_thread_fetch = mysql_fetch_row($max_thread_result);


//만약에 2000번의 글이 삭제되고 1999번만 있다면?
//그럴 경우 1999/1000을 한다음에 올림을 한뒤 1000을 곱하면 2000이 된다.
//그리고 그값에 1000을 더하면 3000이 되서 새로 입력한 글의 Thread는 3000이 된다.
$max_thread = ceil($max_thread_fetch[0]/1000)*1000+1000;


//UNIX_TIMESTAMP는 유닉스 시간을 되돌려주는 MySQL 내장함수입니다.
//$_SERVER[REMOTE_ADDR]은 IP주소를 가져오는 PHP 변수
$query = "INSERT INTO $board (thread, depth, name, pass, email,
title, view, wdate, ip, content)
VALUES ($max_thread, 0, '$_POST[name]', '$_POST[pass]',
'$_POST[email]', '$_POST[title]', 0,
UNIX_TIMESTAMP(), '$_SERVER[REMOTE_ADDR]', '$_POST[content]')"
;
$result=mysql_query($query, $conn);

//데이터베이스와의 연결 종료
mysql_close
($conn);

// 새 글 쓰기인 경우 리스트로..
echo
("<meta http-equiv='Refresh' content='1; URL=list.php'>");
?>
<center>
<font size=
2>정상적으로 저장되었습니다.</font>


동작화면




글 목록을 출력하는 list.php 파일


<?
//데이터 베이스 연결하기
include "db_info.php";

###################################################################
# LIST 설정
# 1. 한 페이지에 보여질 게시물의 수
$page_size=10;

# 2. 페이지 나누기에 표시될 페이지의 수
$page_list_size = 10;

###################################################################
//$no 값이 안넘어 오거나 잘못된(음수)값이 넘어오는 경우 0으로 처리
$no = $_GET[no];
if (!$no || $no <0) $no=0;
###################################################################

// 데이터베이스에서 페이지의 첫번째 글($no)부터 $page_size 만큼의 글을 가져온다.
$query = "SELECT * FROM $board ORDER BY thread DESC LIMIT $no,$page_size";
$result = mysql_query($query, $conn);

// 총 게시물 수 를 구한다.
//count 를 통해 구할 수 있는데 count(항목) 과 같은 방법으로 사용한다. * 는 모든 항목을 뜻한다.
//총 해당 항목의 값을 가지는 게시물의 개수가 얼마인가를 묻는것이다.
//따라서 전체 글수가 된다. count(id) 와 같은 방법도 가능하지만
//이례적으로 count(*)가 조금 빠르다. 일반적으로는 * 가 느리다.
$result_count=mysql_query("SELECT count(*) FROM $board",$conn);
$result_row=mysql_fetch_row($result_count);
$total_row = $result_row[0];

//결과의 첫번째 열이 count(*) 의 결과다.
###################################################################
# 총 페이지 계산
if ($total_row <= 0) $total_row = 0; // 총게시물의 값이 없거나 할경우 기본값으로 세팅
// 총게시물에 1을 뺀뒤 페이지 사이즈로 나누고 소수점이하를 버린다.

$total_page = floor(($total_row - 1) / $page_size);
# 총페이지는 총 게시물의 수를 $page_size 로 나누면 알수있다.
# 총 게시물이 12개(1을 빼서 11이된다)이고 페이지 사이즈가 10이라면 결과는 1.1 이 나올것이다.
# 1.1 라는 페이지수는 한 페이지를 다 표시하고도 글이 더 남아있다는 뜻이다.
# 따라서 실제의 페이지수는 2가된다. 한 페이지는 2개의 글만 표시될것이다.
# 그러나 내림을 해주는 이유는 페이지수가 0부터 시작하기 때문이다. 따라서 1은 두번째 페이지이다.
# 총 게시물에 1을 빼주는 이유는 10페이지가 되면 10/10 = 1 이기 때문이다.
# 앞에서도 말했지만 1은 2번째 페이지를 뜻한다.
# 그러나 총게시물이 10개인 경우 한페이지에 모두 출력이 되어야 한다.
# 그래서 1을 빼서 10개인 경우 (10-1) / 10 = 0.9 로 한페이지에 출력하게 한다.
# 글이 0개가 있는 경우는 결과가 -1 이 되지만 -1은 무시된다.
# ( floor 는 내림을 하는 수학함수이다.)

###################################################################
# 현재 페이지 계산
$current_page = floor($no/$page_size);
# $no 을 통해서 페이지의 첫번째 글이 몇번째 글인지 전달된다.
# 따라서 페이지 사이즈로 나누면 현재가 몇번째 페이지인지 알수있다.
# $no 이 10이고 페이지사이즈가 10 이라면 결과는 1이다. 앞서 페이지는 0부터
# 시작이라고 했으니 두번째 페이지임을 나타낸다.
# 그렇다면 $no 이 11이라면 1.1 이 되어버린다. 11번째 글도 두번째 페이지에 존재하므로 0.1
# 은 무의미하니 버린다.
# 그런데 $no 이란 값이 $page_size 만큼씩 증가되는 값이기때문에 (0,10,20,30 과 같은
# 등차수열) 내림을 하는것 또한 무의미하다.
# 그러나 내림을 하는 이유는 $no 값에 11과 같은 값이 들어와도 제대로 출력되기를 바라는
# 마음에서 해놓은것이다.
?>
<html>
<head>
<title>계층형 게시판</title>
<style>
<!--
td
{ font-size : 9pt; }
A:link { font : 9pt; color : black; text-decoration : none;
font-family: 굴림; font-size : 9pt;
}
A:visited { text-decoration : none; color : black;
font-size : 9pt;
}
A:hover { text-decoration : underline; color : black;
font-size : 9pt;
}
-->
</style>
</head>
<body topmargin=
0 leftmargin=0 text=#464646>
<center>
<BR>
<!-- 게시물 리스트를 보이기 위한 테이블 -->
<table width=
580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
<!-- 리스트 타이틀 부분 -->
<tr height=
20 bgcolor=#999999>
    <td width=30 align=center>
        <font color=white>번호</font>
    </td>
    <td width=
370 align=center>
        <font color=white>제 목</font>
    </td>
    <td width=
50 align=center>
        <font color=white>글쓴이</font>
    </td>
    <td width=
60 align=center>
        <font color=white>날 짜</font>
    </td>
    <td width=
40 align=center>
        <font color=white>조회수</font>
    </td>
</tr>
<!-- 리스트 타이틀 끝 -->
<!-- 리스트 부분 시작 -->
<?
    while($row=mysql_fetch_array($result))
    {
?>
<!-- 행 시작 -->
<tr>
    <!-- 번호 -->
    <td height=
20 bgcolor=white align=center>
        <a href=
"read.php?id=<?=$row[id]?>&no=<?=$no?>">
       
<?=$row[id]?></a>
    </td>
    <!-- 번호 끝 -->
    <!-- 제목 -->
    <td height=
20 bgcolor=white>&nbsp;
       
<?
       
if ($row[depth] >0)
           
echo "<img height=1 width=" . $row[depth]*7 . ">└";//이부분은 답변을 달때 들여쓰기를 위한 곳. 7씩 늘어나게 들여쓰기함
        ?>
        <a href="read.php?id=<?=$row[id]?>&no=<?=$no?>">
       
<?=strip_tags($row[title]);?></a>
    </td>
    <!-- 제목 끝 -->
    <!-- 이름 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black>
        <a href=
"mailto:<?=$row[email]?>"><?=$row[name]?></a>
        </font>
    </td>
    <!-- 이름 끝 -->
    <!-- 날짜 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
date("Y-m-d",$row[wdate])//여기서는 date 함수를 써서 유닉스 타임 스탬프 값을 날짜 형식으로 출력함. ?></font>
    </td>
    <!-- 날짜 끝 -->
    <!-- 조회수 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
$row[view]?></font>
    </td>
<!-- 조회수 끝 -->
</tr>
<!-- 행 끝 -->
<?
    } // end While

//데이터베이스와의 연결을 끝는다.

mysql_close
($conn);
?>
</table>
<!-- 게시물 리스트를 보이기 위한 테이블 끝-->
<!-- 페이지를 표시하기 위한 테이블 -->
<table border=
0>
<tr>
    <td width=
600 height=20 align=center rowspan=4>
    <font color=gray>
    &nbsp;
<?
###################################################################
# 페이지 리스트
# 페이지 리스트의 첫번째로 표시될 페이지가 몇번째 페이지인지 구하는 부분이다.

$start_page = (int)($current_page / $page_list_size)
    *
$page_list_size;

#현재 페이지를 페이지 리스트 수로 나누면 현재 페이지가 몇번째 페이지리스트에 있는지 알게된다.
# 이또한 0을 기준으로 하기에 형변환(타입 캐스팅)을 해주었다.
# 형변환은 앞 강좌에서 배웠지만 위의 나누어지는 수가 1.2와 같이 유리수로 표시되기때문에
# int(정수) 형으로 형변환을 하게되면 소수점자리가 사라지게 된다.
# 즉, 위에서 사용한 floor 랑 같은 효과를 하게 되는 것이다.
# 여기에 floor 함수를 취하거나 위의 floor 를 형변환을 해도 상관없다.
# 페이지 리스트의 마지막 페이지가 몇번째 페이지인지 구하는 부분이다.

$end_page = $start_page + $page_list_size - 1;
if ($total_page <$end_page) $end_page = $total_page;

# 보여주는 페이지 리스트중에서 마지막 페이지가 되는 경우는 두가지이다.
# 1. 페이지가 페이지리스트 크기보다 더 많이 남아있을때
# 10개씩 뿌려주는데 총 11페이지가 존재한다면 11페이지는 두번째 목록페이지에 뿌려진다.
# 그렇다면 마지막 페이지 리스트는 10페이지 즉, 첫번째 페이지 + 9 번째 페이지이다.
# 2. 10개씩 뿌려주는데 5페이지 밖에 없다면?
# 마지막 리스트 페이지는 5 페이지가 된다.

###################################################################
# 이전 페이지 리스트 보여주기
# 페이지 리스트가 10인데 13번째 페이지에 있다면 두번째 목록페이지를 보고 있는것이다.
# 이전 목록페이지로 가고 싶을 때 사용한다.
# 이전 페이지 리스트가 필요할때는 페이지 리스트의 첫 페이지가 페이지 리스트 수보다 클때다.
# 페이지가 적어도 페이지 리스트 수보다는 커야 이전 페이지 리스트가 존재할테니까 말이다.
# 페이지 리스트의 수가 10인데 총 5페이지밖에 없다면 이전 페이지 리스트는 존재하지 않는다.

if ($start_page >= $page_list_size) {

# 이전 페이지 리스트값은 첫번째 페이지 리스트에서 뒤로 리스트의 수만큼 이동하면된다.
# $page_size 를 곱해주는 이유는 글번호로 표시하기 위해서이다.

    $prev_list = ($start_page - 1)*$page_size;
   
echo "<a href="$PHP_SELF?no=$prev_list">◀</a> ";
}
# 페이지 리스트를 출력
for ($i=$start_page;$i <= $end_page;$i++) {
    $page=$page_size*$i; // 페이지값을 no 값으로 변환.
    $page_num = $i+1; // 실제 페이지 값이 0부터 시작하므로 표시할때는 1을 더해준다.
   
   
if ($no!=$page){ //현재 페이지가 아닐 경우만 링크를 표시
        echo "<a href="$PHP_SELF?no=$page">";
   
}

    echo " $page_num "; //페이지를 표시

    if ($no!=$page){
        echo "</a>";
   
}
}
# 다음 페이지 리스트가 필요할때는 총 페이지가 마지막 리스트보다 클 때이다.
# 리스트를 다 뿌리고도 더 뿌려줄 페이지가 남았을때 다음 버튼이 필요할 것이다.
if($total_page >$end_page)
{
    # 다음 페이지 리스트는 마지막 리스트 페이지보다 한 페이지 뒤로 이동하면 된다.
    $next_list = ($end_page + 1)* $page_size;
   
echo "<a href=$PHP_SELF?no=$next_list>▶</a><p>";
}
?>
</font>
</td>
</tr>
</table>
<a href=write.php>글쓰기</a>
</center>
</body>
</html>






동작화면



이번에는 글을 읽었을 때 화면을 구현합니다. read.php 파일


<?
//데이터 베이스 연결하기
include "db_info.php";

$no = $_GET[no];
$id = $_GET[id];

// 조회수 업데이트
$query = "UPDATE $board SET view=view+1 WHERE id=$_GET[id]";
$result=mysql_query($query, $conn);

// 글 정보 가져오기
$query = "SELECT * FROM $board WHERE id=$_GET[id]";
$result=mysql_query($query, $conn);
$row=mysql_fetch_array($result);
?>
<html>
<head>
<title>계층형 게시판</title>
<style>
<!--
td
{ font-size : 9pt; }
A:link { font : 9pt; color : black; text-decoration : none;
font-family: 굴림; font-size : 9pt;
}
A:visited { text-decoration : none; color : black;
font-size : 9pt;
}
A:hover { text-decoration : underline; color : black;
font-size : 9pt;
}
-->
</style>
</head>
<body topmargin=
0 leftmargin=0 text=#464646>
<center>
<BR>
<table width=
580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
<tr>
    <td height=
20 colspan=4 align=center bgcolor=#999999>
        <font color=white><B><?=strip_tags($row[title]);?>
        </B></font>
    </td>
</tr>
<tr>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>글쓴이</td>
    <td width=240 bgcolor=white><?=$row[name]?></td>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>이메일</td>
    <td width=240 bgcolor=white><?=$row[email]?></td>
</tr>
<tr>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>
        날&nbsp;&nbsp;&nbsp;짜</td><td width=240 bgcolor=white>
       
<?=date("Y-m-d", $row[wdate])?></td>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>조회수</td>
    <td width=240 bgcolor=white><?=$row[view]?></td>
</tr>
<tr>
    <td bgcolor=white colspan=
4 style="word-break:break-all;">
        <font color=black>
        <pre><?=
strip_tags($row[content]);?></pre>
        </font>
    </td>
</tr>
<!-- 기타 버튼 들 -->
<tr>
    <td colspan=
4 bgcolor=#999999>
    <table width=100%>
    <tr>
        <td width=
280 align=left height=20>
            <a href=
list.php?no=<?=$no?>><font color=white>
           
[목록보기]</font></a>
            <a href=reply.php?id=
<?=$id?>><font color=white>
           
[답글달기]</font></a>
            <a href=write.php><font color=white>
           
[글쓰기]</font></a>
            <a href=edit.php?id=
<?=$id?>><font color=white>
           
[수정]</font></a>
            <a href=predel.php?id=
<?=$id?>><font color=white>
           
[삭제]</font></a>
        </td>
    </tr>
    </table>
    </td>
</tr>
</table>

<table width=
580 bgcolor=white style="border-bottom-width:1;
border-bottom-style:solid;border-bottom-color:cccccc;"
>
<?
// 현재 글보다 thread 값이 큰 글 중 가장 작은 것의 id를 가져온다. depth가 0인것은 글만 찾기위해서임 depth가 1이상이면 그건  RE: 글이다.
$query = "SELECT id, name, title FROM $board
WHERE thread >$row[thread] and depth=0 LIMIT 1"
;
$query=mysql_query($query, $conn);
$up_id=mysql_fetch_array($query);

if ($up_id[id]) // 이전 글이 있을 경우
{
    echo "<tr><td width=500 align=left height=25>";
   
echo "<a href=read.php?id=$up_id[id]>△ $up_id[title]</a></td>
    <td align=right>$up_id[name]</td></tr>"
;
}

// 현재 글보다 thread 값이 작은 글 중 가장 큰 것의 id를 가져온다. 오름차순으로하고 thread <$row[thread]로 해도 같다.
$query = "SELECT id, name, title FROM $board WHERE
thread <$row[thread] and depth=0  ORDER BY thread DESC LIMIT 1"
;
$query=mysql_query($query, $conn);
$down_id=mysql_fetch_array($query);

if ($down_id[id])
{
    echo "<tr><td width=500 align=left height=25>";
   
echo "<a href=read.php?id=$down_id[id]>▽ $down_id[title]</a>
    </td><td align=right>$down_id[name]</td></tr>"
;
}
?>
</table>
<BR>
<?
//리스트 출력을 위해 thread를 계산한다.
//출력될 리스트는 글 전체 리스트가 아니라
//1000의 배수인 새글과 이를 포함한 답변글들의 리스트이다.
//답변글이 없는 경우 원본글만 리스트에 나오고
//답변글이 있으면 답변글 모두가 다 나오게된다.
//현재 글이 답변글이어도 새글부터 전체 답변글까지 나온다.
//그럴려면 1000~2000 과 같이 새글사이에 글들을 모두 뿌려주면 된다.

//만약 원본글이 삭제됬다면 답변글만 있다.
//만약 답변글이 1999라면 1999/1000=1.999 에서 올림을 하면 2가 됨 그리고 *1000을 하면 2000이 됨.
//즉 2000>= x >1000 의 범위의 값을 모두 찾아야됨.
$thread_end = ceil($row[thread]/1000)*1000;
$thread_start = $thread_end - 1000;

//아래와 같은 쿼리문을 쓸때 단점은 답글이 999개가되면 999개를 출력하게 된다는점이 단점.
$query = "SELECT * FROM $board WHERE thread <= $thread_end and
thread >$thread_start ORDER BY thread DESC"
;
$result = mysql_query($query, $conn);
?>
<!-- 게시물 리스트를 보이기 위한 테이블 -->
<table width=
580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
<!-- 리스트 타이틀 부분 -->
<tr height=
20 bgcolor=#999999>
    <td width=30 align=center>
        <font color=white>번호</font>
    </td>
    <td width=
370 align=center>
        <font color=white>제 목</font>
    </td>
    <td width=
50 align=center>
        <font color=white>글쓴이</font>
    </td>
    <td width=
60 align=center>
        <font color=white>날 짜</font>
    </td>
    <td width=
40 align=center>
        <font color=white>조회수</font>
    </td>
</tr>
<!-- 리스트 타이틀 끝 -->
<!-- 리스트 부분 시작 -->
<?
    while($row=mysql_fetch_array($result))
    {
?>
<!-- 행 시작 -->
<tr>
<!-- 번호 -->
    <td height=
20 bgcolor=white align=center>
        <a href=
"read.php?id=<?=$row[id]?>&no=<?=$no?>"><!-- =$noecho $no와 같은 의미 -->
       
<?=$row[id]?></a>
    </td>
    <!-- 번호 끝 -->
    <!-- 제목 -->
    <td height=
20 bgcolor=white>&nbsp;
       
<? //depth 값을 통해서 들여쓰기를 한다. 투명이미지의 가로사이즈를 늘이는 방법
        if ($row[depth] >0)
           
echo "<img src=img/dot.gif height=1 width=" .
           
$row[depth]*7 . ">->";
       
?>
        <a href="read.php?id=<?=$row[id]?>&no=<?=$no?>"><!-- =$noecho $no와 같은 의미 -->
       
<?=strip_tags($row[title], '<b><i>');?></a>
    </td>
    <!-- 제목 끝 -->
    <!-- 이름 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black>
        <a href=
"mailto:<?=$row[email]?>"><?=$row[name]?></a>
        </font>
    </td>
    <!-- 이름 끝 -->
    <!-- 날짜 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
date("Y-m-d",$row[wdate])?></font>
    </td>
    <!-- 날짜 끝 -->
    <!-- 조회수 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
$row[view]?></font>
    </td>
<!-- 조회수 끝 -->
</tr>
<!-- 행 끝 -->
<?
    } // end While
mysql_close
($conn);
?>
</center>
</body>
</html>










동작화면


글 수정하기 edit.php 파일


동작화면을 보면 글쓰기와 매우 유사함.


그리고 글 저장하기 버튼을 누르면 update.php파일이 실행됨.


<html>
<head>

<title>
초 허접 게시판</title>
<style>

<!--
td { font-size : 9pt; }
A:link { font : 9pt; color : black; text-decoration : none;
font-family: 굴림; font-size : 9pt; }
A:visited { text-decoration : none; color : black;
font-size : 9pt; }
A:hover { text-decoration : underline; color : black;
font-size : 9pt;}
-->
</style>
</head>

<body
topmargin=0 leftmargin=0 text=#464646>
<center>

<BR>

<!-- 입력된 값을 다음 페이지로 넘기기 위해 FORM을 만든다. -->
<form
action=update.php?id=<?=$_GET[id]?> method=post>
<table
width=580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
<tr>

    <td height=20 align=center bgcolor=#999999>
        <font color=white><B>글 수 정 하 기</B></font>
    </td>
</tr>
<
?
//데이터 베이스 연결하기
include
"db_info.php";

// 먼저 쓴 글의 정보를 가져온다.
$result=mysql_query
("SELECT * FROM $board WHERE id=$_GET[id]", $conn);
$row=mysql_fetch_array
($result);
?
>
<!-- 입력 부분 -->
<tr>

<td
bgcolor=white>&nbsp;
<table>

<tr>

<td
width=60 align=left >이름</td>
<td
align=left >
<INPUT
type=text name=name size=20 value=<?=$row[name]?>>
</td>
</tr>

<tr>

<td
width=60 align=left >이메일</td>
<td
align=left >
<INPUT
type=text name=email size=20 value=<?=$row[email]?>>
</td>
</tr>

<tr>

<td
width=60 align=left >비밀번호</td>
<td
align=left >
<INPUT
type=password name=pass size=8> (비밀번호가 맞아야 수정가능)
</td>
</tr>

<tr>

<td
width=60 align=left >제 목</td>
<td
align=left >
<INPUT
type=text name=title size=60 value=<?=$row[title]?>>
</td>
</tr>

<tr>

<td
width=60 align=left >내용</td>
<td
align=left >
<TEXTAREA
name=content cols=65 rows=15><?=$row[content]?></TEXTAREA>
</td>
</tr>

<tr>

<td
colspan=10 align=center>
<INPUT
type=submit value="글 저장하기">
&nbsp;&nbsp;
<INPUT
type=reset value="다시 쓰기">
&nbsp;&nbsp;
<INPUT
type=button value="되돌아가기" onclick="history.back(-1)">
</td>
</tr>
</TABLE>
</td>
</tr>
<!-- 입력 부분 끝 -->
</table>
</form>
</center>
</body>
</html>











동작화면


글을 실제로 수정하는 update.php 파일




<?
    //데이터 베이스 연결하기
    include "db_info.php";

   
// 글의 비밀번호를 가져온다.
    $result=mysql_query("SELECT pass FROM $board WHERE id='$_GET[id]'", $conn);
   
$row=mysql_fetch_array($result);

   
//입력된 값과 비교한다.
    if ($_POST[pass]==$row[pass]) { //비밀번호가 일치하는 경우
        $query = "UPDATE $board SET name='$_POST[name]', email='$_POST[email]',
        title='$_POST[title]', content='$_POST[content]' WHERE id=$_GET[id]"
;
       
$result=mysql_query($query, $conn);
   
}
    else { // 비밀번호가 일치하지 않는 경우
        echo ("
        <script>
        alert('비밀번호가 틀립니다.');
        history.go(-1);
        </script>
        "
);
       
exit;
   
}
    //데이터베이스와의 연결 종료
    mysql_close($conn);
   
//수정하기인 경우 수정된 글로..
    echo ("<meta http-equiv='Refresh' content='3; URL=read.php?id=$_GET[id]'>");
?>
<center>
<font size=
2>정상적으로 수정되었습니다.</font>



동작화면 




글 삭제할 때 비밀번호를 물어보는 predel.php 파일


글 삭제시 비밀번호를 물어보는 form인 predel파일입니다.




<html>
<head>

<title>
초 허접 게시판</title>
<style>

<!--
td {font-size : 9pt;}
A:link {font : 9pt;color : black;text-decoration : none;fontfamily
: 굴림;font-size : 9pt;}
A:visited {text-decoration : none; color : black; font-size : 9pt;}
A:hover {text-decoration : underline; color : black; font-size : 9pt;}
-->
</style>
</head>

<body
topmargin=0 leftmargin=0 text=#464646>
<center>

<BR>

<!-- 입력된 값을 다음 페이지로 넘기기 위해 FORM을 만든다. -->
<form
action=del.php?id=<?=$_GET[id]?> method=post>
<table
width=300 border=0 cellpadding=2 cellspacing=1
bgcolor=#777777>
<tr>

<td
height=20 align=center bgcolor=#999999>
<font
color=white><B>비 밀 번 호 확 인</B></font>
</td>
</tr>

<tr>

<td
align=center >
<font
color=white><B>비밀번호 : </b>
<INPUT
type=password name=pass size=8>
<INPUT
type=submit value="확 인">
<INPUT
type=button value="취 소" onclick="history.back(-1)">
</td>
</tr>
</table>



동작화면



실제 삭제 작업을 수행하는 del.php


실제로 비밀번호가 맞는지 확인하고 글을 삭제하는 쿼리문을 실행하는 파일입니다.


<?
    //데이터 베이스 연결하기
    include "db_info.php";

   
$query = "SELECT pass FROM $board WHERE id=$_GET[id]";
   
$result=mysql_query($query, $conn);
   
$row=mysql_fetch_array($result);

   
if ($_POST[pass]==$row[pass] )
    {
        $query = "DELETE FROM $board WHERE id=$_GET[id] ";
       
$result=mysql_query($query, $conn);
   
}
    else
    {
        echo ("
        <script>
        alert('비밀번호가 틀립니다.');
        history.go(-1);
        </script>
        "
);
       
exit;
   
}
?>
<center>
<meta http-equiv=
'Refresh' content='3; URL=list.php'>
<FONT size=
2 >삭제되었습니다.</font>


동작화면


답글다는 기능을 가진 reply.php


답글 달기는 글쓰기와 거의 유사하고 약간의 소스코드만 추가됨. 답글을 달기위한 form만 주어지며 실질적인 데이터베이스 작업은 insert_reply.php에서 수행

글을 저장하면 insert_reply.php가 실행된다.



<?

include "db_info.php";

$query = "SELECT * FROM $board WHERE id='$_GET[id]'";//부모글을 가져옴.

$parent_result = mysql_query($query, $conn);

$parent_row = mysql_fetch_array($parent_result);

$parent_title = "RE:" . $parent_row[title];//RE : 를 앞에 붙여줌

//$parent_content = "\n>" . str_replace("\n", "\n>", $parent_row[content]);

$parent_content = "\n>" . str_replace("\n", "\n>", $parent_row[content]);

//부모글의 내용에  > 를 붙여줌.

//str_replace(A, B, C) C안에 있는 문자중에서 A를 찾아서 B로 바꾸는 역할

?>

<html>

<head>

<title>계층형 게시판</title>

<style>

<!--

td { font-size : 9pt; }

A:link { font : 9pt; color : black; text-decoration : none;

font-family: 굴림; font-size : 9pt; }

A:visited { text-decoration : none; color : black;

font-size : 9pt; }

A:hover { text-decoration : underline; color : black;

font-size : 9pt;}

-->

</style>

</head>

<body topmargin=0 leftmargin=0 text=#464646>

<center>

<BR>

<!-- 입력된 값을 다음 페이지로 넘기기 위해 FORM을 만든다. -->

<form action=insert_reply.php method=post>

<input type=hidden name=parent_depth value=<?=$parent_row[depth]?>>

<input type=hidden name=parent_thread value=<?=$parent_row[thread]?>>

<table width=580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>

<tr>

        <td height=20 align=center bgcolor=#999999>

        <font color=white><B>답변 달기</B></font>

        </td>

</tr>

<!-- 입력 부분 -->

<tr>

        <td bgcolor=white>&nbsp;

        <table>

        <tr>

        <td width=60 align=left >이름</td>

        <td align=left >

        <INPUT type=text name=name size=20 maxlength=10>

        </td>

        </tr>

        <tr>

        <td width=60 align=left >이메일</td>

        <td align=left >

        <INPUT type=text name=email size=20 maxlength=25>

        </td>

        </tr>

        <tr>

        <td width=60 align=left >비밀번호</td>

        <td align=left >

        <INPUT type=password name=pass size=8 maxlength=8>

        (수정,삭제시 반드시 필요)

        </td>

        </tr>

        <tr>

        <td width=60 align=left >제 목</td>

        <td align=left >

        <INPUT type=text name=title size=60 maxlength=35

        value="<?=$parent_title?>">

        </td>

        </tr>

        <tr>

        <td width=60 align=left >내용</td>

        <td align=left >

        <TEXTAREA name=content cols=65 rows=15><?=$parent_content?></TEXTAREA>

        </td>

        </tr>

        <tr>

        <td colspan=10 align=center>

        <INPUT type=submit value="글 저장하기">

        &nbsp;&nbsp;

        <INPUT type=reset value="다시 쓰기">

        &nbsp;&nbsp;

        <INPUT type=button value="되돌아가기"

        onclick="history.back(-1)">

        </td>

        </tr>

        </TABLE>

        </td>

</tr>

<!-- 입력 부분 끝 -->

</table>

</center>

</body>

</html>















동작화면


실제적인 답글을 위한 쿼리문을 처리하는 insert_reply.php


번호

깊이

제목

종류

3000

0

3번째 글

새 글

2000

0

2번째 글

새 글

1000

0

1번째 글

새 글



에서 만약에 두 번째 글에 답변을 달면


번호

깊이

제목

종류

3000

0

3번째 글

새 글

2000

0

2번째 글

새 글

1999

1

2번째 글의 1번째 답변

답변 글

1000

0

1번째 글

새 글


또 답변을 달면



번호

깊이

제목

종류

3000

0

3번째 글

새 글

2000

0

2번째 글

새 글

1999

1

2번째 글의 2번째 답변

답변 글

1998

2

2번째 글의 1번째 답변

 

1000

0

1번째 글

새 글


이런 식으로 새로운 답변이 높은 번호를 같게 되는 시스템을 구현할 예정입니다.

즉 내부적으로 번호가 업데이트가 되야합니다.



또한 답변에 대한 답변이 또 달릴 경우


번호

깊이

제목

종류

3000

0

3번째 글

새 글

2000

0

2번째 글

새 글

1999

1

2번째 글의 2번째 답변

답변 글

1998

2

2번째 글의 2번째 답변의 답변

 

1997

1

2번째 글의 답변

 

1000

0

1번째 글

새 글


위와 같은 테이블로 구현이 됩니다.


그럼 insert_reply.php를 볼까요?


<?
    //데이터 베이스 연결하기
    include "db_info.php";

   
   
$prev_parent_thread = ceil($_POST[parent_thread]/1000)*1000 - 1000;//ceil는 올림함수인것을 잊지말자.

    //원본글보다는 작고 위값보다는 큰 글들의 thread 값을 모두 1씩 낮춘다.
    //만약 부모글이 2000이면 prev_parent_thread는 1000이므로 2000> x >1000 인 x값을 모두 -1을 한다.
    //만약 부모글이 1950이면 prev_parent_thread는 1000이므로 1950> x >1000 인 x값을 모두 -1을 한다.
    $query = "UPDATE $board SET thread=thread-1 WHERE
    thread >$prev_parent_thread and thread <$_POST[parent_thread]"
;
   
$update_thread = mysql_query($query, $conn);

   
//원본글보다는 1작은 값으로 답글을 등록한다.
    //원본글의 바로 밑에 등록되게 된다.
    //depth는 원본글의 depth + 1 이다. 원본글이 3(이글도 답글이군)이면 답글은 4가된다.
    $query = "INSERT INTO $board (thread,depth,name,pass,email";
   
$query .= ",title,view,wdate,ip,content)";
   
$query .= " VALUES ('" . ($_POST[parent_thread]-1) . "'";
   
$query .= ",'" . ($parent_depth+1) ."','$_POST[name]','$_POST[pass]','$_POST[email]'";
   
$query .= ",'$_POST[title]',0, UNIX_TIMESTAMP(),'$_SERVER[REMOTE_ADDR]'";
   
$query .= ",'$_POST[content]')";
   
$result=mysql_query($query, $conn);

   
//데이터베이스와의 연결 종료
    mysql_close($conn);

   
// 새 글 쓰기인 경우 리스트로..
    echo ("<meta http-equiv='Refresh' content='3; URL=list.php'>");
?>
<center>
<font size=
2>정상적으로 저장되었습니다.</font>



동작화면


계층형 게시판은 아직까지는 이해하기가 쉽네요.


다음에는 이 계층형 게시판의 문제점을 파악하고 업그레이드 시켜보는 것으로 하겠습니다.


소스 출처 : http://brown.ezphp.net/85







블로그 이미지

가카리

소프트웨어와 하드웨어 프로그래밍, 취업 및 직장생활 전문 블로그

이번에는 PHP와 MYSQL을 이용한 간단한 게시판을 만들기입니다.



데이터베이스 항목


항목

영어 항목

변수형

크기

비고

글의 번호

id

int

11

글의 번호는 숫자

글쓴이

name

varchar

20

255자이하의 길지않은 문자열

이메일 주소

email

varchar

30

 

글의 비밀번호

pass

varchar

12

 

글의 제목

title

varchar

70

 

글의 내용

content

text

 

긴 문자열

글쓴 날짜

wdate

datetime

 

날짜 및 시간

IP 주소

ip

varchar

15

 

조회 수

view

int

11

 


테이블 만드는 sql 구문


CREATE TABLE board (

id int(11) unsigned NOT NULL auto_increment,

name varchar(20) NOT NULL,

email varchar(30) NULL,

pass varchar(12) NOT NULL,

title varchar(70) NOT NULL,

content text NOT NULL,

wdate datetime NOT NULL,

ip varchar(15) NOT NULL,

view int(11) NOT NULL DEFAULT 0,

PRIMARY KEY (id)

);


데이터 베이스 접속을 위한 db_info.php


<?
    $conn = mysql_connect("localhost", "아이디", "패스워드");
   
mysql_select_db("디비이름",$conn);
?>



write.php

cellpadding 옵션 변경전


변경후


cellspacing 변경 전


변경 후


write.php 파일

<html>
<head>

<title>
초 허접 게시판</title>
<style>

<!--
td { font-size : 9pt; }
A:link { font : 9pt; color : black; text-decoration : none;
font-family : 굴림; font-size : 9pt; }
A:visited { text-decoration : none; color : black; font-size : 9pt; }
A:hover { text-decoration : underline; color : black;
font-size : 9pt; }
-->
</style>
</head>

<body
topmargin=0 leftmargin=0 text=#464646>
<center>

<BR>

<!-- 입력된 값을 다음 페이지로 넘기기 위해 FORM을 만든다. -->
<form
action=insert.php method=post>
<table
width=580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
    <tr>
        <td height=20 align=center bgcolor=#999999>
        <font color=white><B>글 쓰 기</B></font>
        </td>
    </tr>
    <!-- 입력 부분 -->
    <tr>
        <td bgcolor=white>&nbsp;
        <table>
            <tr>
                <td width=60 align=left >이름</td>
                <td align=left >
                    <INPUT type=text name=name size=20 maxlength=10>
                </td>
            </tr>
            <tr>
                <td width=60 align=left >이메일</td>
                <td align=left >
                    <INPUT type=text name=email size=20 maxlength=25>
                </td>
            </tr>
            <tr>
                <td width=60 align=left >비밀번호</td>
                <td align=left >
                    <INPUT type=password name=pass size=8 maxlength=8>
                    (수정,삭제시 반드시 필요)
               
</td>
            </tr>
            <tr>
                <td width=60 align=left >제 목</td>
                <td align=left >
                    <INPUT type=text name=title size=60 maxlength=35>
                </td>
            </tr>
            <tr>
                <td width=60 align=left >내용</td>
                <td align=left >
                    <TEXTAREA name=content cols=65 rows=15></TEXTAREA>
                </td>
            </tr>
            <tr>
                <td colspan=10 align=center>
                    <INPUT type=submit value="글 저장하기">
                    &nbsp;&nbsp;
                    <INPUT type=reset value="다시 쓰기">
                    &nbsp;&nbsp;
                    <INPUT type=button value="되돌아가기"
                   
onclick="history.back(-1)"> <!--버튼이 클릭되었을때 발생하는 이벤트로 자바스크립트를 실행함. 이렇게 하면 바로 이전페이지로 감-->
                </td>
            </tr>
        </TABLE>
</td>
</tr>
<!-- 입력 부분 끝 -->
</table>
</form>
</center>
</body>
</html>
</html>


글 저장하기 버튼을 누르면



다음의 화면이 나온다.


insert.php를 실행하게 되는데 다음과 같다.



<?
    //데이터 베이스 연결하기
    include "db_info.php";

   
$id = $_GET[id];
   
$name = $_POST[name];
   
$email = $_POST[email];
   
$pass = $_POST[pass];
   
$title = $_POST[title];
   
$content = $_POST[content];
   
$REMOTE_ADDR = $_SERVER[REMOTE_ADDR];

   
$query = "INSERT INTO board
    (id, name, email, pass, title, content, wdate, ip, view)
    VALUES ('', '$name', '$email', '$pass', '$title',
    '$content', now(), '$REMOTE_ADDR', 0)"
;
   
$result=mysql_query($query, $conn) or die(mysql_error());

   
//데이터베이스와의 연결 종료
    mysql_close($conn);

   
// 새 글 쓰기인 경우 리스트로..
    echo ("<meta http-equiv='Refresh' content='1; URL=list.php'>");
   
//1초후에 list.php로 이동함.
?>
<center>
<font size=
2>정상적으로 저장되었습니다.</font>


여기서 echo ("<meta http-equiv='Refresh' content='1; URL=list.php'>");


이것 빼고는 다 익숙한데 이것은 1초후에 list.php로 이동하라는 뜻이다.



edit.php 파일  글 읽기 페이지의 글 수정하기 버튼을 통해서 글 수정하기 페이지로 이동한다. 이때 읽고있던 글의 id값을 넘겨준다.


<html>
<head>
<title>초 허접 게시판</title>
<style>
<!--
td
{ font-size : 9pt; }
A:link { font : 9pt; color : black; text-decoration : none;
font-family: 굴림; font-size : 9pt;
}
A:visited { text-decoration : none; color : black;
font-size : 9pt;
}
A:hover { text-decoration : underline; color : black;
font-size : 9pt;
}
-->
</style>
</head>

<body topmargin=
0 leftmargin=0 text=#464646>
<center>
<BR>
<!-- 입력된 값을 다음 페이지로 넘기기 위해 FORM을 만든다. -->
<form action=update.php?id=
<?=$_GET[id]?> method=post>
<table width=
580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
    <tr>
        <td height=
20 align=center bgcolor=#999999>
            <font color=white><B>글 수 정 하 기</B></font>
        </td>
    </tr>
<?
    //데이터 베이스 연결하기
    include "db_info.php";
   
$id = $_GET[id];
   
$no = $_GET[no];

   
// 먼저 쓴 글의 정보를 가져온다.
    $result=mysql_query("SELECT * FROM board WHERE id=$id", $conn);
   
$row=mysql_fetch_array($result);
?>
<!-- 입력 부분 -->
    <tr>
        <td bgcolor=white>&nbsp;
        <table>
            <tr>
                <td width=
60 align=left >이름</td>
                <td align=left >
                    <INPUT type=text name=name size=
20
                    value=
"<?=$row[name]?>">
                </td>
            </tr>
            <tr>
                <td width=
60 align=left >이메일</td>
                <td align=left >
                    <INPUT type=text name=email size=
20
                    value=
"<?=$row[email]?>">
                </td>
            </tr>
            <tr>
                <td width=
60 align=left >비밀번호</td>
                <td align=left >
                    <INPUT type=password name=pass size=
8>
                   
(비밀번호가 맞아야 수정가능)
                </td>
            </tr>
            <tr>
                <td width=
60 align=left >제 목</td>
                <td align=left >
                    <INPUT type=text name=title size=
60
                    value=
"<?=$row[title]?>">
                </td>
            </tr>
            <tr>
                <td width=
60 align=left >내용</td>
                <td align=left >
                    <TEXTAREA name=content cols=
65 rows=15><?=$row[content]?></TEXTAREA>
                </td>
            </tr>
            <tr>
                <td colspan=
10 align=center>
                    <INPUT type=submit value=
"글 저장하기">
                    &nbsp;&nbsp;
                    <INPUT type=
reset value="다시 쓰기">
                    &nbsp;&nbsp;
                    <INPUT type=button value=
"되돌아가기"
                    onclick=
"history.back(-1)">
                </td>
            </tr>
            </TABLE>
        </td>
    </tr>
<!-- 입력 부분 끝 -->
</table>
</form>
</center>
</body>
</html>



동작 화면



글 수정 반영하기


글 수정 반영하기전에 비밀번호를 데이터베이스와 비교하여 글쓴이가 맞는지 확인한다.

그리고나서 쿼리문을 이용하여 데이터 베이스를 수정한다.


update.php


<?
    //데이터 베이스 연결하기
    include "db_info.php";
   
$id = $_GET[id];
   
$name = $_POST[name];
   
$pass = $_POST[pass];
   
$email = $_POST[email];
   
$title = $_POST[title];
   
$content = $_POST[content];

   
// 글의 비밀번호를 가져온다.
    $query = "SELECT pass FROM board WHERE id=$id";
   
$result=mysql_query($query, $conn);
   
$row=mysql_fetch_array($result);

   
//입력된 값과 비교한다.
    if ($pass==$row[pass]) { //비밀번호가 일치하는 경우
        $query = "UPDATE board SET name='$name', email='$email',
        title='$title', content='$content' WHERE id=$id"
;//업데이트 쿼리문
        $result=mysql_query($query, $conn);
   
}
    else { // 비밀번호가 일치하지 않는 경우
        echo ("
        <script>
        alert('비밀번호가 틀립니다.');
        history.go(-1);
        </script>
        "
);
       
exit;//반드시 exit를 써줘야됨. 안그러면 아래의 코드가 실행이됨.
    }

    //데이터베이스와의 연결 종료
    mysql_close($conn);

   
//수정하기인 경우 수정된 글로..
    echo ("<meta http-equiv='Refresh' content='1;
    URL=read.php?id=$id'>"
);
?>
<center>
<font size=
2>정상적으로 수정되었습니다.</font>


실행 화면


글 읽기 read.php


<html>
<head>
<title>초 허접 게시판</title>
<style>
<!--
td
{font-size : 9pt;}
A:link {font : 9pt; color : black; text-decoration : none;
font-family : 굴림; font-size : 9pt;
}
A:visited {text-decoration : none; color : black; font-size : 9pt;}
A:hover {text-decoration : underline; color : black;
font-size : 9pt;
}
-->
</style>
</head>

<body topmargin=
0 leftmargin=0 text=#464646>
<center>
<BR>
<?
    //데이터 베이스 연결하기
    include "db_info.php";

   
$id = $_GET[id];
   
$no = $_GET[no];
   
// 글 정보 가져오기
    $result=mysql_query("SELECT * FROM board WHERE id=$id", $conn);
   
$row=mysql_fetch_array($result);
?>
<table width=580 border=0 cellpadding=2 cellspacing=1
bgcolor=#777777>
<tr>
    <td height=
20 colspan=4 align=center bgcolor=#999999>
        <font color=white><B><?=$row[title]?></B></font>
    </td>
</tr>
<tr>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>글쓴이</td>
    <td width=240 bgcolor=white><?=$row[name]?></td>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>이메일</td>
    <td width=240 bgcolor=white><?=$row[email]?></td>
</tr>
<tr>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>
    날&nbsp;&nbsp;&nbsp;짜</td><td width=240
    bgcolor=white><?=$row[wdate]?></td>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>조회수</td>
    <td width=240 bgcolor=white><?=$row[view]?></td>
</tr>
<tr>
    <td bgcolor=white colspan=
4>
    <font color=black>
    <pre><?=
$row[content]?></pre>
    </font>
    </td>
</tr>
<!-- 기타 버튼 들 -->
<tr>
    <td colspan=
4 bgcolor=#999999>
    <table width=100%>
        <tr>
            <td width=
200 align=left height=20>
                <a href=
list.php?no=<?=$no?>><font color=white>
               
[목록보기]</font></a>
                <a href=write.php><font color=white>
               
[글쓰기]</font></a>
                <a href=edit.php?id=
<?=$id?>><font color=white>
               
[수정]</font></a>
                <a href=predel.php?id=
<?=$id?>>
                <font color=white>
[삭제]</font></a>
            </td>
            <!-- 기타 버튼 끝 -->
            <!-- 이전 다음 표시 -->
            <td align=right>
<?
    // 현재 글보다 id 값이 큰 글 중 가장 작은 것을 가져온다. 삭제됬을때를 생각해서 이렇게 구현함
    // 즉 바로 이전 글 ORDER BY id ASC가 함축됨 즉 오름차순으로 정렬되있음
    $query=mysql_query("SELECT id FROM board WHERE id >$id LIMIT 1",
   
$conn);
   
$prev_id=mysql_fetch_array($query);

   
if ($prev_id[id]) // 이전 글이 있을 경우
    {
        echo "<a href=read.php?id=$prev_id[id]>
        <font color=white>[이전]</font></a>"
;
   
}
    else
    {
        echo "[이전]";
   
}

    //내림차순으로 정렬하고 작은 것 한개 가져옴
    $query=mysql_query("SELECT id FROM board WHERE id <$id
    ORDER BY id DESC LIMIT 1"
, $conn);
   
$next_id=mysql_fetch_array($query);

   
if ($next_id[id])
    {
        echo "<a href=read.php?id=$next_id[id]>
        <font color=white>[다음]</font></a>"
;
   
}
    else
    {
        echo "[다음]";
   
}
?>
            </td>
        </tr>
    </table>
    </b></font>
    </td>
</tr>
</table>
</center>
</body>
</html>

<?
    // 조회수 업데이트
    $result=mysql_query("UPDATE board SET view=view+1 WHERE id=$id",
   
$conn);

   
mysql_close($conn);
?>


동작 화면


삭제를 눌렀을 때 비밀번호를 입력받기 위한 폼은 predel.php에서 수행한다.


predel.php


<html>
<head>

<title>
초 허접 게시판</title>
<style>

<!--
td {font-size : 9pt;}
A:link {font : 9pt;color : black;text-decoration : none;
font-family: 굴림;font-size : 9pt;}
A:visited {text-decoration : none; color : black; font-size : 9pt;}
A:hover {text-decoration : underline; color : black;
font-size : 9pt;}
-->
</style>
</head>

<body
topmargin=0 leftmargin=0 text=#464646>
<center>

<BR>

<!-- 입력된 값을 다음 페이지로 넘기기 위해 FORM을 만든다. 이때 post 방식을 사용하는 것을 -->
<form
action=delete.php?id=<?=$_GET[id]?> method=post>
<table
width=300 border=0 cellpadding=2 cellspacing=1
bgcolor=#777777>
<tr>

    <td height=20 align=center bgcolor=#999999>
        <font color=white><B>비 밀 번 호 확 인</B></font>
    </td>
</tr>

<tr>

    <td align=center >
        <font color=white><B>비밀번호 : </b>
        <INPUT type=password name=pass size=8>
        <INPUT type=submit value="확 인">
        <INPUT type=button value="취 소" onclick="history.back(-1)">
    </td>
</tr>
</table>



동작 화면



글 삭제 반영은 del.php파일에서 수행한다.



<?
//데이터 베이스 연결하기
include "db_info.php";
$id = $_GET[id];
$pass = $_POST[pass];

$result=mysql_query("SELECT pass FROM board WHERE id=$id",
$conn);
$row=mysql_fetch_array($result);

if ($pass==$row[pass] )//비밀번호 맞는지 확인함.
{
    $query = "DELETE FROM board WHERE id=$id "; //데이터 삭제하는 쿼리문
    $result=mysql_query($query, $conn);
}
else
{
    echo ("
    <script>
    alert('비밀번호가 틀립니다.');
    history.go(-1);
    </script>
    "
);
   
exit;
}
?>
<center>
<meta http-equiv=
'Refresh' content='1; URL=list.php'>
<FONT size=
2 >삭제되었습니다.</font>



동작 화면




글 목록 출력은


list.php 파일


<?
//데이터 베이스 연결하기
include "db_info.php";

# LIST 설정
# 1. 한 페이지에 보여질 게시물의 수
$page_size=10;

# 2. 페이지 나누기에 표시될 페이지의 수
// $no는 페이지가 시작되는 첫 글의 순번이다.
$page_list_size = 10;
$no = $_GET[no];
if (!$no || $no <0) $no=0;

// 데이터베이스에서 페이지의 첫번째 글($no)부터
// $page_size 만큼의 글을 가져온다.
$query = "SELECT * FROM board ORDER BY id DESC LIMIT $no, $page_size";
$result = mysql_query($query, $conn);

// 총 게시물 수 를 구한다.
$result_count=mysql_query("SELECT count(*) FROM board",$conn);
$result_row=mysql_fetch_row($result_count);
$total_row = $result_row[0];
//결과의 첫번째 열이 count(*) 의 결과다.
//mysql_fetch_row 쓰면 $result_row[0] 처럼 숫자를 써서 접근을 해야한다.

# 총 페이지 계산
# ceil는 올림이다.
if ($total_row <= 0) $total_row = 0;
$total_page = ceil($total_row / $page_size);//1개면

# 현재 페이지 계산
# no 변수는 0부터 시작해서 +1을 해줌.
$current_page = ceil(($no+1)/$page_size);
?>
<html>
<head>
<title>초 허접 게시판 </title>
<style>
<!--
td
{font-size : 9pt;}
A:link {font : 9pt;color : black;text-decoration : none; fontfamily
: 굴림;font-size : 9pt;
}
A:visited {text-decoration : none; color : black; font-size : 9pt;}
A:hover {text-decoration : underline; color : black; font-size : 9pt;}
-->
</style>
</head>
<body topmargin=
0 leftmargin=0 text=#464646>
<center>
<BR>
<!-- 게시판 타이틀 -->
<font size=
2>자~ 버그를 찾읍시다~ 버그를~~</a>
<BR>
<BR>
<!-- 게시물 리스트를 보이기 위한 테이블 -->
<table width=
580 border=0 cellpadding=2 cellspacing=1
bgcolor=#777777>
<!-- 리스트 타이틀 부분 -->
<tr height=
20 bgcolor=#999999>
    <td width=30 align=center>
        <font color=white>번호</font>
    </td>
    <td width=
370 align=center>
        <font color=white>제 목</font>
    </td>
    <td width=
50 align=center>
        <font color=white>글쓴이</font>
    </td>
    <td width=
60 align=center>
        <font color=white>날 짜</font>
    </td>
    <td width=
40 align=center>
        <font color=white>조회수</font>
    </td>
</tr>
<!-- 리스트 타이틀 끝 -->
<!-- 리스트 부분 시작 -->
<?
while($row=mysql_fetch_array($result))
{

?>
<!-- 행 시작 -->
<tr>
    <!-- 번호 -->
    <td height=
20 bgcolor=white align=center>
        <a href=
"read.php?id=<?=$row[id]?>&no=<?=$no?>">
       
<?=$row[id]?></a>
    </td>
    <!-- 번호 끝 -->
    <!-- 제목 -->
    <td height=
20 bgcolor=white>&nbsp;
        <a href=
"read.php?id=<?=$row[id]?>&no=<?=$no?>">
       
<?=strip_tags($row[title], '<b><i>');?></a>
    </td>
    <!-- 제목 끝 -->
    <!-- 이름 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black>
        <a href=
"mailto:<?=$row[email]?>"><?=$row[name]?></a>
        </font>
    </td>
    <!-- 이름 끝 -->
    <!-- 날짜 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
$row[wdate]?></font>
    </td>
    <!-- 날짜 끝 -->
    <!-- 조회수 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
$row[view]?></font>
    </td>
    <!-- 조회수 끝 -->
</tr>
<!-- 행 끝 -->
<?
} // end While
//데이터베이스와의 연결을 끝는다.

mysql_close
($conn);
?>
</table>
<!-- 게시물 리스트를 보이기 위한 테이블 끝-->
<!-- 페이지를 표시하기 위한 테이블 -->
<table border=
0>
<tr>
    <td width=
600 height=20 align=center rowspan=4>
    <font color=gray>
    &nbsp;
<?
$start_page = floor(($current_page - 1) / $page_list_size) * $page_list_size + 1;
# floor 함수는 소수점 이하는 버림

# 페이지 리스트의 마지막 페이지가 몇 번째 페이지인지 구하는 부분이다.
$end_page = $start_page + $page_list_size - 1;

if ($total_page <$end_page) $end_page = $total_page;

if ($start_page >= $page_list_size) {
    # 이전 페이지 리스트값은 첫 번째 페이지에서 한 페이지 감소하면 된다.
    # $page_size 를 곱해주는 이유는 글번호로 표시하기 위해서이다.

    $prev_list = ($start_page - 2)*$page_size;
   
echo "<a href="$PHP_SELF?no=$prev_list">◀</a> ";
}

# 페이지 리스트를 출력
for ($i=$start_page;$i <= $end_page;$i++) {
    $page= ($i-1) * $page_size;// 페이지값을 no 값으로 변환.
    if ($no!=$page){ //현재 페이지가 아닐 경우만 링크를 표시
        echo "<a href="$PHP_SELF?no=$page">";
   
}
   
   
echo " $i "; //페이지를 표시
   
   
if ($no!=$page){ //현재 페이지가 아닐 경우만 링크를 표시하기 위해서
        echo "</a>";
   
}
}

# 다음 페이지 리스트가 필요할때는 총 페이지가 마지막 리스트보다 클 때이다.
# 리스트를 다 뿌리고도 더 뿌려줄 페이지가 남았을때 다음 버튼이 필요할 것이다.
if($total_page >$end_page)
{
    $next_list = $end_page * $page_size;
   
echo "<a href=$PHP_SELF?no=$next_list>▶</a><p>";
}
?>
    </font>
    </td>
</tr>
</table>
<a href=write.php>글쓰기</a>
</center>
</body>
</html>


동작 화면



출처 : http://brown.ezphp.net/85



블로그 이미지

가카리

소프트웨어와 하드웨어 프로그래밍, 취업 및 직장생활 전문 블로그

MYSQL과 PHP를 이용한 방명록 만들기


방명록 테이블 설계


항목

내용

id

글번호 키

name

글쓴이의 이름

pass

글쓴이의 비밀번호

content

글의 내용

wdate

글이 등록된 날짜와 시간



sql구문


CREATE TABLE guestbook (

idint(11) UNSIGNED NOT NULL AUTO_INCREMENT,

namevarchar(20) NOT NULL,

passvarchar(20) NOT NULL,

contenttextNOT NULL,

wdatetimestampNOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE

CURRENT_TIMESTAMP,

PRIMARY KEY (id)

) ENGINE=MyISAM DEFAULT CHARSET=euckr;

     



테이블 접근 계정 추가 구문 php_brain 대신에 데이터베이스명 쓰면됨.


grant all privileges on php_brain.guestbook to 'webauth' identified by 'webauth';

flush privileges;


위 구문은 모든 권한을 webauth라는 ID와 webauth라는 비번을 쓰는 사람에게 줌.


grant select on php_brain.* to 'webauth' identified by 'webauth';

flush privileges;


위 구문은 select 권한을 webauth라는 ID와 webauth라는 비번을 쓰는 사람에게 줌.


MySQL 워크벤치에서 실행한 화면

 



 

 

 

list.php 파일


<?

 

  $conn = mysql_connect("localhost", "webauth", "webauth") or die(mysql_error());

 

  @mysql_select_db("php_brain", $conn);//데이터베이스 이름

  mysql_query("set names euckr");


  $query = "SELECT * FROM guestbook ORDER BY id DESC";

  $result = mysql_query($query, $conn);

  $total = mysql_affected_rows();//쿼리의 결과가 몇개인지 확인함


  $pagesize=5;

 

?>


<FORMACTION="insert.php" METHOD="POST">

<TABLEBORDER=1 WIDTH=500>

  <TR>

    <TD>이름</TD><TD><INPUT TYPE="TEXT" NAME="name"></TD>

    <TD>비밀번호</TD><TD><INPUT TYPE="PASSWORD" NAME="pass"></TD>

  </TR>

  <TR>

    <TDCOLSPAN=4><TEXTAREA NAME="content" COLS=65 ROWS=5></TEXTAREA></TD>

  </TR>

  <TR>

    <TDCOLSPAN=4 align=right><INPUT TYPE="SUBMIT" VALUE=" 확인 "></TD>

  </TR>

</TABLE>

</FORM>

<BR>


<?


 

  for($i=$_GET[no] ; $i < $_GET[no]+$pagesize ; $i++) {

 

    if ($i < $total)

    {

      mysql_data_seek($result,$i);//result에 지정한 MYSQL 결과의 내부 행 포인터를 지정한 행번호로 옮깁니다.

      $row = mysql_fetch_array($result);

?>


<TABLEWIDTH=500 BORDER=1>

  <TR>

    <TD>No.<?=$row[id]?></TD>

    <TD><?=$row[name]?></TD>

    <TD>(<?=$row[wdate]?>)</TD>

    <TD><ahref="delete.php?id=<?=$row[id]?>">del</a></TD>

  </TR>

  <TR>

    <TDCOLSPAN=4><?=$row[content]?></TD>

  </TR>

</TABLE>


<?

    } //end if

  } //end for


  $prev = $_GET[no] - $pagesize ; // 이전 페이지는 시작 글에서 $scale을 뺀 값부터

  $next = $_GET[no] + $pagesize ; // 다음 페이지는 시작 글에서 $scale을 더한 값부터


  if ($prev >= 0) {//음수면 페이지가 존재하지않음

    echo"<a href='{$_SERVER['PHP_SELF']}?no=$prev'>이전</a>";

  }


  if ($next < $total) {

    echo"<a href='{$_SERVER['PHP_SELF']}?no=$next'>다음</a></center>";

  }

?>



동작화면




insert.php


<?

  $conn = mysql_connect("localhost", "webauth", "webauth") or die(mysql_error());

 

  if(!$conn) {

   echo"Cannot connect to database.";

   exit;

  }

 

  @mysql_select_db("php_brain", $conn);

  mysql_query("set names euckr", $conn);

 

  //$query = "insert guestbook set name='$_POST[name]', pass='$_POST[pass]', content='$_POST[content]'";

 

  $query = "INSERT INTO guestbook (name, pass, content) ";

  $query .= "VALUES ('".$_POST['name']."', '".$_POST['pass']."', '".$_POST['content']."');";

  //$query .= "VALUES ('$_POST[name]', '$_POST[pass]', '$_POST[content]')";

  //$query .= "VALUES ('$_POST[name]', '$_POST[pass]', '$_POST[content]')";

 

 

  echo$query;

 

  $result = mysql_query($query, $conn) or die("sql 제대로임?");

   if(!$result) {

   echo"Cannot connect to result.";

   exit;

  }

   $err_str = mysql_error();#SQL문 오류를 보여주는 명령어

            echo$err_str;        #포함..

 

 

  //$query = "SELECT * FROM guestbook ORDER BY id DESC";

  //$result = mysql_query($query, $conn);

 

  //echo $result;

 

  ?>


<script>

  alert("글이 등록되었습니다.");

  location.href="list.php";

</script>



동작화면



delete.php 소스


del 버튼을 누르면 list.php에서 id를 넘겨줘서 delete.php로 보낸다.


이 id를 이용해서 데이터베이스를 검색해서 지우게 된다.


<?

  if ($_GET['mode']!="delete")

  {

?>

<HTML>

<FORMMETHOD="POST"

ACTION="<?=$_SERVER['PHP_SELF']?>?id=<?=$_GET[id]?>&mode=delete">

<TABLE>

  <TR>

    <TD>비밀번호</TD>

    <TD><INPUTTYPE="PASSWORD" NAME="pass"></TD>

    <TD><INPUTTYPE="SUBMIT" VALUE=" 확 인 "></TD>

  </TR>

</TABLE>

<?

    exit;

  } //end if


  $conn = mysql_connect("localhost", "webauth", "webauth") or die(mysql_error());

  @mysql_select_db("php_brain", $conn);

  @mysql_query("set names euckr");


  $query = "SELECT pass FROM guestbook WHERE id='$_GET[id]'";

  $result = mysql_query($query, $conn);

  $row = mysql_fetch_array($result);

 

  if ($row[pass] == $_POST[pass])

  {

    $query = "DELETE FROM guestbook WHERE id='$_GET[id]'";

    $result = mysql_query($query, $conn);

  }

?>

<script>alert("글이 삭제되었습니다."); location.href="list.php"; </script>


동작화면



출처 : http://brown.ezphp.net/85





블로그 이미지

가카리

소프트웨어와 하드웨어 프로그래밍, 취업 및 직장생활 전문 블로그

Tag mysql, php

 

 

 $query = "insert into tts values ('','$jaksung','$dayy','$money','$updayy','$dd','$comment',now())";
                  $result=mysql_query($query, $conn);
                  $err_str = mysql_error();#SQL문 오류를 보여주는 명령어
                        echo $err_str;        #포함..

 

 

다음과 같이 mysql_error 함수를 이용하면 SQL문의 오류를 보여준다.

블로그 이미지

가카리

소프트웨어와 하드웨어 프로그래밍, 취업 및 직장생활 전문 블로그

1. get

 

같은 페이지가 아닌 다른페이지에서 값을 넘겨 받을때 사용되어지는 방식.

 

ex>1번페이지에서 값을 입력해 2번페이지로 넘긴다

 

실제로 변수를 넘겨 받는것은 상당히 중요.

 

scanf 와 비슷하다. 값을 입력받아 전달한다.

 

변수를 전달하는 방법 get 과 post

 

<?php

 

echo $_GET['name'];

echo "님 안녕하세요.저는";

echo $_GET['me'];

echo "입니다";

 

?>

 

url주소 끝에 ?name=이름&me=이름

 

위에 ?는 get방식으로 전달하는 변수와 내용 인데

name은 변수 =은 전달 이름은 내용 이 됩니다.

&는 변수추가 me는 변수 이름은 내용이 됩니다.

 

 

실행결과

http: //주소값 ?name=이름&me=이름

 

이름 님 안녕하세요 저는 이름 입니다.

 

$_GET['변수명'] <<<숙지할것!!!

 

GET 은 대문자로 써야될 것!

 

출처 : http://sinttogi.tistory.com/entry/php-get%EB%B0%A9%EC%8B%9D%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%B3%80%EC%88%98-%EC%A0%84%EB%8B%AC

블로그 이미지

가카리

소프트웨어와 하드웨어 프로그래밍, 취업 및 직장생활 전문 블로그

Tag php

list

(PHP 4, PHP 5)

list배열처럼 변수에 할당

설명

void list ( mixed $varname [, mixed $... ] )

array()처럼, 이 함수는 실제 함수가 아니고 언어 구조이다. list()는 한번의 조작으로 배열 목록을 지정하기 위해 사용된다.

인수

varname

변수.

 

반환값

값을 반환하지 않습니다.

예제

Example #1 list() 예제

<?php

$info 
= array('coffee''brown''caffeine');

// 모든 변수를 목록화한다
list($drink$color$power) = $info;
echo 
"$drink is $color and $power makes it special.\n";

// 그들중 일부를 목록화한다
list($drink, , $power) = $info;
echo 
"$drink has $power.\n";

// 또는 세번째 값으로만 건너띈다
list( , , $power) = $info;
echo 
"I need $power!\n";

// list()는 문자열에는 작동하지 않습니다
list($bar) = "abcde";
var_dump($bar); // NULL
?>

 

Example #2 list() 용례

<table>
 <tr>
  <th>Employee name</th>
  <th>Salary</th>
 </tr>

<?php

$result 
mysql_query ("SELECT id, name, salary FROM employees"$conn);
while (list (
$id$name$salary) = mysql_fetch_row ($result)) {
    echo 
" <tr>\n" .
          
"  <td><a href=\"info.php?id=$id\">$name</a></td>\n" .
          
"  <td>$salary</td>\n" .
          
" </tr>\n";
}

?>

</table>

 

Example #3 중첩 list() 사용하기

<?php

list($a, list($b$c)) = array(1, array(23));

var_dump($a$b$c);

?>
int(1)
int(2)
int(3)

 

Example #4 배열 인덱스로 list() 사용하기

<?php

$info 
= array('coffee''brown''caffeine');

list(
$a[0], $a[1], $a[2]) = $info;

var_dump($a);

?>

다음과 같이 출력된다 (이 원소들의 순서는 list() 문법에서 쓰여진 순서와 반대라는 점에 주의):

array(3) {
  [2]=>
  string(8) "caffeine"
  [1]=>
  string(5) "brown"
  [0]=>
  string(6) "coffee"
}

 

주의

Warning

list()는 가장 우측 인수에서 시작하는 값들을 지정한다. 일반적인 변수들을 사용하면, 이 동작에 대해서 신경 쓸 필요가 없다. 그러나 인덱스를 갖는 배열에서 사용한다면 왼쪽에서 오른쪽으로 list()에서 쓰여진것과 같이 배열안의 인덱스 순서로 되는것이라고 보통 기대할수 있으나, 그렇지 않다. 역순으로 지정이 된다.

Note: list()는 숫자 배열에서만 작동하고 0부터 시작하는 숫자 인덱스로 가정한다.

참고

 

블로그 이미지

가카리

소프트웨어와 하드웨어 프로그래밍, 취업 및 직장생활 전문 블로그

Tag php

isset() 함수



bool isset ( mixed $var [, mixed $... ] )



변수가 세트되어있으면서 NULL 이 아닌지를 체크하는 함수입니다.


변수가 존재하고 NULL 이 아닌 값을 가지고 있으면 TRUE를 리턴합니다.

그 외에는 FALSE를 리턴합니다.


unset()함수로 변수를 unset 시킨 후, isset()으로 확인하면, FALSE가 리턴되지요.


함수의 인자로 여러개의 변수를 줄 수 있는데, 이때는 모든 변수가 세트되어 있어야 TRUE를 리턴합니다.





unset() 함수




void unset ( mixed $var [, mixed $... ] )



변수를 파과합니다. 아예 존재하지 않도록 만듭니다.

 

 

출처 : http://zzaps.tistory.com/44