사이드 프로젝트 도전기

[Project] *사용자 사이트 구축* / PHP / 3. 게시판 메인 페이지 및 쓰기

Developer D 2023. 6. 13. 14:05

한걸음부터 다시 시작하기 프로젝트!

<잔잔한 버그는 깃허브에서 수정됩니다..>

https://github.com/silver-liq9118/php_website_basic

 

GitHub - silver-liq9118/php_website_basic: PHP Web site basic, just login and sign up

PHP Web site basic, just login and sign up. Contribute to silver-liq9118/php_website_basic development by creating an account on GitHub.

github.com

PHP 사용자 사이트 구축

게시판 메인, 쓰기구현입니다.

기술스택요약

  • 사용언어 : PHP, HTML, SQL
  • 데이터베이스 : mySQL
  • 서버 : Apache
  • 사용툴 및 환경 : 챗 GPT,  휴먼지능(본인), VsCode, XAMPP

프로젝트 요약 (게시판)

- 동적으로 데이터를 받아온다는 것은.. 생각보다 힘들다.

- 오늘의 삽질은 .. 파일명 오타가 있어서 3시간동안 삽질을 했다.. 눈을 크게뜨고 항상 오타는 조심하자.


Database Create Table (My Sql)

CREATE TABLE posts (
id INT,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
author varchar(50),
created_at DEFAULT current_timestamp()
updated_at TIMESTAMP DEFAULT current_timestamp() ON UPDATE current_timestamp()
);

posts 라는 새로운 게시판 전용 데이터 베이스를 가져와야하며 나는 일단 author == username 으로 받아오게끔 하였다.

(지금 생각해보니 유저들끼리 악용가능성이 있어서 username을 유니크로 바꾸기 or author을 email로 받아오기 로 수정해야겠다.)

 

Board_page.php

