[PHP, MySQL] 웹 페이지 구현

Y·2024년 2월 26일

Web

목록 보기
8/8
post-thumbnail

이전에 작성했던 회원가입, 로그인, 글쓰기, 게시판 페이지에 PHP와 MySQL을 추가해 간단한 웹 페이지를 구현해 보았다.

구현 영상

DB 생성하기

XAMPP 패널에서 Apache와 MySQL을 켜고 phpMyAdmin에 접속해 데이터베이스를 생성한다.

아래 사진과 같이 phpmemo라는 db를 생성한 후, 그 아래에 tb1_member, tb1_post 라는 테이블 두 개를 추가했다.

db.php

DB에 연결하고, 데이터를 조회하거나 삽입, 업데이트, 삭제하는 기능을 하는 함수들로 구성된 가장 중요한 코드이다.

<?php
function db_get_pdo()
{
    $host = 'localhost';
    $port = '3306';
    $dbname = 'phpmemo';
    $charset = 'utf8';
    $username = 'phpmemo';
    $db_pw = "1234";
    $dsn = "mysql:host=$host;port=$port;dbname=$dbname;charset=$charset";
    $pdo = new PDO($dsn, $username, $db_pw);
    return $pdo;
}

function db_select($query, $param=array()){
    $pdo = db_get_pdo();
    try {
        $st = $pdo->prepare($query);
        $st->execute($param);
        $result =$st->fetchAll(PDO::FETCH_ASSOC);
        $pdo = null;
        return $result;
    } catch (PDOException $ex) {
        return false;
    } finally {
        $pdo = null;
    }
}

function db_insert($query, $param = array())
{
    $pdo = db_get_pdo();
    try {
        $st = $pdo->prepare($query);
        $result = $st->execute($param);
        $last_id = $pdo->lastInsertId();
        $pdo = null;
        if ($result) {
            return $last_id;
        } else {
            return false;
        }
    } catch (PDOException $ex) {
        return false;
    } finally {
        $pdo = null;
    }
}

function db_update_delete($query, $param = array())
{
    $pdo = db_get_pdo();
    try {
        $st = $pdo->prepare($query);
        $result = $st->execute($param);
        $pdo = null;
        return $result;
    } catch (PDOException $ex) {
        return false;
    } finally {
        $pdo = null;
    }
}

나머지 코드는 아래와 같다.

1. 회원가입

regist.php

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>회원가입</title>
    <style>
        table {
            margin-left: auto;
            margin-right: auto;
            text-align: left;
        }
        tr {
            height: 40px;
        }
        .info {
            width: 200px;
        }
        .gen {
            text-align: center;
        }
        .button {
            background: lightgreen;
            border: none;
            text-align: center;
            border-radius: 10px;
            height: 40px;
            width: 250px;
        }
    </style>
</head>
<body>
<?php require_once("../inc/header.php"); ?>
    <form method="POST" action="regist.post.php">
        <table>
            <tr>
                <th>
                    <h3><input type="image" src="../image/login1.png"> 회원가입</h3> 
                </th>
            </tr>
            <tr>
                <td>
                    <img src="../image/member1.png">
                    <input type="text" class="info" name="login_id" placeholder="아이디" required>
                </td>
            </tr>
            <tr>
                <td>
                    <img src="../image/member1.png">
                    <input type="text" class="info" name="login_name" placeholder="이름">
                </td>
            </tr>
            <tr>
                <td>
                    <img src="../image/member2.png">
                    <input type="password" class="info" name="login_pw" placeholder="비밀번호" required>
                </td>
            </tr>
            <tr>
                <td>
                    <br><input type="submit" value="회원가입" class="button">
                </td>
            </tr>
        </table>
    </form>
</body>
</html>

regist.post.php

<?php
require_once("../inc/db.php");

$login_id = isset($_POST['login_id']) ? $_POST['login_id'] : null;
$login_pw = isset($_POST['login_pw']) ? $_POST['login_pw'] : null;
$login_name = isset($_POST['login_name']) ? $_POST['login_name'] : null;

// 파라미터 체크
if ($login_id == null || $login_pw == null || $login_name == null){    
    header("Location: regist.php");
    exit();
}

// 회원 가입이 되어 있는지 검사
$member_count = db_select("select count(member_id) cnt from tbl_member where login_id = ?" , array($login_id));
if ($member_count && $member_count[0]['cnt'] == 1){    
    header("Location: regist.php");
    exit();
}

// 비밀번호 암호화
$bcrypt_pw = password_hash($login_pw, PASSWORD_BCRYPT);

// 데이터 저장
db_insert("insert into tbl_member (login_id, login_name, login_pw) values (:login_id, :login_name, :login_pw )",
    array(
        'login_id' => $login_id,
        'login_name' => $login_name,
        'login_pw' => $bcrypt_pw
    )
);

// 로그인 페이지로 이동
header("Location: ../login/login.php");

