반응형
이전글 : [PHP] 게시판 만들기 with MVC - 1부 Migration
이전글 : [PHP] 게시판 만들기 with MVC - 2부 Routing
List
이전 포스팅에서 더미로 "index"만 넣었던 index.php 수정합시다.
Model/Post가 없으므로 에러가 발생할 겁니다.
bbs/view/index.php
<?php
use Model\Post;
$post = new Post();
?>
<!doctype html>
<?php
include "part/header.php";
?>
<body>
<div class="m-4">
<h3><a href="/bbs">자유게시판</a></h3>
<div id="write_btn" class="mb-4">
<p class="d-inline">자유롭게 글을 쓸 수 있는 게시판입니다.</p>
<a href="./create">
<button class="btn btn-primary float-right">글쓰기</button>
</a>
</div>
<!--검색-->
<div class="container mt-4 mb-3">
<form action="" method="get">
<div class="row">
<div class="col-md-6 offset-md-3">
<div class="form-inline full-width-form">
<div class="form-group mb-2 flex-fill">
<label for="searchInput" class="sr-only">검색</label>
<input name="search" type="text" class="form-control w-100" id="searchInput"
placeholder="Search"
value="<?= $_GET['search'] ?? '' ?>">
</div>
<button id="searchSubmit" type="submit" class="btn btn-primary mb-2">검색</button>
</div>
</div>
</div>
</form>
</div>
<!-- 게시물 목록 테이블 -->
<table class="table table-bordered">
<thead>
<tr class="text-center">
<th width="80">번호</th>
<th width="300">제목</th>
<th width="100">글쓴이</th>
<th width="80">추천수</th>
<th width="80">조회수</th>
<th width="100">작성일</th>
</tr>
</thead>
<tbody>
<?php
$startPage = 0;
$perPage = 10;
$searchWord = $_GET['search'] ?? '';
// 게시글 목록 가져오기
$posts = $post->getPosts($searchWord, $startPage, $perPage);
if ($posts) {
$bonusIdx = 0;
foreach ($posts as $postInfo) {
/// 30 글자 초과시 ... 저리
$title = $postInfo["title"];
if (strlen($title) > 30) {
// mb_substr: 한글이 깨지지 않도록 해줌
$title = str_replace($postInfo["title"], mb_substr($postInfo["title"], 0, 30, "utf-8") . "...", $postInfo["title"]);
}
?>
<tr>
<td><?= $postInfo['idx']?></td>
<td>
<a href="./read?idx=<?= $postInfo['idx'] ?>">
<?= $title . " [" . $postInfo['reply_count'] . "]"; ?>
<?php if ($postInfo['is_new']) { ?>
<span class="badge badge-primary">new</span>
<?php } ?>
</a>
</td>
<td><?= $postInfo['name'] ?></td>
<td><?= $postInfo['thumbs_up'] ?></td>
<td><?= $postInfo['views'] ?></td>
<td><?= $postInfo['created_at'] ?></td>
</tr>
<?php
}
} else {
echo "<tr><td colspan='6' class='text-center'>게시글이 없습니다.</td></tr>";
}
?>
</tbody>
</table>
</div>
</body>
</html>
Model
이제 데이터베이스와 연결된 기능을 담을 Model에 해당하는 Post를 만들도록 합시다.
이 Model로 Contorller에서 DB 작업을 하거나 View에서 바로 Model를 통해 데이터를 가져와 뿌릴 수 있습니다.
모든 Model이 상속할 BaseModel을 만듭시다.
bbs/Model/BaseModel.php
<?php
namespace Model;
use DB\Connection;
class BaseModel
{
protected $conn;
public function __construct()
{
$this->conn = new connection();
$this->conn = $this->conn->getConnection();
}
}
이제 Post Table과 매핑될 Post Model을 만들어 줍시다.
bbs/Model/Post.php
<?php
namespace Model;
use PDO;
use PDOException;
class Post extends BaseModel
{
public function __construct()
{
parent::__construct();
}
/**
* Post 목록을 가져옵니다.
* @param $search string 검색어
* @param $start int 시작할 데이터의 인덱스
* @param $perPage int 페이지마다 보여줄 데이터 수
* @return array|false
*/
public function getPosts(string $search, int $start, int $perPage)
{
try {
$query = "select p.*,
(SELECT COUNT(*) FROM replies r WHERE r.post_idx = p.idx) AS reply_count,
CASE WHEN TIMESTAMPDIFF(MINUTE, p.created_at, NOW()) <= 1440 THEN 1
ELSE 0 END AS is_new
from posts p
where p.title like :search
order by idx desc limit :start, :perPage";
$stmt = $this->conn->prepare($query);
$stmt->bindValue('search', '%' . ($search ?? '') . '%');
$stmt->bindParam('start', $start, PDO::PARAM_INT);
$stmt->bindParam('perPage', $perPage, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll();
} catch (PDOException $e) {
error_log($e->getMessage());
return [];
}
}
}
Model을 정상적으로 추가했다면 아래와 같이 페이지가 나오게 됩니다.
Create
이제 글 쓰기 페이지를 추가합시다.
bbs/view/create.php
<!doctype html>
<?php
include "part/header.php";
?>
<body>
<div class="m-4">
<div class="container mt-5">
<h3 class="d-inline"><a href="/bbs">자유게시판</a></h3>/<h4 class="d-inline">글 작성</h4>
<p class="mt-1">글을 작성하는 공간입니다.</p>
<form action="/bbs/post/create" method="post">
<div class="form-group">
<label for="title">제목</label>
<input type="text" class="form-control" name="title" placeholder="제목을 입력하세요">
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="name">Name</label>
<input type="text" class="form-control" name="name" placeholder="Name을 입력해주세요.">
</div>
<div class="form-group col-md-6">
<label for="password">Password</label>
<input type="password" class="form-control" name="pw" placeholder="Password를 입력해주세요.">
</div>
</div>
<div class="form-group">
<label for="content">내용</label>
<textarea class="form-control" name="content" rows="5" placeholder="내용을 입력하세요"></textarea>
</div>
<button type="submit" class="btn btn-primary">글쓰기</button>
</form>
</div>
</div>
</body>
</html>
페이지를 추가했으니 Route에서 연결해 줍시다.
조건문을 하나 추가합니다.
bbs/Route/PostRoute.php
<?php
namespace Route;
class PostRoute extends BaseRoute
{
function routing($url): bool
{
// 게시글 목록에 대한 라우팅
if ($this->routeCheck($url, "post/list", "GET")) {
return $this->requireView('index');
} else if ($this->routeCheck($url, "post/create", "GET")) {
return $this->requireView('create');
}else {
return false;
}
}
}
이제 List 페이지에서 글쓰기를 누르면 다음과 같이 글쓰기 페이지가 나옵니다.
반응형
'PHP > Modern PHP' 카테고리의 다른 글
[PHP] 게시판 만들기 with MVC - 5부 Pagination (1) | 2023.12.27 |
---|---|
[PHP] 게시판 만들기 with MVC - 4부 Controller (0) | 2023.12.27 |
[PHP] 게시판 만들기 with MVC - 2부 Routing (0) | 2023.12.26 |
[PHP] 게시판 만들기 with MVC - 1부 Migration (1) | 2023.12.26 |
[PHP] PHP 면접 질문 정리 (1) | 2023.12.08 |