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

2015. 3. 31. 00:21
저자 : Kurien

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

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


오늘은 본격적으로 게시판 제작에 들어가겠습니다.

설명하기 전에 현재까지 진행 된 코드를 올렸습니다.


20150330_project.zip


여기 있는 dbconfig.php는 더 이상 올리지 않을 생각이구요.

따라하고 계신분은 이 dbconfig.php 파일에서 DB 호스트, DB 아이디, DB 패스워드, DB 이름을 바꿔서 실행하시면 되겠습니다.


CSS의 경우 디자인을 못하기 때문에... ㅠㅠ 최소한으로만 할꺼구요.

디자인 부분은 개인적으로 만들어서 사용하시면 되겠습니다.


먼저 dbconfig.php부터 살펴보겠습니다.


<?php

$db = new mysqli('localhost', 'kurien', '********', 'kurien');


if($db->connect_error) {

die('데이터베이스 연결에 문제가 있습니다.\n관리자에게 문의 바랍니다.');

}


$db->set_charset('utf8');

?>


dbconfig.php는 짧게 만들어놨습니다.

먼저 $db에 mysql을 연결해줍니다.

저와 같이 new mysqli를 쓰던지, mysqli_connect()를 쓰던지 그 부분은 자유입니다.

개인적으로는 new mysqli()가 편하니 이걸로 진행하겠습니다.


각 항목은 위에서 말한 것처럼 DB 호스트, DB 아이디, DB 패스워드, DB 이름 순으로 나열되어있습니다.

큰 이상이 없다면 DB와 연동되었다고 생각하시면 되는데, 만약 DB가 연결되지 않는다면 오류를 출력해줍니다.


여기서 if($db->connect_error) { }는 DB 연동이 실패했을 때 예외를 처리해주는 부분입니다.

여기서는 die()함수를 통해서 메시지를 보여주고 PHP를 종료하게 됩니다.


마지막 줄의 $db->set_charset('utf8')은 해당 DB와의 연결을 어떤 인코딩으로 할지 정해줍니다.

요즘은 UTF-8을 많이 쓰므로 utf8을 적었습니다.


참고로 제가 게시판을 만들면서 제작한 모든 인코딩은 UTF-8입니다.

만약 한글이 깨진다면 인코딩 문제를 의심해주세요!


이제 dbconfig.php에 대한 설명이 끝났으니 board 폴더에 있는 index.php를 열어봅시다.


<?php

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

?>

<!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>

<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

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

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

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"><?php echo $row['b_title']?></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>

</article>

</body>

</html>


별다른 기능도 없이 길기만 한 코드입니다.

먼저 맨 위에서 require_once를 통해서 dbconfig.php를 include 시켜줍니다.


여기서 include가 아닌 require_once를 쓴 이유는 dbconfig.php가 연동되지 않는다면 이 게시판을 볼 필요조차 없기 때문이죠.

만약 include 함수를 사용하면 dbconfig.php를 include에 실패 하더라도 이 페이지를 보여줄 수 있는 만큼 보여주고,

require 함수를 사용하면 dbconfig.php를 include에 실패하면 오류를 보내고 그대로 종료합니다.


그리고 그냥 include, require과 include_once, require_once의 차이점은 include, require의 경우 같은 파일을 여러번 include 해도 실행되지만,

once가 뒤에 붙게 되면 딱 한번만 include 되고 그 뒤의 같은 파일은 무시됩니다.

이렇게 dbconfig.php를 include 시키고, 기본적인 html들을 적어줍니다.


기본적인 html이나 css부분은 넘어가고 바로 table 부분으로 넘어가겠습니다.

caption은 웹 접근성을 지켜볼까 해서 넣은건데, readHide라는 클래스를 줘서 나중에 보이지 않게 할 생각이구요.


thead 부분을 보면 게시판에서 필요한 항목 중 list 부분에 필요한 항목을 th로 출력해줬습니다.

번호, 제목, 작성자, 작성일, 조회 순으로 지정했고, 그 아래 있는 tbody 부분부터 PHP 코드가 많이 사용됩니다.


먼저 $sql에 DB에 보낼 쿼리문을 작성합니다.

select * from board_free order by b_no desc;라는 쿼리문을 DB에 보냅니다.


가장 쉬운 select 문인데다가 어려운 부분도 없습니다.

혹시 모르는 분을 위해서 설명드리자면 이전 포스팅에서 만들었던 board_free 테이블에서 *(모든 column)을 가져오는겁니다.

그리고 마지막에 있는 order by b_no desc는 내림차순을 뜻하는건데요.