2. 로그인

login.php

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>로그인</title>
    <style>
        table {
            margin-left: auto;
            margin-right: auto;
            text-align: left;
        }
        td {
            height: 40px;
        }
        .info {
            width: 180px;
        }
        .button {
            background: lightgreen;
            border: none;
            text-align: center;
            border-radius: 10px;
            height: 35px;
            width: 220px;
        }
    </style>
</head>
<body>
    <?php require_once("../inc/header.php"); ?>
    <form method="POST" action="login.post.php">
        <table>
            <tr>
                <th>
                    <h3><img src="../image/login1.png"> ID 로그인</h3> 
                </th>
            </tr>
            <tr>
                <td>
                    <img src="../image/login2.png">
                    <input type="text" class="info" name="login_id" placeholder="아이디">
                </td>
            </tr>
            <tr>
                <td>
                    <img src="../image/login3.png">
                    <input type="password" class="info" name="login_pw" placeholder="비밀번호">
                </td>
            </tr>
            <tr>
                <td>
                    <input type="submit" class="button" value="로그인">
                </td>
            </tr>
        </table>
    </form>
</body>
</html>

login.post.php

<?php
require_once("../inc/db.php");

$login_id = isset($_POST['login_id']) ? $_POST['login_id'] : null;
$login_pw = isset($_POST['login_pw']) ? $_POST['login_pw'] : null;

// 파라미터 체크
if ($login_id == null || $login_pw == null){    
    header("Location: login.php");
    exit();
}

// 회원 데이터
$member_data = db_select("select * from tbl_member where login_id = ?", array($login_id));

// 회원 데이터가 없다면
if ($member_data == null || count($member_data) == 0){
    header("Location: login.php");
    exit();
}

// 비밀번호 일치 여부 검증
$is_match_password = password_verify($login_pw, $member_data[0]['login_pw']);

// 비밀번호 불일치
if ($is_match_password === false){
    header("Location: login.php");
    exit();
}

session_start();
$_SESSION['member_id'] = $member_data[0]['member_id'];

// 목록으로 이동
header("Location: ../board/list.php");

3. 글 목록

list.php

<?php
// 로그인 체크
session_start();
if (isset($_SESSION['member_id']) === false){
    header("Location: /");
    exit();
}

// DB Require
require_once("../inc/db.php");

$member_id = $_SESSION['member_id'];
$post_query = "select post_id, post_content, member_id, insert_date from tbl_post where member_id = ? order by insert_date desc limit 10";
$post_data = db_select($post_query, array($member_id));

$last_post_id = count($post_data) > 0 ? $post_data[count($post_data) - 1]['post_id'] : "0";
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>boardPage</title>
        <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
        <script type="text/javascript">
            function post_delete(post_id){                
                $.post("delete.api.php", {'post_id' : post_id})
                .done(function(result){
                    if (result['result']){
                        alert('삭제되었습니다.');
                        $('#post_' + post_id).remove();
                    }
                });
            }

            function next_list(){
                var last_post_id = $('#last_post_id').val();
                $.post("list.api.php", {'last_post_id' : last_post_id})
                .done(function(result){                    
                    if (result['result'] == false){
                        alert('글을 불러오는 데 실패했습니다.');
                        return;
                    }

                    if (result['post_data'].length == 0){
                        alert("마지막 페이지입니다.");
                        return;
                    }

                    var ul_list_data = $('#ul_list_data');                    
                    for (var i=0;i<result['post_data'].length;i++) {
                        var post = result['post_data'][i];            
                        var append_li = '<li id="post_' + post['post_id'] + '">"';
                        append_li += post['post_content'];
                        append_li += '<input type="button" value="삭제"token operator">+ post['post_id'] + '\');return false;" />';
                        append_li += "</li>";
                        ul_list_data.append(append_li);
                        $('#last_post_id').val(post['post_id']);
                    }
                });
            }
        </script>
        <style>
            h2, li, a {
                text-align: center;
                text-decoration: none;
            }
            .button {
                background-color: rgb(42, 105, 241);
                color: white;
                border: none;
                border-radius: 5px;
                height: 100px;
                width: 200px;
                text-decoration: none;
                padding: 5px 7px;
            }
            .button-container {
                text-align: right;
                margin-right: 100px;
                margin-bottom: 20px;
            }
            .button-container2 {
                text-align: center;
                margin-top: 20px;
            }
            table {
                width: 80%;
                text-align: center;  
                margin-left: auto;
                margin-right: auto;  
            }
            th {
                padding-bottom: 15px; 
                border-bottom: 2px solid rgb(228, 228, 228);
            }
        </style>
    </head>
    <body>
        <?php require_once("../inc/header.php"); ?>
            <h2>게시판</h2>
            <div class="button-container">
                <a href="write.post.php" class="button"> 글 쓰기 </a>
            </div>
            <table class="table-container">
                <thead>
                    <tr>
                        <th>NO</th>
                        <th style="width:450px;">내용</th>
                        <th>작성자</th>
                        <th>작성일</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    <?php
                    foreach($post_data as $post){                
                    ?>
                    <tr id="post_<?= $post['post_id'] ?>">
                        <td><?= $post['post_id'] ?></td>
                        <td><?= $post['post_content'] ?></td>
                        <td><?= $post['member_id'] ?></td>
                        <td><?= $post['insert_date'] ?></td>
                        <td><button type="button" onclick="post_delete('<?=$post['post_id'] ?>');return false;">삭제</button></td>
                    </tr>
                    <?php
                    }
                    ?>
                </tbody>
                </table>
            <div class="button-container2">
                <a href="#" class="button" id="more" onclick="next_list();">더보기</a>
            </div>
            <input type='hidden' id='last_post_id' value="<?php echo $last_post_id ?>" />
    </body>
