13. PHP 게시판 만들기, list 제작 3

2015.04.19 22:49
저자 : Kurien

주의: 본 게시판은 보안을 생각하지 않고 만들어졌으므로 실제로 사용되어서는 안되는 코드입니다.

공부할 때 게시판이 이처럼 동작한다는 정도로만 이해해주세요.


자격증 시험 때문에 조금 늦어졌습니다.

오늘은 검색 부분을 만들어보려고 합니다.


먼저 하단의 파일을 받아주세요!


20150419_project.zip


파일을 받고, index.php를 열어보면 아래의 코드가 있습니다.


<?php

require_once("../dbconfig.php");

/* 페이징 시작 */

//페이지 get 변수가 있다면 받아오고, 없다면 1페이지를 보여준다.

if(isset($_GET['page'])) {

$page = $_GET['page'];

} else {

$page = 1;

}

/* 검색 시작 */

if(isset($_GET['searchColumn'])) {

$searchColumn = $_GET['searchColumn'];

$subString .= '&amp;searchColumn=' . $searchColumn;

}

if(isset($_GET['searchText'])) {

$searchText = $_GET['searchText'];

$subString .= '&amp;searchText=' . $searchText;

}

if(isset($searchColumn) && isset($searchText)) {

$searchSql = ' where ' . $searchColumn . ' like "%' . $searchText . '%"';

} else {

$searchSql = '';

}

/* 검색 끝 */

$sql = 'select count(*) as cnt from board_free' . $searchSql;

$result = $db->query($sql);

$row = $result->fetch_assoc();

$allPost = $row['cnt']; //전체 게시글의 수

if(empty($allPost)) {

$emptyData = '<tr><td class="textCenter" colspan="5">글이 존재하지 않습니다.</td></tr>';

} else {


$onePage = 15; // 한 페이지에 보여줄 게시글의 수.

$allPage = ceil($allPost / $onePage); //전체 페이지의 수

if($page < 1 && $page > $allPage) {

?>

<script>

alert("존재하지 않는 페이지입니다.");

history.back();

</script>

<?php

exit;

}

$oneSection = 10; //한번에 보여줄 총 페이지 개수(1 ~ 10, 11 ~ 20 ...)

$currentSection = ceil($page / $oneSection); //현재 섹션

$allSection = ceil($allPage / $oneSection); //전체 섹션의 수

$firstPage = ($currentSection * $oneSection) - ($oneSection - 1); //현재 섹션의 처음 페이지

if($currentSection == $allSection) {

$lastPage = $allPage; //현재 섹션이 마지막 섹션이라면 $allPage가 마지막 페이지가 된다.

} else {

$lastPage = $currentSection * $oneSection; //현재 섹션의 마지막 페이지

}

$prevPage = (($currentSection - 1) * $oneSection); //이전 페이지, 11~20일 때 이전을 누르면 10 페이지로 이동.

$nextPage = (($currentSection + 1) * $oneSection) - ($oneSection - 1); //다음 페이지, 11~20일 때 다음을 누르면 21 페이지로 이동.

$paging = '<ul>'; // 페이징을 저장할 변수

//첫 페이지가 아니라면 처음 버튼을 생성

if($page != 1) { 

$paging .= '<li class="page page_start"><a href="./index.php?page=1' . $subString . '">처음</a></li>';

}

//첫 섹션이 아니라면 이전 버튼을 생성

if($currentSection != 1) { 

$paging .= '<li class="page page_prev"><a href="./index.php?page=' . $prevPage . $subString . '">이전</a></li>';

}

for($i = $firstPage; $i <= $lastPage; $i++) {

if($i == $page) {

$paging .= '<li class="page current">' . $i . '</li>';

} else {

$paging .= '<li class="page"><a href="./index.php?page=' . $i . $subString . '">' . $i . '</a></li>';

}

}

//마지막 섹션이 아니라면 다음 버튼을 생성

if($currentSection != $allSection) { 

$paging .= '<li class="page page_next"><a href="./index.php?page=' . $nextPage . $subString . '">다음</a></li>';

}

//마지막 페이지가 아니라면 끝 버튼을 생성

if($page != $allPage) { 

$paging .= '<li class="page page_end"><a href="./index.php?page=' . $allPage . $subString . '">끝</a></li>';

}

$paging .= '</ul>';

/* 페이징 끝 */

$currentLimit = ($onePage * $page) - $onePage; //몇 번째의 글부터 가져오는지

$sqlLimit = ' limit ' . $currentLimit . ', ' . $onePage; //limit sql 구문

$sql = 'select * from board_free' . $searchSql . ' order by b_no desc' . $sqlLimit; //원하는 개수만큼 가져온다. (0번째부터 20번째까지

$result = $db->query($sql);

}