만약 내림차순이 아니라면 primary key(기본 키)를 기준으로 자동으로 오름차순 정렬이 됩니다.



이 이미지를 보면 위에서부터 1, 2, 3이 나오는데 정상적인 게시판이라면 3, 2, 1 순으로 나타나게 됩니다.

오래된 글일수록 뒤로 가야하니깐요.


아래는 order by b_no desc을 적은 후의 이미지입니다.



번호를 보면 정상적으로 나오죠?

이해가 잘 안된다면 작성일을 보시면 이해가 더 쉽게 될 것 같네요.

여기서 시간(22:17:12)만 나온 부분은 오늘 날짜를 나타내는거니, 2015-03-30이라고 생각하시면 되겠습니다.

$sql을 만들었으니 $result = $db->query($sql)을 통해 query를 보내고 결과 값을 $result에 저장합니다.

만약 이 과정에서 문제가 생겼다면 $result에는 FALSE가 들어가고, 정상적으로 query가 전송되었다면 $result에 TRUE가 들어갑니다.


이제 $row = $result->fetch_assoc()을 쓰는데요.

이 부분을 반복문 while($row = $result->fetch_assoc()) { }로 나타내면 보냈던 쿼리의 행이 끝날 때까지 자동으로 반복을 실행합니다.

제 DB에는 "안녕하세요!", "안녕하세요! 2", "테스트"라는 제목을 가진 데이터 3행이 있으니 총 3번 반복해주죠.


while문 내에는 $datetime = explode(' ', $row['b_date']);가 제일 먼저 있는데요.

$row['b_date']는 위에서 $row = $result->fetch_assoc()를 통해 얻은 DB의 데이터가 $row라는 배열에 저장된 것입니다.

배열의 key(b_date)는 column의 이름을 나타내구요.


$row['b_date']를 explode 함수를 통해 ' ' 값을 기준으로 나눈 이유는 b_date의 값은 "0000-00-00 00:00:00"과 같은 형식으로 저장되는데,

공백 기준 왼쪽에 있는 일자(년월일)와 오른쪽에 있는 시간(시분초)를 따로 나눠주기 위해서였습니다.


두 값을 나누면 $datetime[0]과 $datetime[1]에 저장되고, 다시 그 값들은 $date와 $time 변수에 저장됩니다.

여기서 만약 $date의 값이 date('Y-m-d')(오늘의 날짜)와 같다면 $row['b_date']의 값을 $time으로 바꿔주고,

오늘과 다른 날짜라면 $row['b_date']의 값을 $date로 바꿔줍니다.


여기서 이렇게 나눠줬기 때문에 작성일이 오늘인 글은 시간이 나타나게 됩니다.


이제 목록에 내용을 뿌려줄 일만 남았네요.

여기서 반복되어야 할 부분은 <tr>~</tr> 까지입니다.


순서대로 b_no, b_title, b_id, b_date, b_hit를 출력하시면 됩니다.

데이터베이스에 입력을 안하셨다면 입력을 하신 후 진행해보세요!


여기까지 list 제작 1이였습니다.

너무 세세한 것까지 설명해드려서 너무 글이 길어졌는데, 오히려 그걸로 인해 복잡할 수도 있을 것 같네요.

지적 사항이 있거나 글이 너무 어렵다면 댓글 남겨주시구요.


