복원 (데이터 등록)
MySQL -u사용자 -p암호 DB이름 < DB백업.sql -- DB가 존재 하지 않는 경우 미리 생성 후 진행 하여야 함.
복원 (데이터 등록)
MySQL -u사용자 -p암호 DB이름 < DB백업.sql -- DB가 존재 하지 않는 경우 미리 생성 후 진행 하여야 함.
윈도우에서 cmd 를 띄우고
mysql 을 설치한 폴더 bin 까지 이동한다
cd C:\Program Files\MySQL\MySQL Server 5.7\bin
이 상태에서 명령어를 치는데
특정데이터를 백업하려면 예를들어
academy데이터베이스를 백업하려면
mysqldump -uroot -p academy>academy.sql
전체데이터베이스를 백업하려면
mysqldump -uroot -p --all-databases>all.sql
그러면 암호를 치라고 나오고 그 후 bin 폴더에 가면 내가 지정한 all.sql 이 생성된걸 볼수 있다.
게시물 | family | orderby | step |
게시물3 | 3 | 0 | 0 |
게시물2 | 2 | 0 | 0 |
re 게시물2의 답변3 | 2 | 1 | 1 |
re 게시물2의 답변2(부모) | 2 | 2 | 1 |
re 게시물2의 답변2의 답변1 | 2 | 3 | 2 |
re 게시물2의 답변1 | 2 | 4 | 1 |
게시물1 | 1 | 0 | 0 |
게시물 | family | orderby | step |
게시물3 | -3 | 0 | 0 |
게시물2 | -2 | 0 | 0 |
re 게시물2의 답변3 | -2 | 1 | 1 |
re 게시물2의 답변2(부모) | -2 | 2 | 1 |
re 게시물2의 답변2의 답변1 | -2 | 3 | 2 |
re 게시물2의 답변1 | -2 | 4 | 1 |
게시물1 | -1 | 0 | 0 |
물론 위와 같이 1씩 감소하는 형태가 되려면 family는 0에서부터 시작하여 답변 글이 아닌
새 글이 입력될때마다 -1을 해주도록 하면 간단하다
게시물1을 -1로 주고, 다음 게시물이 입력되면 family컬럼의 최소값을 구하여 새로운 게시물의 family값으로 넣어준다
SELECT MIN(family) FROM [테이블이름]
테이블에서 family컬럼의 최소값을 구하여 리턴하는데 우리는 이 값에 -1을 하여 새로운 게시물의 family값으로 사용한다.
위와 같이 family가 -1씩 감소하는 형태라면 게시물을 가져오는 정렬방법을 다음과 같이 수정해 주어야만 한다
ORDER BY family ASC, orderby ASC
기본적으로 우리가 기본키primary key로 지정한 칼럼은 인덱스가 설정되어 있기 때문에, 이 컬럼에 대해 오름차순정렬을 하고자 한다면 상당히 빠르게레코드를 가져올 수 있다.
이것은 우리가 꺼내오고자 하는레코드의 정렬방식이 오름차순ASC이기 때문이다
그런데 기본키로 지정하면 기본적으로 인덱스가 설정되지만
family와 orderby를 기본키로 설정할 수는 없는 것이므로,
INDEX라는 함수를 사용하여 테이블 생성할때 다음과 같이 인덱스를 걸어주자
CREATE TABLE [테이블이름] (
no int unsigned default '0' auto_increment primary key,
family int,
orderby int,
step int,
...
INDEX (family, orderby)
)
위와 같이 인덱스를 사용하면 사용하지 않은 테이블보다 훨씬 빠른 속도로 게시물을 가져 올 수가 있게된다.
하지만 단점은 인덱스 사용시
인덱스된 정보를 따로 저장해 놓기 때문에 mySQL의 용량이 그리 넉넉하지 않다면 인덱스는 그리 권장할 만한 것이 아닐것이다
글의내용보기
-GET방식으로 그 글의 기본키 값을 넘겨주는 것인데
글의 내용을 출력하는 페이지가
VIEW.PHP이고 테이블의 기본키가 no라고 한다면
글 목록의 글 제목에는다음과 같은 링크가 있어야 할 것이다
<a href='view.php?no=글번호'>
이렇게 글번호(no컬럼의 값)라는 기본키의 값을 view.php로 넘겨주면 view.php에서는
$no라는 값을 받아서, 테이블에서 no컬럼의 값이 $no와 같은 글을 꺼내어 그 내용을 출력하게 될 것이다.
테이블설계
CREATE TABLE bbs (
no int unsigned default '0' auto_increment primary key,
family int not null,
orderby int not null,
step int not null,
name char(20) not null,
title varchar(200) not null,
memo text not null,
hit int unsigned default '0'
)
->메모장에서 사용되었던 pass와 time컬럼은 간결한 소스를 위해 생략
write.php
<form method=post action=write_ing.php>
이름 <input type=text size=10 name=name><br>
제목 <input type=text size=30 name=title><br>
<textarea cols=35 rows=5 name=memo></textarea><br>
<input type=submit value='글쓰기'>
</form>
write_ing.php (글의저장)
<?
include "connect.php"; // mySQL에 접속
include "lib.php"; // 함수 라이브러리
if (!$name) {error ('이름을 입력 하세요');} // 이름 체크
if (!$title) {error ('제목을 입력 하세요');} // 제목 체크
if (!$memo) {error ('내용을 입력 하세요');} // 내용 체크
$name = addslashes ($name); // 이름의 특수문자에 \를 붙임
$title = addslashes ($title); // 제목의 특수문자에 \를 붙임
$memo = addslashes ($memo); // 내용의 특수문자에 \를 붙임
$query = "SELECT MIN(family) FROM bbs"; //family컬럼의 최소값을구하여 그 값에 -1을 해준 값이 된다
$family = mysql_fetch_array (mysql_query ($query, $connect));
$family = $family[0]-1; //$family[0]대신에 $family["MIN(family)"]를 넣어주어도 결과는 같다
$orderby = 0;
$step = 0;
$query = "INSERT INTO bbs (family, orderby, step, name, title, memo)
VALUES ($family, $orderby, $step, '$name', '$title', '$memo')";
mysql_query ($query, $connect); // 글 저장
mysql_close ($connect); // mySQL 접속 끊기
move_page ("list.php"); // list.php로 이동
?>
list.php 글목록
<a href=write.php>글쓰기</a>
<table width=450 border=1>
<?
include "connect.php"; // mySQL에 접속
//페이징처리를 위한 구문
$query = "SELECT COUNT(*) FROM bbs"; // 갯수세기 쿼리문
$result = mysql_query ($query, $connect); // 쿼리문 입력
$total = mysql_result ($result, 0, 0); // 총 갯수 저장
$page = 10; // 페이지당 게시물 갯수
$pagesu = ceil ($total / $page); // 전체 페이지 갯수
$start = $page * $pagenum; // 시작위치
$number = $total - ($pagenum * $page); // 현재 페이지의 시작 글 번호
$query = "SELECT * FROM bbs ORDER BY family, orderby LIMIT $start,$page"; //bbs의 글 가져오기
$result = mysql_query ($query, $connect); // 글 꺼내기
while ($data = mysql_fetch_array ($result)) {
$data[name] = stripslashes ($data[name]); // 이름의 \제거
$data[title] = stripslashes ($data[title]); // 제목의 \제거
if ($data[step]) {$re = "re";} //step에 값이 있다는 것을 리플을 의미하므로 앞에 re를 붙여주자
else {$re = "";}
$blank="";
for ($i = 0; $i < $data[step]; $i++) {//step이 2이상이면 답변의 답변이므로 글목록을 좀더 안쪽으로 배치하기 위하여 공백문자를 더해주자
$blank .= " ";
}
echo "<tr> //리스트에 보여주고자 하는 것을 출력하자 no, title, name, hit
<td width=1% nowrap>$number</td>
<td width=97%>$blank$re<a href=view.php?no=$data[no]>$data[title]</a>
</td>
<td width=1% nowrap>$data[name]</td>
<td width=1% nowrap>$data[hit]</td>
</tr>";
$number--; // 글 번호 감소
}
?>
<table>
<?
$pagegroup = 5; // 페이지 그룹당 페이지 수
$pageend = $pagestart +$pagegroup; // 페이지 그룹의 마지막 페이지
$pagegroupnum = ceil(($pagenum + 1) / $pagegroup); // 현재의 페이지 그룹
$pagestart = ($pagegroupnum - 1) * $pagegroup + 1; // 페이지 그룹의 첫 페이지
$pageend = $pagestart +$pagegroup - 1; // 페이지 그룹의 마지막 페이지
$prevgroup = $pagegroupnum - 1; // 이전 그룹
$prevstart = ($prevgroup - 1) * $pagegroup; // 이전 페이지 그룹의 첫 페이지
if ($pagegroupnum != 1) { // 이전 페이지 그룹으로 이동
echo "[<a href='$PHP_SELF?pagenum=$prevstart'>◀◀</a>] ";
}
for ($i = $pagestart; $i <= $pageend; $i++) { // 페이지 이동 버튼 출력
if ($i > $pagesu) {break;} // 페이지 체크
$j = $i - 1; // 넘겨줄 $pagenum
echo "[<a href='$PHP_SELF?pagenum=$j'>$i</a>] ";
}
$nextgroup = $pagegroupnum + 1; // 다음 그룹
$nextstart = ($nextgroup - 1) * $pagegroup; // 다음 페이지 그룹의 첫 페이지
if ($pagesu > ($nextstart + 1)) { // 다음 페이지 그룹으로 이동
echo " [<a href='$PHP_SELF?pagenum=$nextstart'>▶▶</a>]";
}
?>
view.php 글내용
<?
include "connect.php"; // mySQL에 접속
$query = "UPDATE bbs SET hit=hit+1 WHERE no=$no"; //조회수가 올라가는 쿼리문
mysql_query ($query, $connect); // 조회수 증가
$query = "SELECT * FROM bbs WHERE no=$no"; //선택한 글을 꺼내오는 쿼리
$data = mysql_fetch_array (mysql_query ($query, $connect))
;
$data[name] = stripslashes ($data[name]); // 이름의 \제거
$data[title] = stripslashes ($data[title]); // 이름의 \제거
$data[memo] = stripslashes ($data[memo]); // 내용의 \제거
$data[memo] =nl2br ($data[memo]); // 띄어쓰기
?>
<table width=450 border=1> //실제 데이터를 출력해주는부분
<tr><td>글쓴이</td><td><?=$data[name]?></td></tr>
<tr><td>조회수</td><td><?=$data[hit]?></td></tr>
<tr><td>제목</td><td><?=$data[title]?></td></tr>
<tr><td>내용</td><td><?=$data[memo]?></td></tr>
</table>
<a href=list.php>글 목록</a> //데이터하단에 목록으로 돌아가는링크와 리플링크를 추가해줌
<a href=reply.php?no=<?=$data[no]?>>답변 쓰기</a>
reply.php 답변쓰기
<form method=post action=reply_ing.php>
<input type=hidden name=no value=<?=$no?>>
이름 <input type=text size=10 name=name><br>
제목 <input type=text size=30 name=title><br>
<textarea cols=35 rows=5 name=memo></textarea><br>
<input type=submit value='답변쓰기'>
</form>
reply_ing.php 답변글저장
<?
include "connect.php"; // mySQL에 접속
include "lib.php"; // 함수 라이브러리
if (!$name) {error ('이름을 입력 하세요');} // 이름 체크
if (!$title) {error ('제목을 입력 하세요');} // 제목 체크
if (!$memo) {error ('내용을 입력 하세요');} // 내용 체크
$name = addslashes ($name); // 이름의 특수문자에 \를 붙임
$title = addslashes ($title); // 제목의 특수문자에 \를 붙임
$memo = addslashes ($memo); // 내용의 특수문자에 \를 붙임
$query = "SELECT * FROM bbs WHERE no=$no"; //부모글의 값을 가져오는쿼리
$data = mysql_fetch_array (mysql_query ($query, $connect));
$family = $data[family];
$orderby = $data[orderby]+1;
$step = $data[step]+1;
$query = "UPDATE bbs SET orderby=orderby+1 WHERE family=$data[family] AND orderby>$data[orderby]";
mysql_query ($query, $connect);
$query = "INSERT INTO bbs (family, orderby, step, name, title, memo)
VALUES ($family, $orderby, $step, '$name', '$title', '$memo')";
mysql_query ($query, $connect); // 글 저장
mysql_close ($connect); // mySQL 접속 끊기
move_page ("list.php"); // list.php로 이동
?>
완벽한 게시판을 위해서는
비번을 입력받고, 삭제, 수정기능을 추가하여야 한다
출처; php초보탈출이야기 / 신동규/ PCBOOK[책도서]
6. 가상글번호붙이기
글이 16개 있는데 중간에 15번글을 삭제하면 그 번호가 비게 된다
이때 빠지는 글이 없도록 번호를 붙여줘야 하는데,
먼저 글 번호를 붙여주기 위해 글의 총 개수($total)을 이용한다.
총개수가 15개라면 첫번째 페이지의 글은15부터 감소하게 되는 것이다.
그리고 두번째 페이지의 글은 첫번째 페이지에서 페이지 당 글의 수($page)만큼의 번호를 사용하였기 때문에, 글의 총 개수($total)에서 페이지 당 글의 수($page)를 빼준 수부터 글 번호가 감소하게 된다.
결국
$number = $total - ($pagenum*$page); //현재 페이지의 시작 글번호
이 된다
예를들어
$total=15, $page=5일 경우, $pagenum은 첫번째 페이지가 0이므로
$total이 그대로 $number가 된다. 즉 글번호는 $total, 즉 15부터 감소해 나가는 것이다.
두번째페이지에서는 $pagenum이 1이므로 $page와의 곲은 5가 된다.
$total-5=10이므로 두번째 페이지는 10번부터 시작한다.
같은방법으로 세번째페이지를 계산하면 15-10=5, 글번호는 5번부터 시작한다
list.php소스에서 while문의 바로 앞에 위 소스를 추가해보자
$number = $total - ($pagenum * $page); //현재 페이지의 시작 글번호
while ($data=mysql_fetch_array($result)) { //글꺼내기
$data[name]=stripslashes($data[name]); //이름의 \제거
$data[memo]=stripslashes($data[memo]); //내용의 \제거
$data[memo]=nl2br ($data[memo]); //띄어쓰기
$data[time]=date('y-m-d', $data[time]); //시간포맷변환
echo "
<tr>
<td>$number</td><td> $data[name]</td><td> $data[memo]</td><td> $data[time]</td></tr>";
$number--; //글번호 감소
}
mysql_close($connect);
?>
</table>
7. del.php(삭제)
아래 것을 리스트 소스에 덧붙여 주자 그래야 삭제 버튼이 생긴다
<a href='del.php?no=$data[no]'>삭제 </a>
del.php
<form method=post action =del_ing.php>
<input type=hidden name=no value=<?=no?>>
비밀번호 <input type=password size=10 name=pass>
<input type=submit value='삭제'>
</form>
del_ing.php
<?
include "connecct.php"; //mysql접속
include "lib.php"; //함수라이브러리
$query= "SELECT * FROM exam_memo WHERE no=$no"; //no컬럼의 값이 no인 글을 가져오라
$data=mysql_fetch_array ( mysql_query ($query, $connect)); //가져온 글을 연관배열에 저장해라
$pass = crypt ($pass,12) //비밀번호암호화
if ($pass==$data[pass]) {
mysql_query ("DELETE FROM exam_memo WHERE no=$no", $connect);
}
else {
error ("비밀번호가 정확하지 않습니다");
}
mysql_close ($connect);
move_page ("list.php");
?>
8. edit.php (수정)
list.php에 삭제에서와 같은 방법으로 수정버튼을 만들어준다
<a href='edit.php?no=$data[no]'>수정 </a>
edit.php
<?
include "connecct.php"; //mysql접속
include "lib.php"; //함수라이브러리
$query= "SELECT * FROM exam_memo WHERE no=$no"; //no컬럼의 값이 no인 글을 가져오라
$data=mysql_fetch_array ( mysql_query ($query, $connect)); //가져온 글을 연관배열에 저장해라
$data[name]= stripslashes ($data[name]); //이름의 \제거
$data[memo]= stripslashes ($data[memo]); //내용의 \제거
mysql_close ($connect);
?>
<form method=post action=Write_ing.php autocomplete=off>
<input type=hidden name=no value=<?=$no?> >
이름 <input type=text size=10 name=name>
비번 <input type=password size=10 name=pass> <br>
<textarea cols=30 rows=3 name=memo><?=$data[memo]?></textarea></br>
<input type=submit value='글수정'>
</form>
edit_ini.php
<?
include "connecct.php"; //mysql접속
include "lib.php"; //함수라이브러리
$query= "SELECT * FROM exam_memo WHERE no=$no"; //글정보꺼내기-no컬럼의 값이 no인 글을 가져오라
$data=mysql_fetch_array ( mysql_query ($query, $connect)); //가져온 글을 연관배열에 저장해라
$pass = crypt ($pass,12) //비밀번호암호화
if ($pass==$data[pass]) { //글수정
$name=addslashes ($name); //이름의 특수문자에 \를붙임
$memo=addslashes ($memo); //내용의 특숨ㄴ자에 \를붙임
mysql_query ("UPDATE exam_memo SET name='$name', memo='$memo' WHERE no=$no", $connect);
}
else {
error ("비밀번호가 정확하지 않습니다");
}
mysql_close ($connect);
move_page ("list.php");
?>
install.php
<?
include "connect.php"; //mysql접속
$query ="CREATE TABLE exam_memo(
no int unsigned auto_increment primary key,
name char(20) not null,
memo text not null,
pass char(20) not null,
time int unsigned
)";
mysql_query($query, $connect); //테이블생성
?>
페이지설계
connect.php -mysql에 접속, include하여 사용
install.php -exam_memo 테이블을 생성, 최초 설치시에만 실행
write.php -글 입력폼, 폼을 write_ing.php로 전송
write_ing.php - 입력된 글을 exam_memo테이블에 저장, 저장 후 list.php로 이동
list.php -입력된 글 리스트
del.php -선택된 글을 삭제하기 위해 비번을 입력받는 폼, 폼을 del_ing.php로 전송
del_ing.php - 선택된 글을 exam_memo테이블에서 삭제, 삭제후 리스트로 이동
edit.php - 선택된 글을 수정하기 위한 수정 폼, 폼을 edit_ing.php로 전송
edit_ing.php - 선택된 글을 수정, 수정 후 list.php로 이동
lib.php - 메모장 프로그램에 사용된 함수 라이브러리
lib.php 함수라이브러리
<?
//페이지 이동함수
function move_page ($url){
echo "<meta http-equiv='refresh' content='0; url=$url'>";
}
//에러메시지출력함수
function error ($memo){
echo "
<script language=javascript>
alert('$memo');
history.go(-1);
</script>
";
exit;
}
?>
write.php
<form method=post action=write_ing.php autocomplete=off>//autocomplete은 자동완성기능
이름 <input type=text size=10 name=name>
비번 <input type=password size=10 name=pass><br>
<textarea cols=30 rows=3 name=memo></textarea>
<input type=submit value='글쓰기'>
</form>
write_ing.php 글의저장
글쓰기 폼에서 전송을 누르면 write_ing.php로 각 변수가 전송되는데
post방식으로 전송되었기 때문에 $name, $pass, $memo과 같은 일반적인 변수가 아닌
$HTTP_POST_VARS[name], $HTTP_POST_VARS[pass], $HTTP_POST_VARS[memo]과 같은 환경변수를 사용하는것이 정석이긴 하지만, 여기서는 일반변수로 사용한다고 해서 문제될 것이 없으므로
그냥 $name, $pass, $memo로 사용하도록 하겠다
<?
include "connect.php"; //mysql에 접속
include "lib.php"; //함수라이브러리
if (!$name){error ('이름을 입력하삼');} //이름체크
if(!$pass){error ('비번을 입력하삼');} //비번체크
if (!$memo){error ('내용을입력하삼');}//내용체크
$pass=crypt ($pass,12); //비번암호화
$time=time(); //현재시간저장
$name=addslashes($name); //이름의 특수문자에 \를 붙임
$memo=addslashes($memo); //내용의 특수문자에 \를 붙임
$query="INSERT INTO exam_memo (name, memo, pass, time) VALUES ('$name', '$memo', ''$pass', '$time')";
mysql_query($query); //글저장
mysql_close($connect); //mySQL접속끊기
move_page ("list.php"); //list.php로 이동
?>
list.php
<table width=450 border=1>
<?
include "connect.php"; // mySQL에 접속
$query="SELECT * FROM exam_memo ORDER BY no DESC";
$result =mysql_query($query, $connect);
while ($data=mysql_fetch_array($result)) {
$data[name]=stripslashes($data[name]); //이름의 \제거
$data[memo]=stripslashes($data[memo]); //내용의 \제거
$data[memo]=nl2br ($data[memo]); //띄어쓰기
$data[time]=date('y-m-d', $data[time]); //시간포맷변환
echo "
<tr>
<td>$data[no]</td><td> $data[name]</td><td> $data[memo]</td><td> $data[time]</td></tr>";
}
mysql_close($connect);
?>
</table>
페이지이동로직
SELECT * FROM exam_memo ORDER BY no DESC LIMIT 0, 5 //첫번째페이지
SELECT * FROM exam_memo ORDER BY no DESC LIMIT 5, 5 //두번째페이지
SELECT * FROM exam_memo ORDER BY no DESC LIMIT 10, 5 //세번째페이지
$pagenum=1; //두번째 페이지로 설정
$page=5; // 페이지 당 게시물 개수
$total=16; //전체 게시물 수
$pagesu=총 페이지 수
$pagesu=ceil($total/$page); //올림하는 함수
LIMIT ($page*$pagenum), $page
LIMIT절에서의 시작위치는 페이지당 게시물 수에 $pagenum을 곱한 수가 되고,가져올 개수는 페이지 당 게시물 개수이다.
($page * $pagenum)을 $start라는 변수에 저장하자
$pagenum=1; //두번째 페이지로 설정
$page=5; // 페이지 당 게시물 개수
$total=16; //전체 게시물 수
$pagesu=ceil($total/$page); //올림하는 함수
$start=$page*$pagenum //시작위치
첫번째 페이지는 $pagenum=0 이다 0*5=0 그러므로 $start=0 결국 LIMIT 0, 5가 된다
두번째 페이지는 $pagenum=1 이다 1*5=5 그러므로 $start=5 결국 LIMIT 5, 5가 된다
일단 게시물의 전체갯수를 구하기 위하여 아래소스를 보자
$query="SELECT COUNT(*) FROM exam_memo "; //개수 세기 쿼리문
$result =mysql_query($query, $connect); //쿼리문입력
$total = mysql_result($result, 0, 0)//총개수저장
mysql_result 대신에 mysql_fetch_array 를 사용하는 방법도 있는데,
$query="SELECT COUNT(*) FROM exam_memo "; //개수 세기 쿼리문
$result = mysql_fetch_array (mysql_query($query, $connect)); //쿼리문입력
$total = $result["COUNT(*)"]; //총개수 저장
여기서 $result["COUNT(*)"] 대신에 $result[0]을 넣어주어도 같은 결과를 얻을 수 있다.
이제 $total 의 값을 구했으니 $total=16 부분은 삭제한다
$total=mysql_result ($result, 0,0);//총개수 저장
$pagenum=1; //두번째 페이지로 설정
$page=5; // 페이지 당 게시물 개수
$pagesu=ceil($total/$page); //올림하는 함수
$start=$page*$pagenum //시작위치
정리하면
<table width=450 border=1>
<?
include "connect.php"; // mySQL에 접속
$query="SELECT COUNT(*) FROM exam_memo"; //개수 세기 쿼리문
$result =mysql_query($query, $connect); //쿼리문입력
$total = mysql_result($result, 0, 0);//총개수저장
$pagenum=1; //두번째 페이지로 설정
$page=5; // 페이지 당 게시물 개수
$pagesu=ceil($total/$page); //올림하는 함수
$start=$page*$pagenum ;//시작위치
$query="SELECT * FROM exam_memo ORDER BY no DESC LIMIT $start, $page";
$result =mysql_query($query, $connect); //쿼리문입력-글꺼내기
while ($data=mysql_fetch_array($result)) { //글꺼내기
$data[name]=stripslashes($data[name]); //이름의 \제거
$data[memo]=stripslashes($data[memo]); //내용의 \제거
$data[memo]=nl2br ($data[memo]); //띄어쓰기
$data[time]=date('y-m-d', $data[time]); //시간포맷변환
echo "
<tr>
<td>$data[no]</td><td> $data[name]</td><td> $data[memo]</td><td> $data[time]</td></tr>";
}
mysql_close($connect);
?>
</table>
페이지그룹만들기
[1] [2] [3] [4] [5] [▶▶]
페이지그룹 1 ->pagenum의 값:0,1,2,3,4
페이지그룹 2 ->pagenum의 값:5,6,7,8,9
pagegroup=5; //페이지 그룹 당 페이지 수
현재의 페이지그룹을 구하는 식은
$pagegroupnum = ceil (($pagenum+1) / $pagegroup); //현재의 페이지 그룹
왜 이런식이 나왔는지 차근차근 대입해 보면?
$pagenum=0 일때 -> ceil( (0+1)/5 )=1 따라서 $pagegroupnum은 1이 된다
$pagenum=5 일때 -> ceil( (5+1)/5 )=2 따라서 $pagegroupnum은 2가 된다
페이지그룹의 첫페이지 구하는 식은
$pagestart = ($pagegroupnum - 1) * $pagegroup + 1 //페이지그룹의 첫 페이지
첫번째페이지그룹(1)이라면 (1-1)*5+1=1 , 즉 첫번째페이지그룹의 첫페이지는 1페이지이고
두번째페이지그룹(2)이라면 (2-1)*5+1=6 , 즉 두번째페이지그룹의 첫페이지는 6페이지이다.
첫번째페이지를 구하였으니 페이지그룹의 마지막페이지를 구하는식은?
$pageend=$pagestart + $pagegroup; //페이지 그룹의 마지막페이지
그런데 이렇게 해주면 첫번째 페이지 그룹의 시작페이지는 1이고, 페이지그룹 당 페이지수인 5를 더해주면
6이 되므로 -1을 해주어 5가 되도록 맞춰주도록 하자
$pageend=$pagestart + $pagegroup - 1; //페이지 그룹의 마지막페이지
현재의 페이지 그룹을 결정하고 그 페이지 그룹의 첫 페이지와 마지막페이지를 알아내었으니,
for문으로 페이지 이동버튼을 출력해보자
지금까지 정리해 보면
<table width=450 border=1>
<?
include "connect.php"; // mySQL에 접속
$query="SELECT COUNT(*) FROM exam_memo"; //개수 세기 쿼리문
$result =mysql_query($query, $connect); //쿼리문입력
$total = mysql_result($result, 0, 0);//총개수저장
//$pagenum=1; //두번째 페이지로 설정
$page=5; // 페이지 당 게시물 개수
$pagesu=ceil($total/$page); //올림하는 함수
$start=$page*$pagenum ;//시작위치
$query="SELECT * FROM exam_memo ORDER BY no DESC LIMIT $start, $page";
$result =mysql_query($query, $connect); //쿼리문입력-글꺼내기
while ($data=mysql_fetch_array($result)) { //글꺼내기
$data[name]=stripslashes($data[name]); //이름의 \제거
$data[memo]=stripslashes($data[memo]); //내용의 \제거
$data[memo]=nl2br ($data[memo]); //띄어쓰기
$data[time]=date('y-m-d', $data[time]); //시간포맷변환
echo "
<tr>
<td>$data[no]</td><td> $data[name]</td><td> $data[memo]</td><td> $data[time]</td></tr>";
}
mysql_close($connect);
?>
</table>
<?//페이지처리
$pagegroup = 5; //페이지그룹당 페이지수
$pageend = $pagestart + $pagegroup; //페이지그룹의 마지막페이지
$pagegroupnum= ceil(($pagenum+1)/$pagegroup); //현재의 페이지그룹
$pagestart = ($pagegroupnum-1) * $pagegroup +1; //페이지그룹의 첫 페이지
$pageend = $pagestart + $pagegroup -1 ; //페이지그룹의 마지막페이지
for ($i=$pagestart; $i <= $pageend; $i++) { //페이지 이동버튼 출력->1~5까지 루프가 돈다
if ($i > $pagesu) {break;} //페이지체크-실제페이지수보다 많으면 중단
echo "[$i]";
}
?>
이제 링크를 걸어 실제 페이지가 이동하도록 해보자
링크할 페이지는 자기자신, 즉 $PHP_SELF를 사용하고 GET방식으로 pagenum값을 넘겨주어야한다
<a href='$PHP_SELF?pagenum=$i'>
근데만약 위처럼 $i를 그대로 pagenum에 넣어주면 엉뚱한 펭지로 이동하게 될것이다
이것은 첫번째페이지일때 $pagenum=0이고
두번째페이지일때 $pagenum=1 인 것과 같이 $pagenum이 실제페이지보다 1만큼 작기때문이다
따라서 $i-1의 값을 넣어주어야 한다.
다음페이지 그룹으로 이동하기위해 [▶▶]
이전페이지 그룹으로 이동하기위해 [◀◀] 를 사용해보자
현재 페이지그룹이 2라면 다음페이지 그룹은 3이고, 이전페이지그룹은 1이 된다
따라서
$nextgroup = $pagegroupnum +1; //다음그룹
$prevgroup = $pagegroupnum -1; //이전그룹
이제 링크를 걸어주기위해 각각의 페이지 그룹에 속해 있는 페이지들의 첫 페이지를 구해준다.
$pagestart = ($pagegroupnum -1) * pagegroup +1; //페이지그룹의 첫페이지
$nextstart = ($nextgroup -1) * $pagegroup + 1; //다음 페이지 그룹의 첫 페이지
$prevstart = ($prevgroup -1) * $pagegroup +1; //이전 페이지 그룹의 첫 페이지
그런데 여기서는 몇번째 페이지인가를 생각하는 것이 아니라, 실제로 $pagenum으로 전달해 줄 값을 결정하는 것이므로
마지막의 +1은 하지 않도록 한다.
$nextstart = ($nextgroup -1) * $pagegroup ; //다음 페이지 그룹의 첫 페이지
$prevstart = ($prevgroup -1) * $pagegroup ; //이전 페이지 그룹의 첫 페이지
이제, 위의 $nextstart 와 $prevstart가 pagenum의 값으로 전달되도록 링크를 걸어주면된다
[<a href='$PHP_SELF?pagenm=$prevstart'>◀◀</a>]
[<a href='$PHP_SELF?pagenm=$nextstart'>▶▶</a>]
그런데 첫번째 페이지 그룹이라면 이전페이지가 존재하지 않기때문에, 첫번째 페이지 그룹이 아닐 경우에만 이전 페이지 그룹으로 이동하도록 if문을 하나 넣어준다
if ($pagegroupnum != 1) { //이전 페이지 그룹으로 이동
echo " [<a href='$PHP_SELF?pagenm=$prevstart'>◀◀</a>]";
다음페이지그룹으로의 이동에서도 마찬가지로 현재의 페이지 그룹이 마지막페이지그룹이라면
다음페이지그룹으로 이동할 필요는 없을 것이다.
따라서 다음페이지 그룹이 실제 존재하는지 알아보려면
전체 페이지 수($pagesu)가 다음페이지 그룹의 첫 번째 페이지($nextstart)+1 보다 큰지 알아보는 것이다.
전체 페이지 수가 크다면 아직 출력할 페이지들이 남아있는 것이 되므로
다음페이지 그룹은 실제로 존재하고 있다는 얘기가 된다
그리고 여기서 다음페이지 그룹의 첫페이지($nextstart)에 +1을 해준 이유는 우리가 구한 $nextstart는 $pageum의 값,
즉 첫번째 페이지가 1이 아닌 0을 갖기 때문이다.
결국 첫번째 페이지가 1이라는 값을 갖는 전체페이지 수와 값을 비교하기 위해 $nextstart에는 1을 더해줘야 한다
if($pagesu > ($nextstart +1) { //다음페이지그룹으로이동
echo " [<a href='$PHP_SELF?pagenum=$nextstart'>▶▶</a>]";
}
위 if문에서는 다음 페이지 그룹의 첫번째페이지($nextstart)가 전체 페이지 수보다 작은지를 검사하고,
만약 작다면 다음페이지 그룹이 존재하는 것으로 판단하여 이동버튼을 출력하도록 해준 것이다.
정리해보면
이전페이지그룹이동버튼
$prevgroup = $pagegroupnum -1; //이전그룹
$prevstart = ($prevgroup -1) * $pagegroup +1; //이전 페이지 그룹의 첫 페이지
if ($pagegroupnum != 1) { //이전 페이지 그룹으로 이동
echo " [<a href='$PHP_SELF?pagenm=$prevstart'>◀◀</a>]";
}
다음페이지그룹 이동버튼
$nextgroup = $pagegroupnum +1; //다음그룹
$nextstart = ($nextgroup -1) * $pagegroup ; //다음 페이지 그룹의 첫 페이지
if($pagesu > ($nextstart +1)) { //다음페이지그룹으로이동
echo " [<a href='$PHP_SELF?pagenum=$nextstart'>▶▶</a>]";
}
지금까지 한걸 정리해보면
list.php
<table width=450 border=1>
<?
include "connect.php"; // mySQL에 접속
$query="SELECT COUNT(*) FROM exam_memo"; //개수 세기 쿼리문
$result =mysql_query($query, $connect); //쿼리문입력
$total = mysql_result($result, 0, 0);//총개수저장
//$pagenum=1; //두번째 페이지로 설정
$page=5; // 페이지 당 게시물 개수
$pagesu=ceil($total/$page); //올림하는 함수
$start=$page*$pagenum ;//시작위치
$query="SELECT * FROM exam_memo ORDER BY no DESC LIMIT $start, $page";
$result =mysql_query($query, $connect); //쿼리문입력-글꺼내기
while ($data=mysql_fetch_array($result)) { //글꺼내기
$data[name]=stripslashes($data[name]); //이름의 \제거
$data[memo]=stripslashes($data[memo]); //내용의 \제거
$data[memo]=nl2br ($data[memo]); //띄어쓰기
$data[time]=date('y-m-d', $data[time]); //시간포맷변환
echo "
<tr>
<td>$data[no]</td><td> $data[name]</td><td> $data[memo]</td><td> $data[time]</td></tr>";
}
mysql_close($connect);
?>
</table>
<?//페이지처리
$pagegroup = 5; //페이지그룹당 페이지수
$pageend = $pagestart + $pagegroup; //페이지그룹의 마지막페이지
$pagegroupnum= ceil(($pagenum+1)/$pagegroup); //현재의 페이지그룹
$pagestart = ($pagegroupnum-1) * $pagegroup +1; //페이지그룹의 첫 페이지
$pageend = $pagestart + $pagegroup -1 ; //페이지그룹의 마지막페이지
$prevgroup = $pagegroupnum -1; //이전그룹
$prevstart = ($prevgroup -1) * $pagegroup +1; //이전 페이지 그룹의 첫 페이지
if ($pagegroupnum != 1) { //이전 페이지 그룹으로 이동
echo " [<a href='$PHP_SELF?pagenm=$prevstart'>◀◀</a>]";
}
for ($i=$pagestart; $i <= $pageend; $i++) { //페이지 이동버튼 출력->1~5까지 루프가 돈다
if ($i > $pagesu) {break;} //페이지체크-실제페이지수보다 많으면 중단
echo "[$i]";
}
$nextgroup = $pagegroupnum +1; //다음그룹
$nextstart = ($nextgroup -1) * $pagegroup ; //다음 페이지 그룹의 첫 페이지
if($pagesu > ($nextstart +1)) { //다음페이지그룹으로이동
echo " [<a href='$PHP_SELF?pagenum=$nextstart'>▶▶</a>]";
}
?>
로직
방문->총방문자수구하기->총방문자수+1 하고 저장 -> 방문자수출력
install.php
<?
include "connect.php"; //mysql접속
$query = "CREATE TABLE counter (
today int UNSIGNED,
total int UNSIGNED,
time int UNSIGNED
);";
$result=mysql_query($query, $connect); //쿼리문입력-테이블생성
mysql_close($connect); //접속해제
if ($result) {echo "설치성공";}
?>
INSERT INTO counter (today, total, time) VALUES (0,0,0);
->각 값을 0으로 초기화 해준다
<?
include "connect.php"; //mysql접속
$query = "SELECT * FROM counter LIMIT 1"; //쿼리문
//카운터테이블에서 1개의 모든 레코드의 모든 컬럼을 가져오라
$data=mysql_fetch_array(mysql_query($query, $connect)); //쿼리문실행-연관배열에 저장
$now = date(Ymd); //오늘날짜
$last = date(Ymd, $data[time]); //마지막방문날짜
if ($now == $last) {$data[today]++;} //오늘방문자수 구하기
else {$data[today]=1;}
$time = time(); //현재의 유닉스타임스탬프
$data[total]++; //총방문자 수 구하기
$query="UPDATE counter SET today=$data[today], total=$data[total], time=$time";
mysql_query ($query, $connect); //새로운 쿼리값 입력
echo "오늘:$data[today] 전체:$data[total]"; //출력
?>
위의 소스는 새로고침하면 계속 카운팅이 하므로 뭔가 제한을 걸어 줄 필요가 있다
쿠키를 이용해 만들어 보자
<?
setcookie("counter_cookie", "^_^", 0, "/"); //쿠키굽기
include "connect.php"; //mysql접속
$query = "SELECT * FROM counter LIMIT 1"; //쿼리문
//카운터테이블에서 1개의 모든 레코드의 모든 컬럼을 가져오라
$data=mysql_fetch_array(mysql_query($query, $connect)); //쿼리문실행-연관배열에 저장
$now = date(Ymd); //오늘날짜
$last = date(Ymd, $data[time]); //마지막방문날짜
if (!$HTTP_COOKIE_VARS[counter_cookie]) { //새로운 방문자일 경우
if ($now == $last) {$data[today]++;} //오늘방문자수 구하기
else {$data[today]=1;}
}
else { //새로운 방문자가 아닐경우
if ($now != $last) {$data[today]=0;}
}
$time = time(); //현재의 유닉스타임스탬프
if (!$HTTP_COOKIE_VARS[counter_cookie]) { //새로운방문자일 경우
$data[total]++; //총방문자 수 구하기
}
$query="UPDATE counter SET today=$data[today], total=$data[total], time=$time";
mysql_query ($query, $connect); //새로운 쿼리값 입력
echo "오늘:$data[today] 전체:$data[total]"; //출력
?>
1. COUNT
-가져온 레코드의 개수를 세어주는 함수
SELECT COUNT (*) 테이블이름
<?
include "connect.php"; //mysql접속
$query="SELECT COUNT(*) FROM student;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력
$count = mysql_result($result, 0, 0); //꺼내온 값의 저장
echo $count;
?>
결과는 3
저장될변수=mysql_result (쿼리결과, 열, 행);
no | name | year |
(0,0) | 0,1 | 0,2 |
1,0 | 1,1 | 1,2 |
우리가 넣어준 sql쿼리문의 결과는 위와 같이 여러 개의 열과 행으로 나누어진 형태의 2차원 배열이 아니라,
단순한 레코드의 개수이기에 하나의 열과 행으로 이루어진 값이 될것이다. 그렇기에
mysql_result함수에는 0,0을 넣어 첫번째 열의 첫번째 행에 해당하는 값임을 알려주는 것이다.
만약 mysql_fetch_array함수를 사용하고자 한다면
<?
include "connect.php"; //mysql접속
$query="SELECT COUNT(*) FROM student;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력
$data = mysql_fetch_array ($result); //연관배열만들기
echo $data["COUNT(*)"];
?>
mysql_fetch_array함수 사용은 하나의 레코드를가져올때 사용했던 방법과 동일하지만
저장된 연관 배열의 원소를 나타낼때의 방법은 조금 다르다
$배열이름["함수(매개변수)"]
위와 같은 형식은 count함수가 아닌 다른 함수에서도 같은 방법으로 사용된다
2. SUM
-지정된 컬럼에 입력된 값들의 합계를 구함
SELECT SUM(컬럼이름) FROM 테이블이름
<?
include "connect.php"; //mysql접속
$query="SELECT SUM(no) FROM student;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력
$sum = mysql_result($result, 0, 0); //꺼내온 값의 저장
echo $sum;
?>
결과는 6
-> no컬럼에는 1,2,3의 값이 들어 있으므로 1+2+3이 되어 6이 되는 것이다.
3. MAX, MIN
-최대값과 최소값을 구하는 함수
SELECT MAX(컬럼이름) FROM 테이블이름
SELECT MIN(컬럼이름) FROM 테이블이름
<?
include "connect.php"; //mysql접속
$query="SELECT MAX(no) FROM student;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력
$max = mysql_result($result, 0, 0); //꺼내온 값의 저장
echo $max;
?>
결과는 3
->student 테이블의 no컬럼에서 가장큰 값은 3
4. AVG
-평균을 구하는 함수
SELECT AVG(컬럼이름) FROM 테이블이름
예>
SELECT AVG(no) FROM student
결과는 2
->1,2,3의 평균
5. ROUND
-반올림을 해주는 함수
SELECT ROUND(컬럼이름, 자릿수) FROM 테이블이름
자릿수를 입력하지 않거나 0으로 해준다면 소수첫째자리에서 반올림하여 정수형태가 된다
자릿수를 1로 해준다면 소수둘째자리에서 반올림하여 소수첫째자리까지만 표시한다.
SELECT ROUND(no,1) FROM student WHERE no=1
-> student테이블에서 no가 1인 레코드의 no값을 반올림하여 소수 둘째 자리에서 반올림하여
소수 첫째자리까지만 표시 하라는 것
SELECT ROUND(AVG(no)) FROM student WHERE no=1
->위와 같이 중복사용도 가능하다
<?
include "connect.php"; //mysql접속
$query="SELECT ROUND(AVG(no)) FROM student ;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력
$avg = mysql_result($result, 0, 0); //꺼내온 값의 저장
echo $avg;
?>
6. 기타함수
UNIX_TIMESTAMP() -현재의 유닉스타임스탬프를 리턴
HEX(n) - 10진수를 16진수로 변환
OCT(n) - 10진수를 8진수로 변환
BIN(n) - 10진수를 2진수로 변환
CONV(n, 진수1, 진수2) - n을 진수1에서 진수2로 변환
ASCII(문자열) - 문자열의 첫분자의 ASCII코드로 변환
LOWER(문자열) - 문자열을 소문자로 변환
UPPER(문자열) - 문자열을 대문자로 변환
REVERSE(문자열) - 문장ㄹ의 순서를 바꿈
INSERT (문자열1, 위치, 크기, 문자열2) - 문자열1의 지정된 위치에 지정된 크기만큼 문장열2를 추가
LTRIM(문자열) - 문자열의 왼쪽 공백을 제거
RTRIM(문자열) - 해당 문자열의 오른쪽 공백을 제거
CONCAT(문자열,문자열...) -해당문자열을 연결
LEFT(문자열,크기) -문자열에서 지정된 크기만큼 왼쪽부터 리턴
RIGHT(문자열,크기) -문자열에서 지정된 크기만큼 오른쪽부터 리턴
LOCATE(문자열1, 문자열2) -문자열2에서 문자열1의 위치를 리턴
LPAD(문자열1, 길이, 문자열2) -문자열1의 왼쪽에 문자열2를 길이 만큼 추가
RPAD(문자열1, 길이, 문자열2)- 문자열1의 오른쪽에 문자열2를 길이만큼 추가
USER() - 현재 mysql에 접속중인 사용자의 이름을 리턴
VERSION() -mysql의 버전을 리턴
PASSWORD(문자열) - 문자열을 암호화하여 리턴