?>

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8" />

<title>자유게시판 | Kurien's Library</title>

<link rel="stylesheet" href="./css/normalize.css" />

<link rel="stylesheet" href="./css/board.css" />

</head>

<body>

<article class="boardArticle">

<h3>자유게시판</h3>

<div id="boardList">

<table>

<caption class="readHide">자유게시판</caption>

<thead>

<tr>

<th scope="col" class="no">번호</th>

<th scope="col" class="title">제목</th>

<th scope="col" class="author">작성자</th>

<th scope="col" class="date">작성일</th>

<th scope="col" class="hit">조회</th>

</tr>

</thead>

<tbody>

<?php

if(isset($emptyData)) {

echo $emptyData;

} else {

while($row = $result->fetch_assoc())

{

$datetime = explode(' ', $row['b_date']);

$date = $datetime[0];

$time = $datetime[1];

if($date == Date('Y-m-d'))

$row['b_date'] = $time;

else

$row['b_date'] = $date;

?>

<tr>

<td class="no"><?php echo $row['b_no']?></td>

<td class="title">

<a href="./view.php?bno=<?php echo $row['b_no']?>"><?php echo $row['b_title']?></a>

</td>

<td class="author"><?php echo $row['b_id']?></td>

<td class="date"><?php echo $row['b_date']?></td>

<td class="hit"><?php echo $row['b_hit']?></td>

</tr>

<?php

}

}

?>

</tbody>

</table>

<div class="btnSet">

<a href="./write.php" class="btnWrite btn">글쓰기</a>

</div>

<div class="paging">

<?php echo $paging ?>

</div>

<div class="searchBox">

<form action="./index.php" method="get">

<select name="searchColumn">

<option <?php echo $searchColumn=='b_title'?'selected="selected"':null?> value="b_title">제목</option>

<option <?php echo $searchColumn=='b_content'?'selected="selected"':null?> value="b_content">내용</option>

<option <?php echo $searchColumn=='b_id'?'selected="selected"':null?> value="b_id">작성자</option>

</select>

<input type="text" name="searchText" value="<?php echo isset($searchText)?$searchText:null?>">

<button type="submit">검색</button>

</form>

</div>

</div>

</article>

</body>

</html>


이번에도 빨간색으로 적혀진 부분이 수정된 부분입니다.

전체적인 코드는 길지만 전에 설명했던 부분이므로 빨간색 코드 부분만 설명 드리겠습니다.


/* 검색 시작 */


if(isset($_GET['searchColumn'])) {

$searchColumn = $_GET['searchColumn'];

$subString .= '&amp;searchColumn=' . $searchColumn;

}

if(isset($_GET['searchText'])) {

$searchText = $_GET['searchText'];

$subString .= '&amp;searchText=' . $searchText;

}


if(isset($searchColumn) && isset($searchText)) {

$searchSql = ' where ' . $searchColumn . ' like "%' . $searchText . '%"';

} else {

$searchSql = '';

}


/* 검색 끝 */


$sql = 'select count(*) as cnt from board_free' . $searchSql;


검색 시작부분부터 보면 searchColumn이라는 GET 변수와 searchText라는 GET 변수를 받아왔습니다.

거기에 $subString이라는 아직은 뭔지 이해 하기 힘든 변수가 하나 있긴 한데요,

뒷 부분에서 사용되는 변수입니다.

일단은 &amp;가 &(엠퍼센트)라는 것만 알고 넘어가시면 되겠습니다.


그 다음 $searchColumn과 $searchText 변수가 선언되어있다면, $searchSql을 선언합니다.

선언 되어있지 않았을 때 ''(공백)을 넣는 이유는 아래 있는 $sql을 보면 나와있습니다.


만약 $searchSql에 값이 있다면,

$sql은 'select count(*) as cnt from board_free where ' . $searchColumn .' like "%' . $searchText . '%"';가 되고,

값이 없다면,

$sql은 'select count(*) as cnt from board_free가 되겠죠?


이런 작업을 통해서 검색 시에는 기존과는 다른 결과를 볼 수 있게 되는겁니다.


if(empty($allPost)) {

$emptyData = '<tr><td class="textCenter" colspan="5">글이 존재하지 않습니다.</td></tr>';

} else {

}


이 코드는 검색 기능을 넣으면서 글이 없을 때 문제가 있어서 추가한 부분입니다.