게시판 페이지

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>게시판</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            background-color: #f5f5f5;
        }

        h1 {
            color: #333;
            margin-bottom: 20px;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        th, td {
            padding: 10px;
            text-align: left;
            border-bottom: 1px solid #ddd;
        }

        th {
            background-color: #f2f2f2;
            font-weight: bold;
        }

        tr:hover {
            background-color: #f9f9f9;
        }

        .button-container {
            margin-top: 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .button-container input[type="submit"] {
            padding: 10px 20px;
            font-size: 16px;
            background-color: #4caf50;
            color: #fff;
            border: none;
            cursor: pointer;
            transition: background-color 0.3s ease;
        }

        .button-container input[type="submit"]:hover {
            background-color: #45a049;
        }

        .input-container {
            display: flex;
            align-items: center;
        }

        .input-container input[type="text"] {
            padding: 10px;
            font-size: 16px;
            border: 1px solid #ddd;
            border-radius: 4px;
        }

        .input-container button {
            padding: 10px 20px;
            font-size: 16px;
            background-color: #4caf50;
            color: #fff;
            border: none;
            cursor: pointer;
            transition: background-color 0.3s ease;
            margin-left: 10px;
        }

        .input-container button:hover {
            background-color: #45a049;
        }

        .post-link {
        color: #000;
        text-decoration: none;
        transition: color 0.3s ease;
        }

        .post-link:hover {
        color: #ff0000;
        }
    </style>
</head>

<body>
    <h1>&#9997;게시판&#128172;</h1>
    <div class="button-container">
        <input type="submit" value="게시글 작성하기&#128221;" name="post" onclick="window.location.href='write_post_page.html'">
        <div class="input-container">
            <input type="text" id="find_title" name="find_title" required placeholder="찾고싶은 게시물 제목">
            <button onclick="find()">찾기&#128269;</button>
        </div>
    </div>
    <br>
    <table>
        <tr>
            <th>No.</th>
            <th>제목</th>
            <th>작성자</th>
            <th>작성일</th>
        </tr>
        <?php

        // 게시물 데이터를 동적으로 표에 추가합니다.
        foreach ($rows as $post) {
            $postId = $post['id'];
            echo "<tr onclick='goToBoard({$postId})'>";
            echo "<td><a href='get_board_content.php?id={$post['id']}' class='post-link'>{$post['id']}</a></td>";
            echo "<td>{$post['title']}</td>";
            echo "<td>{$post['author']}</td>";
            echo "<td>{$post['created_at']}</td>";
            echo "</tr>";
            echo "</a>";
        }
               // 게시물의 콘텐츠 데이터를 가져오는 함수
               function getContent($postId) {
                
                include "get_board_content.php";

                return "게시물 {$postId}의 콘텐츠";
            }?>
    </table>
    <script>
    function goToBoard(postId) {
        // 게시물 상세 페이지로 이동합니다.
        window.location.href = 'get_board_content.php?id=' + postId;
    }
    </script>
</body>
</html>

사실 이 파일은 처음에 html로 만들었다가 동적으로 게시판 글들을 받을 수없음을 2시간쯤에 발견하고 수정했다.

이 파일은 기능위주보다는 보여주기 위주로 생각하면 된다.

나름 본인은 _page.html 은 페이지 보여주기로 .php 는 기능으로 분리 하려고 노력하고있다.

1,2,3 다음이 58인 이유는 그중간의 게시물들을 본인이 삭제하였기때문이다.

(처음에는 No == 게시글의 고유 id 라고 생각했는데 No를 따로주고 id는 따로저장하는 방식으로 바꿔야겠다.)

→ username을 데이터베이스에서 unique로 변경하였음

 

board.php

데이터베이스에서 게시판 가져오기

<?php
include "db_conn.php";

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

if(isset($_SESSION['email']) && isset($_SESSION['username'])){
$email = $_SESSION['email'];
$username =$_SESSION['username'];
// 세션에서 유저 이름 가져오기
}
else {
$email = "";
$username ="";
}

try   
    {

    if (!empty($email)) {
    //로그인 했을 때
       
    // 게시판 기본 목록 불러오기
    $sql = "SELECT id, title, author, created_at FROM posts";
    $result = $conn->query($sql);

        if ($result && mysqli_num_rows($result) > 0) {
            $rows = array();  // 결과 행을 저장할 배열
            while ($row = $result->fetch_assoc()) {
                $rows[] = $row;  // 각 행을 배열에 추가
            }
            include "board_page.php";       
            }}

    else {

    // 로그인 을 안했을 때
   
    include "access_failed.html"; }
                                        }
    
    catch ( Exception $e ) { 
    // 오류 발생 시 ?>     
<?php
        include "access_failed.html"; 
    }

?>

이 코드로 모든 posts 게시물들을 모두 저장하고 동적으로 빼내어 테이블에 보여 줄 수 있게 된다.

 

Write_post_page.html

게시글 작성하기

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>게시판 글쓰기</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f3f3f3;
            padding: 20px;
        }
        h1 {
            color: #333;
            text-align: center;
        }
        .notice {
            color: #333;
            text-align: center;
        }

        .container {
            max-width: 500px;
            margin: 0 auto;
            background-color: #fff;
            padding: 20px;
            border-radius: 5px;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }
        .form-group {
            display: flex;
            flex-direction: column;
            margin-bottom: 20px;
        }
        label {
            font-weight: bold;
            margin-bottom: 5px;
        }
        input[type="text"],
        textarea {
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 3px;
            resize: vertical;
            font-family: Arial, sans-serif; 
        }
        .button-group {
            display: flex;
            justify-content: space-between;
        }
        input[type="submit"],input[type="button"] {
            background-color: #007bff;
            color: #fff;
            border: none;
            padding: 10px 20px; 
            border-radius: 3px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        input[type="submit"]:hover,input[type="button"]:hover {
            background-color: #0056b3;
        }
    </style>
</head>
<body>
    <h1> &#9997; 게시판 글쓰기 &#9997;</h1>
    <div class = "notice"name="notice"style="font-family: Arial, sans-serif;"> &#9994; 비속어를 지양하는 지성인이 됩시다 &#10024; </div>
    <p></p>
    <div class="container">
        <form action="write_post.php" method="post">
            <div class="form-group">
                <label for="title"></label>
                <input type="text" id="title" name="title" required placeholder="제목을 입력해주세요." style="font-family: Arial, sans-serif;"> 
            </div>
            
            <div class="form-group">
                <label for="content"></label>
                <textarea id="content" name="content" rows="20" required placeholder="내용을 입력해주세요." style="font-family: Arial, sans-serif;"></textarea> 
            </div>
            
            <div class="button-group">
                <input type="submit" value="작성하기">
                <input type="button" value="뒤로가기" onclick="goToBoardPage()">
            </div>
        </form>
    </div>
</body>
</html>
<script>
    function goToBoardPage() {
        window.location.href = "board.php";
    }
</script>

뒤로가기를 누르면 board.php로 이동되어 다시 게시판으로 이동된다.

 

write_post.php

<?php
include "db_conn.php";

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

if(isset($_SESSION['email']) && isset($_SESSION['username'])){

    $title = $_POST['title'];
    $content = $_POST['content'];
    $author =$_SESSION['username'];

}

else {

    $title = "";
    $content ="";
    $author ="";

    


    return include "access_failed.html";

}



if ($_SERVER['REQUEST_METHOD'] === 'POST') {
//title, author, created_at
$sql = "INSERT INTO posts (title,content, author) VALUES ('$title','$content','$author')";
$result = $conn->query($sql);

if ($result) {
    // 게시글 추가에 성공한 경우
    include "board.php";
    
} else {

    // 게시글 추가에 실패한 경우
    // 에러메세지 출력시 $error_message = mysqli_error($conn);

    include "write_failed.html";
    
}
}

else {

    // 게시글 추가에 실패한 경우
    // 에러메세지 출력시 $error_message = mysqli_error($conn);

    include "write_failed.html"; }
?>

글쓰기를 입력하면 데이터베이스에 실제로 기입이 된다.

* 한글 인코딩 문제 해결

데이터베이스의 인코딩 설정을 다시해줬다.

ALTER TABLE posts
MODIFY COLUMN content TEXT CHARACTER SET utf8,
MODIFY COLUMN title VARCHAR(255) CHARACTER SET utf8,
MODIFY COLUMN author VARCHAR(255) CHARACTER SET utf8,
DEFAULT CHARSET=utf8;

 

추가 기능 로그인접근제한 (Board.php 일부)

게시판 접근은 로그인 한 사람만 할 수 있다.

→  세션에서 값을 가져올 수 있는 사람만 접근할 수 있고 그외에 사람들은 접근 불가 사이트를 조회하게 했다.

    if (!empty($email)) {
    //로그인 했을 때
       
    // 게시판 기본 목록 불러오기
    $sql = "SELECT id, title, author, created_at FROM posts";
    $result = $conn->query($sql);

        if ($result && mysqli_num_rows($result) > 0) {
            $rows = array();  // 결과 행을 저장할 배열
            while ($row = $result->fetch_assoc()) {
                $rows[] = $row;  // 각 행을 배열에 추가
            }
            include "board_page.php";       
            }}

    else {

    // 로그인 을 안했을 때
   
    include "access_failed.html"; }

 

access.failed.html

<!DOCTYPE html>
<html>
<meta charset="UTF-8">
    <title>잘못된 접근 입니다.</title>
    <style>
        body {
            background-color: #f3f3f3;
            text-align: center;
            padding-top: 100px;
            font-family: Arial, sans-serif;
        }
        h1 {
            color: #333;
            font-size: 28px;
        }
        p {
            color: #666;
            font-size: 16px;
        }
        .login-button {
            display: inline-block;
            background-color: #007bff;
            color: #fff;
            padding: 10px 20px;
            border-radius: 4px;
            text-decoration: none;
            transition: background-color 0.3s;
        }
        .login-button:hover {
            background-color: #0056b3;
        }
    </style> 
<h1> &#9940;허용되지 않는 접근입니다.&#9940; <br> 로그인을 하거나 회원가입을 진행해 주세요!</h1>
<p>&#127969;홈페이지로 돌아가시려면 <a class="login-button" href="Login_page.php"> 홈페이지 바로가기 </a> 버튼을 클릭해주세요.</p>
<p>&#128221;회원가입 <a class="login-button" href="Join_page.html"> 회원가입</a> 버튼을 클릭해주세요.</p>
</html>

+ 글이써지지 않는경우도 분리하여 게시판 페이지로 돌아가게했다.

write.php

if ($result) {
    // 게시글 추가에 성공한 경우
    include "board.php";
    
} else {

    // 게시글 추가에 실패한 경우
    // 에러메세지 출력시 $error_message = mysqli_error($conn);

    include "write_failed.html";
    
}
}

else {

    // 게시글 추가에 실패한 경우
    // 에러메세지 출력시 $error_message = mysqli_error($conn);

    include "write_failed.html"; }

 

write_failed.html

<!DOCTYPE html>
<html>
<meta charset="UTF-8">
    <title>글쓰기 실패</title>
    <style>
        body {
            background-color: #f3f3f3;
            text-align: center;
            padding-top: 100px;
            font-family: Arial, sans-serif;
        }
        h1 {
            color: #333;
            font-size: 28px;
        }
        p {
            color: #666;
            font-size: 16px;
        }
        .login-button {
            display: inline-block;
            background-color: #007bff;
            color: #fff;
            padding: 10px 20px;
            border-radius: 4px;
            text-decoration: none;
            transition: background-color 0.3s;
        }
        .login-button:hover {
            background-color: #0056b3;
        }
    </style> 
<h1> 글쓰기에 실패 했습니다. <br> </h1>
<p><a class="login-button" href="board.php"> ✍게시판 으로 돌아가기 💬</a> 버튼을 클릭해주세요.</p>

</html>

 

이런 접근들을 다 제어해준다는게 생각보다 손이많이가고 신경써야하는 부분들이 많은것같다.

반응형