현재 진행 상태는 http://kurien.dothome.co.kr에서 확인하실 수 있습니다.


  1. 이전 댓글 더보기
  2. 직딩1 2016.07.22 13:39  댓글주소  수정/삭제  댓글쓰기

    답변 감사합니다.
    버전 업그레이드를 했더니 해결됐어요...
    APM을 쓰고 있었는데 버전이 너무 낮아서 그럴 수도 있다는 말을 듣고 XAMPP로 갈아탔습니다. ㅎㅎ

    추가로 CSS에 관한 것입니다만,
    운영자님께서 올리신 압축 파일 속 css 폴더와 관련 코드를 복붙했는데 이미지처럼 안 나오더라구요...
    폰트는 바뀌었지만 테이블 라인이 하나도 안 나오는데 어떻게 해야 될까요? ㅠㅠ
    이미지의 레이아웃이 너무 맘에 들어서요...
    답변 부탁드립니다.

  3. 안녕하세요 2016.10.03 02:29  댓글주소  수정/삭제  댓글쓰기

    list 만들기를 그대로 따라해봤는데요 제대로 리스트가 나오긴하는데..

    query($sql); 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; ?>

    이 코드가 웹 화면에 나오네요..

    이유를 알고계신가요??

    • Kurien 2016.10.04 10:03 신고  댓글주소  수정/삭제

      맨 앞의 query($sql); 앞에 mysqli->가 아니라 mysqli?>라고 적혀있는지 확인해보시고, 그 문제가 아니라면 kurien92@gmail.com으로 전체 코드 보내주시면 확인 후 말씀 드리겠습니다.

  4. 게시판! 2016.10.17 04:06  댓글주소  수정/삭제  댓글쓰기

    저도 앞서 다른 사람들이 말한것처럼 Fatal error: Call to a member function fetch_assoc() on boolean 라고 에러가 뜨네요. if문 사용해서 어디서부터 에러가 낮는지 찾어보니깐 php에서 board_free 테이블로 연결이 안되는게 문제인것 같은데 이 문제를 해결할 방법이 있나요?

    • Kurien 2016.10.17 13:33 신고  댓글주소  수정/삭제

      phpinfo()를 확인하셨을 때 mysqli 모듈이 포함되어 있는지 확인하셔야합니다.

      mysqli 모듈이 없다면, 서버상에서 설치하시거나 호스팅이시라면 호스팅사에 문의하셔야합니다.

      모듈 없이 진행하시려면 해당 mysqli에 맞는 mysql 함수로 변경해주셔야하구요.

  5. 요요 2016.10.20 09:10  댓글주소  수정/삭제  댓글쓰기

    한번 올려보아요
    안녕하세요

    반갑습니다

  6. 요요 2016.10.27 17:57  댓글주소  수정/삭제  댓글쓰기

    한번 올려보아요
    안녕하세요

    반갑습니다

  7. Rothko 2016.11.07 23:35  댓글주소  수정/삭제  댓글쓰기

    오오 PHP 공부하면서 게시판 만들기좀 배울려고 구글링 하다가 들어왔습니다.!!
    설명 하나하나가 주옥같고, 이해도 잘 됩니다. 따라하해보기도 쉽고요!!
    감사합니다. 정말 , 덕분에 좋은 공부 할 수 있습니다.^^

  8. j 2016.11.07 23:39  댓글주소  수정/삭제  댓글쓰기

    안녕하세요

    위의 게시물을 따라 게시판을 만들고 있는 한 사람인데요

    오류가 났지만 해결을 하기 힘든 상황입니다.

    혹시 실례가 되지 않으신다면 이메일을 알려주실 수 있으신가요?

  9. 자색고구마 2016.11.18 11:26  댓글주소  수정/삭제  댓글쓰기

    와 감사합니다. 엄청난 글이군요.
    php 이제 맛 시작해볼려고하는데 이런 갓 글을 발견했네요.
    위 댓글에 어렵다고 하시는 분들 아주 기본적인 서버 세팅없이 db를 사용하시려고 한 것 같은데
    최소한 서버에 phpMyAdmin 설치는 하셨는지 의문이 가네요.

    아무튼 이제 시작인데 미리 감사감사 드립니다.
    지금 리스트 뷰 라이트 까지 했는데 아주 잘되네요 ^^
    짱짱맨

  10. 궁금 2016.11.21 16:42  댓글주소  수정/삭제  댓글쓰기

    안녕하세요? 다른 문제때문에 검색하다 여쭤볼게 있어서 질문 드려요..
    db 연결하는 코드는 dbconfig.php로 따로 만들어서 include 하셨는데
    그럼 db를 닫을때는 어떻게 하나요?
    보통 연결부터 기타 작업까지 한 문서에선
    $conn = mysql_connect($server, $user, $pass);
    으로 쓰고 닫을때는
    mysql_close($conn); 이런 식으로 하던데

    include 할때는 mysql_close(); 이런식으로도 되나요?
    왕초보라 이상한질문 죄송합니다 ^^;

    • Kurien 2016.11.24 10:40 신고  댓글주소  수정/삭제

      그냥 dbconfig.php가 인크루드 된곳 기준으로 아래의 원하는 위치 어디에서든 사용하셔도 됩니다.

      하지만 PHP의 경우에는 페이지 로드가 끝나면 자동으로 mysql_close를 해주므로 크게 신경쓰실 필요는 없습니다^^

  11. PHP좋아요 2017.10.10 12:11  댓글주소  수정/삭제  댓글쓰기

    상세히 설명해주셔서 처음 접하는 사람들에게도 쉽게 다가갈 수 있어서 좋았어요!
    다시 한 번 감사드립니다~!

  12. 안녕하세요 2019.07.14 05:40  댓글주소  수정/삭제  댓글쓰기

    잘보고 갑니다....db에 잘 저장되고 list가 잘 나옵니다..근데 하나씩 누락이 됩니다...3개의 게시글이 있으면 2개만 나오고... 하나더 작성을 하면 누락되었던 글이 추가가 되고 새롭게 작성한 글이 누락됩니다....어딜 손봐야될까요?

    • Kurien 2019.07.16 22:44 신고  댓글주소  수정/삭제

      말씀하신 내용만으로는 알 수 있는 부분이 제한적입니다.

      생각되는 부분은 $row = $result->fetch_assoc(); 해당 코드를 한군데 더 적어두신건 아니신지 확인해보시기 바랍니다.

  13. 전경국 2021.01.31 21:16  댓글주소  수정/삭제  댓글쓰기

    Fatal error: Call to a member function query() on null in /host/home5/joongopc/html/project/index.php on line 32
    $result = $db->query($sql); 이부분이 맴버함수가 틀리다고 나오네요.. 뭐가 틀린지 모르겠어요

  14. 라시나 2022.04.27 22:36  댓글주소  수정/삭제  댓글쓰기

    자애로운 ♬두형이 스파이더맨 벽지까지 맞춰주고 가셨네
    구토들아 구톡방 돌리지마라 ㅋㅋ
    날두 신경 쓸 시간에 느그들 주인님이나 걱정해라 ㅋ
    오늘 인터뷰했는데(당사펌) 이랬음
    2. 윌리안, 2013 (£31.5m)



    이들 중 가장 비싼 영입이다. 2013년 1월에 영입된 [ http://xooxma.com ] 윌리안은 안지에서 11경기 출장에 그쳤고, 그 해 여름 £30m에 첼시로 이적했다.



    3. 사무엘 에투, 2011 (£24.3m)



    가장 비싼 건 아니지만, 확실히 이들 중 가장 미친 딜이다. 에투는 안지에서 세후 연봉 [ http://xooxa.xyz ] €20m을 받으며 세계 축구에서 가장 높은 소득을 자랑하는 선수가 되었다. 그는 73경기에서 26골을 넣었다.



    4. 알렉산드르 코코린, 2013 (£17.1m)



    2013년 여름에 영입한 높은 평가를 받았던 이 러시아 [ http://xooxb.xyz ] 공격수는 안지에서 총 0경기에 출전했고 약 한 달 후 예산 삭감으로 인해 디나모 모스크바로 팔려나갔다. 그는 현재 ACF 피오렌티나에서 뛰고 있다.



    2011년부터 2013년까지 안지 마하치칼라의 미친 돈♪♩♬을 기억하며 - 4.ren.jpg [기브미스포츠] 2011년부터 2013년까지 안지 마하치칼라의 미친 돈♪♩♬을 기억하며

  15. 에드워즈 2022.05.10 15:00  댓글주소  수정/삭제  댓글쓰기

    전 첼시 레프트백은 현재 첼시 아카데미와 잉글랜드 U21팀 코치로 활동 중이다.



    램파드는 그를 구디슨 파크로 데려오기 위해 [ http://xooxc.xyz] 논의했으며, 향후 며칠 안에 결정이 내려질 것으로 예상된다.



    콜은 조 에드워즈(어시스턴트 매니저), 폴 클레먼트(코치) 및 크리스 존스(코치)와 함께 램파드의 팀에 합류하고 이미 클럽에 있었던 던컨 퍼거슨(코치) 및 앨런 켈리(골키퍼 코치)와 함께할 것이다.



    6. 이고르 데니소프, 2013 (£13.5m)



    데니소프는 안지에서 겨우 3경기만 뛰었다. 이후 구단이 자금을 절약하기 [ http://xooxd.xyz ] 위해 그는 코코린과 함께 2013년 8월 디나모 모스크바로 보내졌다. 지난 2019년 5월에 그는 축구를 은퇴했다.



    분데스리가

    조지 벨로(20): 애틀랜타 유나이티드에서 아르미니아 빌레펠트(수비수, 2026년까지 계약)

    스벤 미셸(31): SC 파더보른에서 우니온 베를린으로 (공격수, 2024년까지 계약)

    토비아스 라슐(21): 보루시아 도르트문트에서 [ http://xooxe.xyz ] SpVgg 그로이터 퓌르트로(미드필더, 2024년까지 계약)

    브라이트 아크워 아레이 음비(18)는 바이에른 뮌헨에서 FC 쾰른으로 (수비수, 2023년 여름까지 임대)

    켈리안 은소나(19): SM 캉에서 헤르타 BSC로 (공격수, 2026년까지 계약)

    요나스 빈트(22): FC 코펜하겐에서 VfL 볼프스부르크로 (공격수, 2026년까지 계약)

  16. 분데스 2022.05.14 23:51  댓글주소  수정/삭제  댓글쓰기

    분데스리가 2부

    알루 쿠올(20): VfB 슈투트가르트 II에서 SV 산트하우젠으로 (공격수, 여름까지 임대)

    모리스 드빌(29): FC 자르브뤼켄에서 SV [ http://xooxf.xyz ] 산트하우젠으로 (공격수, 2022년 여름까지 계약)

    톰 트리불 (28): 하노버 96에서 SV 산트하우젠으로 (미드필더, 계약 기간 미상)

    에리히 베르코(27): 다름슈타트 98에서 SV 산트하우젠으로 (공격수, 계약 기간 미상)

    케말 아데미(26): FK 침키에서 SC 파더보른 07 ([ http://xooxg.xyz ] 공격수, 2022년 여름까지 계약)

    아드리안 파인(22): 바이에른 뮌헨에서 디나모 드레스덴으로 (미드필더, 여름까지 임대)

    마리우스 리제강(22): . FSV 마인츠 05 II에서 다이나모 드레스덴으로 (골키퍼, 2022년 여름까지 계약)

    다니엘로 시칸(20): 샤흐타르 도네츠크에서 한자 로스토크로 (공격수, 여름까지 임대)

    벤자민 골러(23): 베르더 브레멘에서 칼스루에 SC로 (공격수, 여름까지 임대)

    이동경(24) : 울산 현대에서 샬케 04로 (미드필더, [ http://xooxma.com ] 여름까지 임대)

    니클라스 시프노스키(24) : 포르투나 뒤셀도르프에서 얀 레겐스부르크로 (공격수, 2023년 여름


    까지 임대)

  17. 코카티비 2022.05.18 15:20  댓글주소  수정/삭제  댓글쓰기

    스포츠중계 LIVE 코카티비 cokatv.com 가입x 무료웹툰 성인자료 분석정보 구글검색 "코카티비" 기프트콘/제휴업체머니/승무패 이벤트

  18. 세바스 2022.05.22 23:09  댓글주소  수정/삭제  댓글쓰기

    3부리그

    세바스티안 뵈셀 (27): 1. FC 자르브뤼켄에서 [ http://xooxa.xyz ] 할리스체스 FC로 (수비수, 2022년 여름까지 계약)

    필리프 줄레흐네어(31) : 클럽이 없다가 할레슈 FC로 (공격수, 2022년 여름까지 계약)

    잘렌 호킨스 (21): FC 잉골슈타트에서 FC 자르브뤼켄로 (미드필더, 여름까지 임대)

    야밀 지베르트(19): 포르투나 뒤셀도르프에서 빅토리아 [ http://xooxb.xyz ] 쾰른으로 (수비수, 여름까지 임대)

    마이크 파이겐스판(26): 헤센 카셀에서 SV 메펜으로 (공격수, 옵션과 함께 2022년 여름까지 계약)

    케빈 라우후트 (32): SGV 프라이베르크 풋볼에서 빅토리아 쾰른으로 (공격수, 계약 기간 미상)

    앤서니 시어(26) : 클럽이 없다가 FSV 즈비카우로 (미드필더, 2022년 여름까지 계약)


    도미니크 코더(21) : 카를스루에 SC에서 발트호프 [ http://xooxc.xyz ] 만하임으로 (공격수, 여름까지 임대)

  19. 코카티비 2022.05.27 05:50  댓글주소  수정/삭제  댓글쓰기

    스포츠중계 LIVE 코카티비 cokatv.com 가입x 무료웹툰 성인자료 분석정보 구글검색 "코카티비" 기프트콘/제휴업체머니/승무패 이벤트

  20. 코카티비 2022.05.30 09:55  댓글주소  수정/삭제  댓글쓰기

    스포츠중계 LIVE 코카티비 cokatv.com 가입x 무료웹툰 성인자료 분석정보 구글검색 "코카티비" 기프트콘/제휴업체머니/승무패 이벤트

  21. 코카티비 2022.06.02 08:12  댓글주소  수정/삭제  댓글쓰기

    스포츠중계 LIVE 코카티비 cokatv.com 가입x 무료웹툰 성인자료 분석정보 구글검색 "코카티비" 기프트콘/제휴업체머니/승무패 이벤트