만약 $allPost의 값이 0이라면 글이 존재하지 않습니다. 라는 결과를 출력하게 만들었습니다.


$allPost가 0이 아니라면 정상적으로 실행이 되는거구요.


$paging .= '<li class="page page_start"><a href="./index.php?page=1' . $subString . '">처음</a></li>';

$paging .= '<li class="page page_prev"><a href="./index.php?page=' . $prevPage . $subString . '">이전</a></li>';

$paging .= '<li class="page"><a href="./index.php?page=' . $i . $subString . '">' . $i . '</a></li>';

$paging .= '<li class="page page_next"><a href="./index.php?page=' . $nextPage . $subString . '">다음</a></li>';

$paging .= '<li class="page page_end"><a href="./index.php?page=' . $allPage . $subString . '">끝</a></li>';


$sql = 'select * from board_free' . $searchSql . ' order by b_no desc' . $sqlLimit;


else 부분에서 수정된 코드들입니다.


먼저 $paging 변수에는 모두 $subString이라는 변수를 추가했는데요.

검색이 없었을 때의 목록이였다면 별 문제가 없지만 GET변수를 통해서 searchColumn과 searchText를 받아오게 될 때는 문제가 생깁니다.

검색을 해도 페이징이 생길 수 있는데, 만약 $subString을 사용하지 않으면 다른 페이지로 넘어간 순간 두 GET 변수가 사라지고,

그냥 일반 목록의 페이지가 표시되어버리는거죠.