</html>

list.api.php

<?php
header('Content-Type: application/json');

// 로그인 체크
session_start();
if (isset($_SESSION['member_id']) === false){
    echo json_encode(array('result' => false));
    exit();
}

// 파라미터 체크
$last_post_id = isset($_POST['last_post_id']) ? $_POST['last_post_id'] : null;
if ($last_post_id == null){
    echo json_encode(array('result' => false));
    exit();
}

// DB Require
require_once("../inc/db.php");

$member_id = $_SESSION['member_id'];
$post_query = "select post_id, post_content from tbl_post where member_id = :member_id and post_id < :post_id order by insert_date desc limit 10";
$post_data = db_select($post_query, array("member_id"=> $member_id, "post_id" => $last_post_id));

echo json_encode(
    array(
        'result' => true,
        'post_data' => $post_data
    )
);

4. 글쓰기

write.post.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>글쓰기</title>
    <style>
        .div {
            padding-left: 55px;
        }
        .form, textarea {
            width: 80%;
            border-radius: 5px;
            border: solid rgb(228, 228, 228) 2px;
            font-family: "맑은고딕", Malgun Gothic;
            margin-top: 8px;
        }
        .form {
            height: 25px;      
        }
        textarea {
            height: 150px;
        }
        .button {
            background-color: rgb(42, 105, 241);
            color: white;
            border: none;
            border-radius: 5px;
            height: 25px;
            width: 50px;
        }
    </style>
</head>
<body>
    <div class="div">
        <h2>게시글 작성</h2>
        <form method="POST" action="post.api.php">
            <div>
                <label>제목</label>
                <br><input type="text" class="form" name="title" placeholder="  제목을 입력해 주세요">
            </div>
            <br>
            <div>
                <label>작성자</label>
                <br><input type="text" name="member_id" class="form" placeholder="  이름을 입력해 주세요">
            </div>
            <br>
            <br>
            <div>
                <label>내용</label>
                <br><textarea name="post_content" placeholder="  내용을 입력해 주세요"></textarea>
            </div>
            <div><p>
            <input type="submit" class="button" value="등록"></input>
            </div>
        </form>
    </div>
</body>
</html>

post.api.php

<?php
// 로그인 체크
session_start();
if (isset($_SESSION['member_id']) === false){
    header("Location: ../login/login.php");
    exit();
}

// 글이 있는지 파라미터 체크
$post_content = isset($_POST['post_content']) ? $_POST['post_content'] : null;
if ($post_content == null || trim($post_content) == ''){
    header("Location: list.php");    
    exit();
}

// DB Require
require_once("../inc/db.php");

$member_id = $_SESSION['member_id'];

// tbl_post 입력
$post_id = db_insert("insert into tbl_post (post_content, member_id) values (:post_content, :member_id)", 
    array(
        'post_content'=> $post_content,
        'member_id'=> $member_id
    )
);

header("Location: list.php");
exit();

5. 글 삭제

delete.api.php

<?php
header('Content-Type: application/json');

// 로그인 체크
session_start();
if (isset($_SESSION['member_id']) === false){
    echo json_encode(array('result' => false));
    exit();
}

// 파라미터 체크
$post_id = isset($_POST['post_id']) ? $_POST['post_id'] : null;
if ($post_id == null){
    echo json_encode(array('result' => false));
    exit();
}

// DB Require
require_once("../inc/db.php");

$member_id = $_SESSION['member_id'];

// 글 삭제. 작성자 체크를 위해 writer_id 도 함께 검사.
$result = db_update_delete("delete from tbl_post where post_id = :post_id and member_id = :member_id",
    array(
        'post_id' => $post_id,
        'member_id' => $member_id
    )
);

echo json_encode(array('result' => $result));

css까지 한 파일에 같이 쓰다 보니 코드가 너무 길어졌다.
다음부턴 css를 따로 분리해서 쓰도록 해야겠다.

첨부된 링크를 참고하여 작성했습니다.

0개의 댓글