여기서 위에서 선언한 $subString('&amp;searchColumn=' . $searchColumn . '&amp;searchText=' . $searchText;가 있으면

모든 페이지에 GET 변수인 검색 부분이 함께 따라오게 되고, 해당 검색어에 대한 결과 값이 정상적으로 보여집니다.


$sql 부분은 위에 있던 $sql처럼 검색에 대한 $searchSql을 추가해줬습니다.

이 부분을 넣음으로써 목록이 검색어에 관한 결과로 바뀝니다.


if(isset($emptyData)) {

echo $emptyData;

} else {

}


<div class="searchBox">

<form action="./index.php" method="get">

<select name="searchColumn">

<option <?php echo $searchColumn=='b_title'?'selected="selected"':null?> value="b_title">제목</option>

<option <?php echo $searchColumn=='b_content'?'selected="selected"':null?> value="b_content">내용</option>

<option <?php echo $searchColumn=='b_id'?'selected="selected"':null?> value="b_id">작성자</option>

</select>

<input type="text" name="searchText" value="<?php echo isset($searchText)?$searchText:null?>">

<button type="submit">검색</button>

</form>

</div>


마지막으로 $emptyData와 #searchBox입니다.


$emptyData는 위에서 생성했던 글이 존재하지 않습니다.라는 결과를 출력해주는 부분입니다.

$emptyData가 없다면 정상 실행 되는거구요.


그리고 #searchBox 부분은 검색 기능을 담당할 select 태그와 input 태그로 구성되어있습니다.

이 부분에 검색을 하게 되면 위에서 프로그래밍 해둔 부분이 실행 되고, 목록의 결과가 바뀌게 되는거죠.



위의 이미지는 제목에 1이 포함된 글을 출력한 부분입니다.

먼저 URL을 보시면 searchColumn과 searchText에 값이 존재하는 것을 알 수 있죠?

각각 b_title과 1이라는 값이 있고, 아래 검색 폼에도 같은 내용이 있습니다.


그 아래 URL을 보시면 page=2&searchColumn=b_title&searchText=1이라는 값이 들어있는데,

이 부분은 페이징에서 2 페이지 부분에 마우스를 댔을 때 나오는 부분입니다.


위에서 $subString 부분을 넣었기 때문에 검색에 관한 GET 변수도 함께 들어가게 된겁니다.


어렵다고 생각하실 수 있지만 여러번 읽어보시는 수밖에 없구요.

이해가 안되는 부분이 있다면 댓글 남겨주시면 최대한 빠르게 답변 해드리겠습니다^^

TAG ,
  1. 윤필재 2015.04.20 09:54 신고  댓글주소  수정/삭제  댓글쓰기

    PHP 프로그래밍이라는 책보면서 따라치기 바빠서 이해를 못해도 그냥 결과만 나오게 만들었더니
    전 한계가 온듯하네요ㅋㅋ
    지식인과 함께 MSSQL이랑 하고 있는데 어찌저찌 리스트 수정 저장 삭제 까지는 했는데
    조건검색기능 추가 하려니 뭔 말인지도 모르겠고 내가 저걸 왜 쳤는지도 모르겠고ㅋㅋ
    그냥 주저리주저리 해봤습니다.
    여튼 감사합니다. 이글 계속 들여다 보면 답이 나오겠죠 뭐ㅎㅎ

    • Kurien 2015.04.20 09:57 신고  댓글주소  수정/삭제

      따라 치기만 해서는 실행은 되더라도 다음번에 다시 사용하기도 힘들고, 수정도 맘대로 하기 힘듭니다.

      어려운 부분은 말씀 해주시면 설명해드릴테니 꼭 이해 하고 넘어가는게 중요합니다.

  2. 김준현 2015.04.21 03:39 신고  댓글주소  수정/삭제  댓글쓰기

    항상 좋은 강좌 감사히 보고 있습니다 ^^

    $searchSql=' where ' . $searchColumn . ' like "%' . $searchText . '%"';

    구문에서 parse에러가 나옵니다.
    T_CONSTANT_ENCAPSED_STRING 에러인데 php버전은5.2.12 입니다.

    어떤문제일까요?

    • Kurien 2015.04.21 09:10 신고  댓글주소  수정/삭제

      이 부분만으로는 오류를 알 수가 없습니다.
      이 부분에서 오류가 나온다고 출력이 되더라도 다른 부분에 문제가 있을 가능성이 더 높습니다.

      김준현님이 받은 파일에 dbconfig.php라는 파일이 있는지 확인해보시고, 있다면 혹시 수정하신 부분이 있는지와 수정하신 부분도 없다면 그 파일 전체 압축하신 후에 kurien92@gmail.com으로 보내주시면 확인해보겠습니다.

  3. 윤필재 2015.04.21 10:31 신고  댓글주소  수정/삭제  댓글쓰기

    kurien님 제가 메일 한통을 보내었는데 시간 나시면 한번 확인 해주시면 감사하겠습니다...

  4. 윤필재 2015.04.21 13:11 신고  댓글주소  수정/삭제  댓글쓰기

    메일 잘 받았습니다. 바쁘실텐데 시간내셔서 답장해주신점 정말 감사드립니다.
    늘 건강하시고 행복하십시오!!

  5. php입문 2015.06.25 14:25 신고  댓글주소  수정/삭제  댓글쓰기

    게시판 글작성할때 아무내용도 입력하지 안아도 그냥 넘어가는걸 수정하려면 어디를 해야할까요 ???... ㅜ

  6. dsfsdfad 2015.07.06 19:37 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요
    리스트 로직이 MYSQL에서 모든 정보를 받아와서 페이징을 시작하는데
    MYSQL단에서 내가 원하는 데이터만 고르는 페이징이 이루어져야 하는것 아닌가요?
    비효율적인것 같아 문의드립니다.

    • Kurien 2015.07.06 23:29 신고  댓글주소  수정/삭제

      mysql에서 모든 정보를 받아와서 페이징을 시작한다는게 이해가 안되네요.
      limit문을 통해서 해당되는 부분만 가져왔는데, 어느 부분에서 비효율적이라고 하신건지 이해가 잘 안됩니다.
      제가 잘 모르는 부분이 있다면 댓글에 남겨주세요!

  7. 게시판 입문 2015.09.15 23:40 신고  댓글주소  수정/삭제  댓글쓰기

    잘 보고 있습니다^^
    에러가 두 개인데 모두 정의되지 않은 변수에 관한것입니다. $subString, $searchColumn 부분인데요 $subString까지 묶어서 시작할 때 null값으로 정의를 해주면 에러는 없어집니다. 또한 마지막 select 옵션부분에서 php코드 자체가 필요한가 하는 생각이 듭니다.검색을 버튼을 눌러야 $searchColumn에 값이 들어가는데 미리 그 값을 비교해주는게 약간 이상하게 보여서요^^;; 아니면 에러가 날 수 있기 때문에 일부러 코드를 삽입하신건가요?

    • Kurien 2015.12.09 14:57 신고  댓글주소  수정/삭제

      포스팅을 했을 때 너무 대충 만들어서... 여러가지 간과했던게 많습니다.
      $subString 같은것들은 해당 페이지 시작부분에 말씀하신것처럼 $subString = '' 또는 null 등과 같은걸로 초기화 해주시면 되는 문제구요.

      select 옵션부분에서 php 코드를 넣은 이유는 php 코드를 넣지 않게되면 검색 시 내용을 기준으로 검색을 해도 제목이 맨 위로 올라오게 됩니다.

      이 부분은 직접 해보시는 편이 이해가 빠를 것 같네요.

  8. DH 2015.11.30 14:17 신고  댓글주소  수정/삭제  댓글쓰기

    댓글수는 제목 옆에 표시 못하나요?

    • Kurien 2015.12.09 14:57 신고  댓글주소  수정/삭제

      댓글 수는 mysql의 count 함수를 써서 가져오시거나, 따로 게시판별 DB를 만들어서 글을 올릴 때 마다 +1, 지워질 때마다 -1을 해주시고 그 값을 가져오시면 됩니다.

  9. KANA 2016.10.27 14:33 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요, 궁금한 점이 있어 문의 드립니다.

    통합검색, 즉 내용, 닉네임 등등..을 모두 검색 할 수 있는 방법이 있을까요?

    • Kurien 2016.10.27 15:02 신고  댓글주소  수정/삭제

      아무런 조건을 말씀하시지 않고 가능하냐 안하냐 말씀하시면 당연히 가능합니다.

      혼자 집을 지을 수 있는가? 란 질문에 조건이 없다면 가능하지 않을까요?

  10. KANA 2016.10.31 10:45 신고  댓글주소  수정/삭제  댓글쓰기

    헙 ㅠㅠ 죄송합니다.
    제가 생각하는 내용 전달을 잘못드렸네요..

    지금 SQL부분을 보면 $searchSql = ' where ' . $searchColumn . ' like "%' . $searchText . '%"'; 이런식으로 구성이 되어 있는데, $searchColumn 지금 하나 있는 컬럼을 컬럼을 두개로 검색하고 싶어요. 즉 id와 title 두개를 동일한 키워드로 검색을 하려면 어떤식으로 이 부분을 짜야하나요?

    강의 잘 보고 있습니다 ㅜㅜ 감사합니다.

    • Kurien 2016.11.01 00:12 신고  댓글주소  수정/삭제

      말씀하신 부분을 SQL로 작성하자면, select * from table where column1 like "%text%" or column2 like "%text%";
      일 듯 합니다.

      사이에 있는 것이 or 이 아니라 and라면 column1과 2 모두에 포함되어야 하구요.

      프로그램으로 위와 같은 쿼리를 제작하시려면, $searchColumn을 "|"와 같은 특수 기호를 구분자로 만들어서 해당 구분자로 column1과 column2로 나누어 사용하시면 될 것 같네요.

  11. Rothko 2016.11.10 22:37 신고  댓글주소  수정/삭제  댓글쓰기

    Kurien님 만약 검색조건에 맞는 글이 존재 하지 않을 때 페이징 부분을 나오지 않게 하기 위해서는 <div class="paging"><?= $paging ?></div> 이 부분도 if(isset($emptyData){ }else{ } 문으로 감싸주면 되겠죠?? (3일동안 Kurien님 블로그보면서 공부 잘하고 있습니다. 감사합니다.^^)

  12. Robushy 2016.12.26 16:27 신고  댓글주소  수정/삭제  댓글쓰기

    처음부터 따라서 하다보니 여기까지 왔네요 ..ㅠㅠ 전 PDO방식으로 한다고 꽤나 고생해서..여기까지왔네요
    다름이 아니라..여기서..만약에 게시물이 하나도 없을경우는

    Notice: Undefined variable: paging in C:\xampp\htdocs\test.php on line 196

    이렇게 $paging에서 에러가 나거등요... 생각해보니.. 당연히 아무것도없으면 에러가 나올것같은데..

    글이 0개부터 페이징 1로 시작할수는 없을까요?...어디다가 수정및소스추가를 무엇을 해야할지 ㅠㅠ

    • 익명의개발자 2016.12.27 04:34 신고  댓글주소  수정/삭제

      같은날 같은 고민을 하다가 보고 답변남겨요~

      board.php에 있는 부분 수정하시면 생각하시는대로 작동할꺼에요~

      if(empty($allPost)) {
      $emptyData = '<tr><td class="textCenter" colspan="5">글이 존재하지 않습니다.</td></tr>';
      //추가된 부분
      $paging = '<ul>';
      $paging .= '<li class="page current">1</li>';
      $paging .= '</ul>';
      //추가된 부분
      }

      추가된 부분이라고 주석처리된 부분을 추가해주시면 되요~

    • Kurien 2017.01.11 14:24 신고  댓글주소  수정/삭제

      연말, 연초를 맞아서 여러모로 바빠서 관리를 못했네요 ㅠㅠ

      대신 답변 달아주셔서 감사합니다!

  13. Robushy 2016.12.27 08:56 신고  댓글주소  수정/삭제  댓글쓰기

    와우!!감사합니다 익명의 개발자님!!! ㅠㅠ