[카테고리:] 블로그

  • 9. 웹서버 운영하기 9th

    9. 웹서버 운영하기 9th

    📌 로그인 및 회원 관리 시스템 구축

    이제 회원 로그인 기능을 추가하여, 회원별로 접근 권한을 설정할 수 있도록 하겠습니다.
    즉, 회원가입, 로그인, 로그아웃 기능을 구현하여 사용자가 개인 계정을 가질 수 있도록 만듭니다.

    이번 단계에서 다룰 내용

    1. 회원 테이블에 로그인 정보 추가 (users 테이블 수정)
    2. 회원가입 기능 (register.php)
    3. 로그인 기능 (login.php)
    4. 세션을 이용한 로그인 유지 (session.php)
    5. 로그아웃 기능 (logout.php)
    6. 로그인한 회원만 접근 가능하도록 페이지 보호 (auth_check.php)

    1️⃣ 회원 테이블 수정 (로그인 정보 추가)

    회원이 이메일과 비밀번호를 사용해 로그인할 수 있도록 users 테이블을 수정합니다.

    phpMyAdmin에서 아래 SQL 실행

    ALTER TABLE user ADD COLUMN email VARCHAR(100) UNIQUE NOT NULL AFTER name;
    ALTER TABLE user ADD COLUMN password VARCHAR(255) NOT NULL AFTER email;
    

    결과 (users 테이블 구조)

    +----+--------+------------------+----------------------------------+-----+--------------+
    | ID | 이름   | 이메일           | 비밀번호                         | 나이 | 프로필 사진  |
    +----+--------+------------------+----------------------------------+-----+--------------+
    |  1 | 홍길동 | test@naver.com   | $2y$10$abcde...                 |  30 | profile1.jpg |
    |  2 | 김철수 | kim@gmail.com    | $2y$10$xyz123...                |  25 | profile2.jpg |
    +----+--------+------------------+----------------------------------+-----+--------------+
    

    이제 회원가입 시 이메일과 비밀번호를 입력하도록 구현하겠습니다. 🚀

    2️⃣ 회원가입 기능 (register.php)

    회원가입 시 비밀번호는 암호화(password_hash())하여 저장해야 합니다.

    🔍 코드 해석

    1. password_hash($password, PASSWORD_DEFAULT); → 비밀번호를 암호화하여 저장
    2. FILTER_VALIDATE_EMAIL → 이메일 형식이 올바른지 확인
    3. mysqli_prepare() → SQL Injection 방지를 위한 Prepared Statements 사용
    4. email이 중복되는지 검사 후 중복이면 회원가입 불가

    🖥️ 실행 코드 (register.php)

    📌 파일 경로: register.php
    📌 아래 코드를 register.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $name = trim($_POST['name']);
        $email = trim($_POST['email']);
        $password = $_POST['password'];
        $age = (int) $_POST['age'];
    
        // 이메일 형식 확인
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            die("올바른 이메일을 입력하세요.");
        }
    
        // 비밀번호 암호화
        $hashed_password = password_hash($password, PASSWORD_DEFAULT);
    
        // 이메일 중복 확인
        $check_sql = "SELECT id FROM user WHERE email = ?";
        $stmt = $conn->prepare($check_sql);
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $stmt->store_result();
    
        if ($stmt->num_rows > 0) {
            die("이미 사용 중인 이메일입니다.");
        }
    
        $stmt->close();
    
        // 회원가입 처리
        $sql = "INSERT INTO user (name, email, password, age) VALUES (?, ?, ?, ?)";
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("sssi", $name, $email, $hashed_password, $age);
    
        if ($stmt->execute()) {
            echo "<script>alert('회원가입 성공! 로그인하세요.'); location.href='login.php';</script>";
        } else {
            echo "오류 발생: " . $stmt->error;
        }
    
        $stmt->close();
        $conn->close();
    }
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>회원가입</title>
    </head>
    <body>
        <h2>회원가입</h2>
        <form method="post" action="register.php">
            이름: <input type="text" name="name" required><br>
            이메일: <input type="email" name="email" required><br>
            비밀번호: <input type="password" name="password" required><br>
            나이: <input type="number" name="age" required><br>
            <button type="submit">회원가입</button>
        </form>
    </body>
    </html>
    

    이제 register.php에서 회원가입이 가능하며, 비밀번호가 안전하게 암호화됩니다. 🚀
    이제 로그인 기능을 추가하겠습니다.

    3️⃣ 로그인 기능 (login.php)

    회원이 이메일과 비밀번호를 입력하면 로그인하도록 구현합니다.

    🔍 코드 해석

    1. password_verify($password, $row['password']) → 비밀번호 일치 확인
    2. session_start(); → 로그인 정보를 유지하기 위해 세션 시작
    3. 로그인 성공 시 세션에 회원 정보를 저장 ($_SESSION['user_id'], $_SESSION['user_name'])

    🖥️ 실행 코드 (login.php)

    📌 파일 경로: login.php
    📌 아래 코드를 login.php 파일로 저장하세요.

    <?php
    session_start();
    include 'db.php';
    
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $email = trim($_POST['email']);
        $password = $_POST['password'];
    
        $sql = "SELECT id, name, password FROM user WHERE email = ?";
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $stmt->store_result();
        
        if ($stmt->num_rows > 0) {
            $stmt->bind_result($id, $name, $hashed_password);
            $stmt->fetch();
    
            if (password_verify($password, $hashed_password)) {
                $_SESSION['user_id'] = $id;
                $_SESSION['user_name'] = $name;
                echo "<script>alert('로그인 성공!'); location.href='index.php';</script>";
            } else {
                echo "비밀번호가 올바르지 않습니다.";
            }
        } else {
            echo "이메일이 존재하지 않습니다.";
        }
    
        $stmt->close();
        $conn->close();
    }
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>로그인</title>
    </head>
    <body>
        <h2>로그인</h2>
        <form method="post" action="login.php">
            이메일: <input type="email" name="email" required><br>
            비밀번호: <input type="password" name="password" required><br>
            <button type="submit">로그인</button>
        </form>
    </body>
    </html>
    

    이제 login.php에서 로그인하면 index.php로 이동합니다.
    세션을 이용하여 로그인 상태를 유지할 수 있습니다. 🚀
    이제 로그아웃 기능을 추가하겠습니다.

    4️⃣ 로그아웃 기능 (logout.php)

    회원이 로그아웃하면 세션을 삭제해야 합니다.

    📌 파일 경로: logout.php
    📌 아래 코드를 logout.php 파일로 저장하세요.

    <?php
    session_start();
    session_unset();
    session_destroy();
    echo "<script>alert('로그아웃 되었습니다.'); location.href='login.php';</script>";
    ?>
    

    이제 logout.php를 실행하면 로그아웃됩니다. 🚀

    🎯 최종 점검

    register.php → 회원가입 기능 추가
    login.php → 이메일과 비밀번호로 로그인 가능
    logout.php → 세션 삭제 후 로그아웃

    🚀 이제 로그인 시스템이 완성되었습니다! 🚀
    📌 이제 다음 단계(로그인한 사용자만 특정 페이지 접근 가능하게 보호)로 진행합니다!

    📌 로그인한 사용자만 특정 페이지에 접근 가능하게 보호하기

    이제 로그인한 사용자만 특정 페이지에 접근할 수 있도록 인증 시스템을 강화하겠습니다.
    즉, 로그인하지 않으면 회원 목록 페이지(index.php) 등 특정 페이지에 접근할 수 없도록 설정할 것입니다.

    이번 단계에서 다룰 내용

    1. 로그인 여부 확인 및 인증 적용 (auth_check.php)
    2. 로그인한 사용자만 접근할 수 있도록 index.php 등 페이지 보호
    3. 로그인 상태에서만 회원 수정/삭제 가능하도록 적용

    1️⃣ 로그인 여부 확인 (auth_check.php)

    로그인하지 않은 사용자가 특정 페이지에 접근하면 login.php로 이동하도록 설정합니다.

    🔍 코드 해석

    1. session_start(); → 세션 시작
    2. if (!isset($_SESSION['user_id'])) → 로그인 여부 확인
    3. 로그인하지 않았으면 login.php로 강제 이동 (header("Location: login.php"))

    🖥️ 실행 코드 (auth_check.php)

    📌 파일 경로: auth_check.php
    📌 아래 코드를 auth_check.php 파일로 저장하세요.

    <?php
    session_start();
    if (!isset($_SESSION['user_id'])) {
        header("Location: login.php");
        exit();
    }
    ?>
    

    이제 auth_check.php를 모든 보호할 페이지 상단에 추가하면 로그인 상태를 확인할 수 있습니다. 🚀

    2️⃣ 특정 페이지 보호 (index.php, edit.php, delete.php 수정)

    회원 목록 페이지(index.php) 등 보호할 페이지의 상단에 auth_check.php를 추가합니다.

    📌 파일 경로: index.php
    📌 아래처럼 auth_check.phpindex.php 파일 최상단에 추가하세요.

    <?php
    include 'auth_check.php'; // 로그인 여부 확인
    include 'db.php'; // 데이터베이스 연결
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>회원 목록</title>
    </head>
    <body>
        <h2>회원 목록</h2>
        <p>안녕하세요, <?php echo $_SESSION['user_name']; ?>님!</p>
        <a href="logout.php">로그아웃</a>
    
        <table border="1">
            <tr>
                <th>프로필</th>
                <th>ID</th>
                <th>이름</th>
                <th>이메일</th>
                <th>나이</th>
                <th>관리</th>
            </tr>
    
            <?php
            $sql = "SELECT * FROM user";
            $result = $conn->query($sql);
    
            if ($result->num_rows > 0) {
                while ($row = $result->fetch_assoc()) {
                    $image_src = !empty($row['profile_image']) ? "uploads/" . $row['profile_image'] : "uploads/default.png";
                    $safe_name = htmlspecialchars($row['name']);
                    echo "<tr>
                            <td><img src='$image_src' width='50' height='50'></td>
                            <td>{$row['id']}</td>
                            <td>{$safe_name}</td>
                            <td>{$row['email']}</td>
                            <td>{$row['age']}</td>
                            <td>
                                <a href='edit.php?id={$row['id']}'>수정</a> | 
                                <a href='delete.php?id={$row['id']}'>삭제</a>
                            </td>
                          </tr>";
                }
            } else {
                echo "<tr><td colspan='6'>등록된 회원이 없습니다.</td></tr>";
            }
    
            $conn->close();
            ?>
        </table>
        <br>
        <a href="insert.php">회원 추가</a>
    </body>
    </html>
    

    이제 index.php에 로그인하지 않은 사용자가 접근하면 login.php로 자동 이동됩니다. 🚀
    이제 edit.phpdelete.php에도 동일한 보호 기능을 추가하겠습니다.

    3️⃣ 회원 수정 및 삭제 페이지 보호 (edit.php, delete.php 수정)

    회원 정보 수정(edit.php)과 삭제(delete.php) 페이지에도 auth_check.php를 추가하여 보호합니다.

    📌 파일 경로: edit.php
    📌 아래처럼 auth_check.php를 추가하세요.

    <?php
    include 'auth_check.php'; // 로그인 여부 확인
    include 'db.php'; // 데이터베이스 연결
    
    $id = $_GET['id'];
    $sql = "SELECT * FROM user WHERE id=$id";
    $result = $conn->query($sql);
    $row = $result->fetch_assoc();
    
    if (!$row) {
        echo "<script>alert('회원 정보를 찾을 수 없습니다.'); location.href='index.php';</script>";
    }
    
    $image_src = !empty($row['profile_image']) ? "uploads/" . $row['profile_image'] : "uploads/default.png";
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>회원 정보 수정</title>
    </head>
    <body>
        <h2>회원 정보 수정</h2>
        <form method="post" action="update.php" enctype="multipart/form-data">
            <input type="hidden" name="id" value="<?php echo $row['id']; ?>">
            이름: <input type="text" name="name" value="<?php echo htmlspecialchars($row['name']); ?>" required><br>
            이메일: <?php echo htmlspecialchars($row['email']); ?> (변경 불가)<br>
            나이: <input type="number" name="age" value="<?php echo $row['age']; ?>" required><br>
            현재 프로필 사진:<br>
            <img src="<?php echo $image_src; ?>" width="100" height="100"><br>
            새로운 프로필 사진: <input type="file" name="profile_image"><br>
            <button type="submit">수정</button>
        </form>
    </body>
    </html>
    

    📌 파일 경로: delete.php
    📌 아래처럼 auth_check.php를 추가하세요.

    <?php
    include 'auth_check.php'; // 로그인 여부 확인
    include 'db.php'; // 데이터베이스 연결
    
    $id = $_GET['id'];
    
    // 기존 이미지 파일 가져오기
    $sql = "SELECT profile_image FROM user WHERE id=$id";
    $result = $conn->query($sql);
    $row = $result->fetch_assoc();
    $old_image = $row['profile_image'];
    
    // 기존 이미지 삭제 (default.png는 삭제하지 않음)
    if (!empty($old_image) && file_exists("uploads/" . $old_image) && $old_image !== "default.png") {
        unlink("uploads/" . $old_image);
    }
    
    // 회원 삭제
    $sql = "DELETE FROM user WHERE id=$id";
    
    if ($conn->query($sql) === TRUE) {
        echo "<script>alert('회원 삭제 완료!'); location.href='index.php';</script>";
    } else {
        echo "오류: " . $conn->error;
    }
    
    $conn->close();
    ?>
    

    이제 edit.phpdelete.php에도 로그인한 사용자만 접근할 수 있습니다. 🚀

    🎯 최종 점검

    auth_check.php → 로그인 여부 확인
    index.php → 로그인한 사용자만 접근 가능
    edit.php → 로그인한 사용자만 수정 가능
    delete.php → 로그인한 사용자만 삭제 가능

    🚀 이제 로그인 시스템이 완벽하게 보호되었습니다! 🚀
    📌 이제 다음 단계(관리자 페이지 추가)로 진행합니다!

  • 8. 웹서버 운영하기 8th

    8. 웹서버 운영하기 8th

    📌 파일 업로드 및 이미지 저장

    이제 PHP에서 파일을 업로드하고 저장하는 방법을 배워보겠습니다.
    사용자가 이미지(프로필 사진)를 업로드하고, 이를 데이터베이스에 저장 및 표시할 수 있도록 구현할 것입니다.

    이번 단계에서 다룰 내용

    1. 파일 업로드 기본 개념
    2. 파일 업로드 기능 추가 (insert.php 수정)
    3. 업로드한 파일을 데이터베이스에 저장 (upload.php)
    4. 저장된 이미지를 웹 페이지에서 출력 (index.php 수정)
    5. 보안 적용 (업로드 제한, 허용 확장자 설정)

    1️⃣ 파일 업로드 개념

    PHP에서 파일을 업로드할 때의 기본 원리

    1. 사용자가 HTML 폼을 통해 파일을 선택하고 업로드 버튼을 누름
    2. 서버가 해당 파일을 지정된 폴더(uploads/)에 저장
    3. 데이터베이스에는 **파일 이름(경로)**만 저장하고, 필요할 때 가져와 표시

    파일 저장 위치 설정

    • 업로드된 파일은 uploads/ 폴더에 저장됩니다.
    • PHP는 기본적으로 $_FILES 배열을 사용하여 업로드된 파일을 처리합니다.

    파일 업로드 시 주의할 점

    • 허용된 파일 확장자만 저장해야 함 (이미지 파일만 업로드 가능)
    • 파일 크기 제한 설정 (예: 2MB 이하)
    • 보안 위협(실행 파일 업로드 방지)
    • 파일 이름 중복 방지 (랜덤 이름 사용)

    2️⃣ 파일 업로드 폼 추가 (insert.php)

    회원 추가 시 프로필 사진을 업로드할 수 있도록 폼을 수정합니다.

    📌 파일 경로: insert.php
    📌 아래 코드를 insert.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $name = trim($_POST['name']); // 입력값 앞뒤 공백 제거
        $age = (int) $_POST['age']; // 숫자로 변환 (문자 입력 방지)
        $profile_image = ""; // 기본적으로 빈 값
    
        // 파일 업로드 처리
        if (!empty($_FILES["profile_image"]["name"])) {
            $target_dir = "uploads/"; // 업로드 폴더
            $file_name = basename($_FILES["profile_image"]["name"]);
            $file_extension = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
            $new_file_name = uniqid() . "." . $file_extension; // 파일 이름 중복 방지
            $target_file = $target_dir . $new_file_name;
            $allowed_extensions = ["jpg", "jpeg", "png", "gif"]; // 허용할 확장자
    
            // 확장자 검사
            if (!in_array($file_extension, $allowed_extensions)) {
                die("허용되지 않은 파일 형식입니다. (jpg, jpeg, png, gif 만 가능)");
            }
    
            // 파일 크기 제한 (2MB 이하)
            if ($_FILES["profile_image"]["size"] > 2 * 1024 * 1024) {
                die("파일 크기는 2MB 이하만 가능합니다.");
            }
    
            // 파일을 업로드 폴더에 저장
            if (move_uploaded_file($_FILES["profile_image"]["tmp_name"], $target_file)) {
                $profile_image = $new_file_name; // DB에 저장할 파일명
            } else {
                die("파일 업로드 실패");
            }
        }
    
        // 데이터베이스에 회원 정보 추가 (파일명 포함)
        $stmt = $conn->prepare("INSERT INTO user (name, age, profile_image) VALUES (?, ?, ?)");
        $stmt->bind_param("sis", $name, $age, $profile_image);
    
        if ($stmt->execute()) {
            echo "<script>alert('회원 추가 성공!'); location.href='index.php';</script>";
        } else {
            echo "오류 발생: " . $stmt->error;
        }
    
        $stmt->close();
        $conn->close();
    }
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>회원 추가</title>
    </head>
    <body>
        <h2>회원 추가</h2>
        <form method="post" action="insert.php" enctype="multipart/form-data">
            이름: <input type="text" name="name" required><br>
            나이: <input type="number" name="age" required><br>
            프로필 사진: <input type="file" name="profile_image"><br>
            <button type="submit">추가</button>
        </form>
    </body>
    </html>
    

    변경 후 추가된 기능

    • enctype="multipart/form-data" : 파일 업로드를 위해 반드시 설정해야 함
    • <input type="file" name="profile_image"> : 파일 선택 창 추가
    • 파일 확장자 제한 (jpg, jpeg, png, gif만 허용)
    • 파일 크기 제한 (2MB 이하)
    • 파일 이름 중복 방지 (랜덤 파일명 생성)

    이제 index.php에서 업로드한 프로필 사진을 표시해야 합니다.

    3️⃣ 업로드된 이미지 표시 (index.php 수정)

    회원 목록에서 업로드된 프로필 사진을 표시하도록 수정합니다.

    📌 파일 경로: index.php
    📌 아래 코드를 index.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>회원 목록</title>
    </head>
    <body>
        <h2>회원 목록</h2>
        <table border="1">
            <tr>
                <th>프로필</th>
                <th>ID</th>
                <th>이름</th>
                <th>나이</th>
                <th>관리</th>
            </tr>
    
            <?php
            $sql = "SELECT * FROM user";
            $result = $conn->query($sql);
    
            if ($result->num_rows > 0) {
                while ($row = $result->fetch_assoc()) {
                    $image_src = !empty($row['profile_image']) ? "uploads/" . $row['profile_image'] : "uploads/default.png";
                    $safe_name = htmlspecialchars($row['name']); // XSS 방지
                    echo "<tr>
                            <td><img src='$image_src' width='50' height='50'></td>
                            <td>{$row['id']}</td>
                            <td>{$safe_name}</td>
                            <td>{$row['age']}</td>
                            <td>
                                <a href='edit.php?id={$row['id']}'>수정</a> | 
                                <a href='delete.php?id={$row['id']}'>삭제</a>
                            </td>
                          </tr>";
                }
            } else {
                echo "<tr><td colspan='5'>등록된 회원이 없습니다.</td></tr>";
            }
    
            $conn->close();
            ?>
        </table>
        <br>
        <a href="insert.php">회원 추가</a>
    </body>
    </html>
    

    변경 후 추가된 기능

    • <img src='$image_src' width='50' height='50'> : 업로드된 프로필 사진 표시
    • 기본 이미지 (default.png) 제공 (이미지 없을 경우 대비)

    이제 insert.php에서 회원 추가 시 프로필 사진을 업로드할 수 있으며, index.php에서 이를 확인할 수 있습니다.

    🎯 최종 점검

    insert.php → 파일 업로드 기능 추가
    uploads/ 폴더 → 업로드된 이미지 저장
    index.php → 업로드된 프로필 사진 표시
    ✅ 보안 적용 → 확장자 제한, 파일 크기 제한, 파일명 랜덤화

    🚀 이제 웹에서 회원을 추가할 때 프로필 사진을 업로드하고 확인할 수 있습니다! 🚀
    이제 다음 단계(파일 삭제 및 이미지 수정)로 진행합니다!

    📌 파일 삭제 및 이미지 수정 기능 추가

    이제 회원 정보 수정 시 기존 이미지를 변경하거나 삭제하는 기능을 추가하겠습니다.
    즉, 사용자가 새로운 프로필 사진을 업로드하면 기존 사진을 삭제하고 새로운 사진을 저장할 수 있도록 구현할 것입니다.

    이번 단계에서 다룰 내용

    1. 회원 수정 시 기존 이미지 불러오기 (edit.php)
    2. 새로운 이미지 업로드 시 기존 이미지 삭제 (update.php)
    3. 회원 삭제 시 프로필 이미지도 함께 삭제 (delete.php)

    1️⃣ 회원 수정 시 기존 이미지 불러오기 (edit.php)

    회원 정보를 수정할 때, 기존 프로필 사진을 표시하고 새로운 이미지를 업로드할 수 있도록 해야 합니다.

    🔍 코드 해석

    1. $_GET['id'] : URL에서 id 값을 가져옵니다. (edit.php?id=1 같은 URL에서 1을 가져옴)
    2. SELECT * FROM user WHERE id=$id : 해당 id를 가진 회원 정보를 조회합니다.
    3. 기존 프로필 사진이 있다면 표시 (<img src='uploads/파일명'>)
    4. 새로운 이미지 업로드 시 기존 이미지를 대체할 수 있도록 <input type="file"> 추가

    🖥️ 실행 코드 (edit.php)

    📌 파일 경로: edit.php
    📌 아래 코드를 edit.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    $id = $_GET['id']; // URL에서 회원 ID 가져오기
    $sql = "SELECT * FROM user WHERE id=$id";
    $result = $conn->query($sql);
    $row = $result->fetch_assoc();
    
    if (!$row) {
        echo "<script>alert('회원 정보를 찾을 수 없습니다.'); location.href='index.php';</script>";
    }
    
    $image_src = !empty($row['profile_image']) ? "uploads/" . $row['profile_image'] : "uploads/default.png"; // 기존 프로필 이미지
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>회원 정보 수정</title>
    </head>
    <body>
        <h2>회원 정보 수정</h2>
        <form method="post" action="update.php" enctype="multipart/form-data">
            <input type="hidden" name="id" value="<?php echo $row['id']; ?>">
            이름: <input type="text" name="name" value="<?php echo htmlspecialchars($row['name']); ?>" required><br>
            나이: <input type="number" name="age" value="<?php echo $row['age']; ?>" required><br>
            현재 프로필 사진:<br>
            <img src="<?php echo $image_src; ?>" width="100" height="100"><br>
            새로운 프로필 사진: <input type="file" name="profile_image"><br>
            <button type="submit">수정</button>
        </form>
    </body>
    </html>
    

    이제 edit.php에서 회원 수정 시 기존 프로필 사진을 확인하고, 새로운 이미지를 업로드할 수 있습니다.
    이제 update.php에서 새로운 이미지를 업로드하면 기존 이미지를 삭제하도록 수정하겠습니다. 🚀

    2️⃣ 새로운 이미지 업로드 시 기존 이미지 삭제 (update.php)

    회원이 새로운 이미지를 업로드하면, 기존 프로필 이미지를 삭제해야 합니다.

    🔍 코드 해석

    1. 사용자가 새로운 이미지를 업로드했는지 확인 (!empty($_FILES["profile_image"]["name"]))
    2. 기존 프로필 사진이 있다면 삭제 (unlink("uploads/파일명"))
    3. 새로운 이미지를 저장한 후 데이터베이스 업데이트

    🖥️ 실행 코드 (update.php)

    📌 파일 경로: update.php
    📌 아래 코드를 update.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    $id = $_POST['id']; // 수정할 회원 ID
    $name = trim($_POST['name']);
    $age = (int) $_POST['age'];
    $profile_image = "";
    
    // 기존 이미지 파일 가져오기
    $sql = "SELECT profile_image FROM user WHERE id=$id";
    $result = $conn->query($sql);
    $row = $result->fetch_assoc();
    $old_image = $row['profile_image'];
    
    // 새로운 이미지 업로드 처리
    if (!empty($_FILES["profile_image"]["name"])) {
        $target_dir = "uploads/";
        $file_name = basename($_FILES["profile_image"]["name"]);
        $file_extension = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
        $new_file_name = uniqid() . "." . $file_extension;
        $target_file = $target_dir . $new_file_name;
        $allowed_extensions = ["jpg", "jpeg", "png", "gif"];
    
        if (!in_array($file_extension, $allowed_extensions)) {
            die("허용되지 않은 파일 형식입니다. (jpg, jpeg, png, gif 만 가능)");
        }
    
        if ($_FILES["profile_image"]["size"] > 2 * 1024 * 1024) {
            die("파일 크기는 2MB 이하만 가능합니다.");
        }
    
        // 기존 이미지 삭제 (default.png는 삭제하지 않음)
        if (!empty($old_image) && file_exists("uploads/" . $old_image) && $old_image !== "default.png") {
            unlink("uploads/" . $old_image);
        }
    
        // 새 이미지 저장
        if (move_uploaded_file($_FILES["profile_image"]["tmp_name"], $target_file)) {
            $profile_image = $new_file_name;
        } else {
            die("파일 업로드 실패");
        }
    } else {
        // 새로운 이미지 업로드가 없으면 기존 이미지 유지
        $profile_image = $old_image;
    }
    
    // 회원 정보 업데이트
    $stmt = $conn->prepare("UPDATE user SET name=?, age=?, profile_image=? WHERE id=?");
    $stmt->bind_param("sisi", $name, $age, $profile_image, $id);
    
    if ($stmt->execute()) {
        echo "<script>alert('회원 정보 수정 완료!'); location.href='index.php';</script>";
    } else {
        echo "오류 발생: " . $stmt->error;
    }
    
    $stmt->close();
    $conn->close();
    ?>
    

    이제 새로운 프로필 사진을 업로드하면 기존 사진이 삭제되고 새 사진으로 교체됩니다. 🚀

    3️⃣ 회원 삭제 시 프로필 이미지도 함께 삭제 (delete.php)

    회원 정보를 삭제할 때 프로필 이미지도 함께 삭제해야 합니다.

    🔍 코드 해석

    1. 삭제할 회원의 기존 프로필 이미지를 가져오기
    2. 기존 프로필 이미지가 존재하면 삭제 (unlink("uploads/파일명"))
    3. 회원 데이터 삭제

    🖥️ 실행 코드 (delete.php)

    📌 파일 경로: delete.php
    📌 아래 코드를 delete.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    $id = $_GET['id']; // 삭제할 회원 ID
    
    // 기존 이미지 파일 가져오기
    $sql = "SELECT profile_image FROM user WHERE id=$id";
    $result = $conn->query($sql);
    $row = $result->fetch_assoc();
    $old_image = $row['profile_image'];
    
    // 기존 이미지 삭제 (default.png는 삭제하지 않음)
    if (!empty($old_image) && file_exists("uploads/" . $old_image) && $old_image !== "default.png") {
        unlink("uploads/" . $old_image);
    }
    
    // 회원 삭제
    $sql = "DELETE FROM user WHERE id=$id";
    
    if ($conn->query($sql) === TRUE) {
        echo "<script>alert('회원 삭제 완료!'); location.href='index.php';</script>";
    } else {
        echo "오류: " . $conn->error;
    }
    
    $conn->close();
    ?>
    

    이제 회원을 삭제하면 프로필 사진도 함께 삭제됩니다. 🚀

    🎯 최종 점검

    edit.php → 회원 정보 수정 시 기존 프로필 사진 표시
    update.php → 새로운 프로필 사진 업로드 시 기존 이미지 삭제
    delete.php → 회원 삭제 시 프로필 이미지도 함께 삭제

    🚀 이제 완벽한 회원 관리 시스템이 완성되었습니다! 🚀
    📌 이제 다음 단계(로그인 및 회원 관리 시스템)로 진행합니다!

  • 7. 웹서버 운영하기 7th

    7. 웹서버 운영하기 7th

    📌 사용자 입력 검증 및 보안 강화

    이제 PHP 웹 애플리케이션에서 보안 강화를 진행하겠습니다.
    이전 단계에서 우리는 **사용자 데이터를 추가, 조회, 수정, 삭제(CRUD)**하는 기능을 만들었습니다.
    하지만 보안이 취약하면 SQL Injection(해킹 공격), XSS(스크립트 공격) 등의 문제가 발생할 수 있습니다.

    이번 단계에서 다룰 보안 강화 방법

    1. SQL Injection 방지 (mysqli_real_escape_string(), prepared statements 사용)
    2. XSS 공격 방지 (htmlspecialchars() 사용)
    3. 입력 값 검증 (숫자, 이메일 등)
    4. 에러 메시지 처리 (보안상 민감한 정보 노출 방지)

    1️⃣ SQL Injection 방지

    SQL Injection(구문 삽입 공격)이란, 해커가 SQL 문을 조작하여 데이터베이스를 탈취하는 공격입니다.
    예를 들어, name 입력란에 ' OR 1=1 -- 같은 값을 입력하면, 전체 데이터가 노출될 수 있습니다.

    📌 1.1 SQL Injection 공격 예시

    예를 들어, 기존 코드가 다음과 같다면 보안에 취약합니다.

    $name = $_POST['name'];
    $sql = "SELECT * FROM user WHERE name='$name'";
    

    여기에 $_POST['name'] 값으로 ' OR 1=1 --을 입력하면,
    쿼리가 다음과 같이 변형됩니다.

    SELECT * FROM user WHERE name='' OR 1=1 --'
    

    결과: 모든 회원 정보가 노출됨! 🚨

    📌 1.2 해결 방법: prepared statements 사용

    SQL Injection을 방지하려면 **준비된 SQL 문(Prepared Statements)**을 사용해야 합니다.

    아래처럼 기존 insert.php 코드를 변경하세요.

    📌 파일 경로: insert.php (보안 적용)

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $name = trim($_POST['name']); // 입력값 앞뒤 공백 제거
        $age = (int) $_POST['age']; // 숫자로 변환 (문자 입력 방지)
    
        // SQL Injection 방지: Prepared Statements 사용
        $stmt = $conn->prepare("INSERT INTO user (name, age) VALUES (?, ?)");
        $stmt->bind_param("si", $name, $age); // "s" = string, "i" = integer
    
        if ($stmt->execute()) {
            echo "<script>alert('회원 추가 성공!'); location.href='index.php';</script>";
        } else {
            echo "오류 발생: " . $stmt->error;
        }
    
        $stmt->close();
        $conn->close();
    }
    ?>
    

    변경 후 장점

    • ?를 사용하여 변수를 직접 입력하지 않음 → SQL Injection 방지
    • bind_param("si", $name, $age);자료형을 명확히 지정 (s = 문자열, i = 정수)
    • 입력값 검증 추가: trim(), (int) 사용하여 불필요한 공백 제거 및 숫자로 변환

    2️⃣ XSS(크로스 사이트 스크립트) 방지

    XSS(크로스 사이트 스크립트)란, 악의적인 스크립트를 입력하여 웹사이트를 해킹하는 공격입니다.
    예를 들어, name 입력란에 다음과 같이 입력하면,

    <script>alert("해킹됨!");</script>
    

    결과: 사이트를 방문하는 모든 사용자가 해킹 코드에 감염됨! 🚨

    📌 2.1 해결 방법: htmlspecialchars() 사용

    사용자가 입력한 데이터를 웹 페이지에 출력할 때, HTML 태그가 실행되지 않도록 변경해야 합니다.

    아래처럼 기존 index.php 코드를 변경하세요.

    📌 파일 경로: index.php (보안 적용)

    <?php
    include 'db.php'; // 데이터베이스 연결
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>회원 목록</title>
    </head>
    <body>
        <h2>회원 목록</h2>
        <table border="1">
            <tr>
                <th>ID</th>
                <th>이름</th>
                <th>나이</th>
                <th>관리</th>
            </tr>
    
            <?php
            $sql = "SELECT * FROM user";
            $result = $conn->query($sql);
    
            if ($result->num_rows > 0) {
                while ($row = $result->fetch_assoc()) {
                    $safe_name = htmlspecialchars($row['name']); // XSS 방지
                    echo "<tr>
                            <td>{$row['id']}</td>
                            <td>{$safe_name}</td>
                            <td>{$row['age']}</td>
                            <td>
                                <a href='edit.php?id={$row['id']}'>수정</a> | 
                                <a href='delete.php?id={$row['id']}'>삭제</a>
                            </td>
                          </tr>";
                }
            } else {
                echo "<tr><td colspan='4'>등록된 회원이 없습니다.</td></tr>";
            }
    
            $conn->close();
            ?>
        </table>
        <br>
        <a href="insert.php">회원 추가</a>
    </body>
    </html>
    

    변경 후 장점

    • htmlspecialchars($row['name']) → HTML 코드가 실행되지 않음 → XSS 공격 방지

    3️⃣ 사용자 입력값 검증 (유효성 검사)

    보안 강화를 위해, 입력값이 올바른지 검사하는 기능을 추가해야 합니다.

    📌 파일 경로: insert.php (유효성 검사 추가)

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $name = trim($_POST['name']); // 앞뒤 공백 제거
        $age = filter_var($_POST['age'], FILTER_VALIDATE_INT); // 정수인지 확인
    
        if (empty($name)) { // 이름이 비어 있는지 확인
            die("이름을 입력하세요.");
        }
        if ($age === false || $age < 0) { // 나이가 숫자가 아니거나 음수인지 확인
            die("올바른 나이를 입력하세요.");
        }
    
        $stmt = $conn->prepare("INSERT INTO user (name, age) VALUES (?, ?)");
        $stmt->bind_param("si", $name, $age);
    
        if ($stmt->execute()) {
            echo "<script>alert('회원 추가 성공!'); location.href='index.php';</script>";
        } else {
            echo "오류 발생: " . $stmt->error;
        }
    
        $stmt->close();
        $conn->close();
    }
    ?>
    

    변경 후 장점

    • trim() : 공백 제거
    • filter_var($_POST['age'], FILTER_VALIDATE_INT) : 숫자가 아니면 오류
    • if (empty($name)) : 이름이 비었으면 오류

    🎯 최종 점검

    insert.php → SQL Injection 방지 (Prepared Statement 사용)
    index.php → XSS 공격 방지 (htmlspecialchars())
    insert.php → 입력값 검증 (공백 제거, 숫자 확인)

    🚀 이제 보안이 강화된 회원 관리 시스템이 완성되었습니다! 🚀
    이제 다음 단계(파일 업로드 및 이미지 저장)로 진행합니다!

  • 6. 웹서버 운영하기 6th

    6. 웹서버 운영하기 6th

    📌 회원 수정 및 삭제 기능 추가

    이제 회원 정보를 **수정(edit.php)**하고, **삭제(delete.php)**하는 기능을 구현하겠습니다.
    index.php에서 수정 버튼을 클릭하면 해당 회원의 정보를 수정할 수 있도록 만들고,
    삭제 버튼을 클릭하면 해당 회원이 삭제되도록 하겠습니다.

    3️⃣ 회원 정보 수정 (edit.php & update.php)

    📌 3.1 회원 수정 폼 (edit.php)

    회원 정보를 수정할 수 있도록 수정 폼을 생성합니다.
    수정하려는 회원의 ID를 받아와 기존 정보를 표시하고, 새로운 정보를 입력받아 업데이트합니다.

    🔍 코드 해석

    1. $_GET['id'] : URL에서 id 값을 가져옵니다. (edit.php?id=1 같은 URL에서 1을 가져옴)
    2. SELECT * FROM user WHERE id=$id : 해당 id를 가진 회원 정보를 조회합니다.
    3. if (!$row) : 회원 정보가 없을 경우 오류 메시지를 출력합니다.
    4. <form> : HTML 폼을 사용하여 기존 정보를 표시하고 수정할 수 있도록 만듭니다.
    5. <input type="text" name="name" value="값"> : 기존 값을 입력칸에 표시합니다.
    6. <button type="submit"> : 수정 버튼을 클릭하면 업데이트됩니다.

    🖥️ 실행 코드 (edit.php)

    📌 파일 경로: edit.php
    📌 아래 코드를 edit.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    $id = $_GET['id']; // URL에서 회원 ID 가져오기
    $sql = "SELECT * FROM user WHERE id=$id";
    $result = $conn->query($sql);
    $row = $result->fetch_assoc();
    
    if (!$row) {
        echo "<script>alert('회원 정보를 찾을 수 없습니다.'); location.href='index.php';</script>";
    }
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>회원 정보 수정</title>
    </head>
    <body>
        <h2>회원 정보 수정</h2>
        <form method="post" action="update.php">
            <input type="hidden" name="id" value="<?php echo $row['id']; ?>">
            이름: <input type="text" name="name" value="<?php echo $row['name']; ?>" required><br>
            나이: <input type="number" name="age" value="<?php echo $row['age']; ?>" required><br>
            <button type="submit">수정</button>
        </form>
    </body>
    </html>
    

    이제 edit.php에서 회원 정보를 수정하면 update.php에서 변경 내용을 반영하도록 만들어야 합니다.

    📌 3.2 회원 정보 업데이트 (update.php)

    사용자가 입력한 새로운 이름과 나이를 데이터베이스에 저장하는 기능입니다.

    🔍 코드 해석

    1. $_POST['id'], $_POST['name'], $_POST['age'] : 사용자가 입력한 값들을 가져옵니다.
    2. UPDATE user SET name='$name', age='$age' WHERE id=$id : 해당 회원 ID의 정보를 변경합니다.
    3. if ($conn->query($sql) === TRUE) : 업데이트가 성공했는지 확인합니다.
    4. echo "<script>alert('회원 정보 수정 완료!'); location.href='index.php';</script>"; : 성공 시 목록 페이지로 이동합니다.

    🖥️ 실행 코드 (update.php)

    📌 파일 경로: update.php
    📌 아래 코드를 update.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    $id = $_POST['id']; // 수정할 회원 ID
    $name = $_POST['name']; // 새로운 이름
    $age = $_POST['age']; // 새로운 나이
    
    $sql = "UPDATE user SET name='$name', age='$age' WHERE id=$id";
    
    if ($conn->query($sql) === TRUE) {
        echo "<script>alert('회원 정보 수정 완료!'); location.href='index.php';</script>";
    } else {
        echo "오류: " . $conn->error;
    }
    
    $conn->close();
    ?>
    

    이제 index.php에서 “수정” 버튼을 클릭하면 edit.php에서 정보를 수정할 수 있습니다. 🚀
    수정된 정보를 반영하려면 “저장”을 누르면 update.php가 실행됩니다.

    4️⃣ 회원 정보 삭제 (delete.php)

    회원 정보를 삭제하는 기능을 추가합니다.
    사용자가 삭제 버튼을 클릭하면, 해당 회원이 데이터베이스에서 삭제됩니다.

    🔍 코드 해석

    1. $_GET['id'] : URL에서 id 값을 가져옵니다. (delete.php?id=1 같은 URL에서 1을 가져옴)
    2. DELETE FROM user WHERE id=$id : 해당 id를 가진 회원 정보를 삭제합니다.
    3. if ($conn->query($sql) === TRUE) : 삭제가 성공했는지 확인합니다.
    4. echo "<script>alert('회원 삭제 완료!'); location.href='index.php';</script>"; : 성공 시 목록 페이지로 이동합니다.

    🖥️ 실행 코드 (delete.php)

    📌 파일 경로: delete.php
    📌 아래 코드를 delete.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    $id = $_GET['id']; // 삭제할 회원 ID
    $sql = "DELETE FROM user WHERE id=$id";
    
    if ($conn->query($sql) === TRUE) {
        echo "<script>alert('회원 삭제 완료!'); location.href='index.php';</script>";
    } else {
        echo "오류: " . $conn->error;
    }
    
    $conn->close();
    ?>
    

    이제 index.php에서 “삭제” 버튼을 클릭하면 해당 회원이 삭제됩니다. 🚀

    🎯 최종 테스트

    이제 전체 흐름을 테스트해보세요!

    insert.php에서 회원 추가
    index.php에서 회원 목록 확인
    edit.php에서 회원 정보 수정
    update.php 실행 후 정보 변경 확인
    delete.php에서 회원 삭제 확인

    🎯 결과 예시

    📌 1. 회원 추가 (insert.php)

    이름: 이순신
    나이: 55
    [추가] 버튼 클릭
    => 회원 추가 성공!
    

    📌 2. 회원 목록 (index.php)

    +----+--------+----+-----------------+
    | ID | 이름   | 나이 | 관리           |
    +----+--------+----+-----------------+
    | 1  | 홍길동 | 30  | 수정 | 삭제 |
    | 2  | 김철수 | 25  | 수정 | 삭제 |
    | 3  | 이순신 | 55  | 수정 | 삭제 |
    +----+--------+----+-----------------+
    

    📌 3. 회원 수정 (edit.php)

    [수정] 버튼 클릭
    이름: 이순신 → 이순신 장군
    나이: 55 → 60
    [저장] 버튼 클릭
    => 회원 정보 수정 완료!
    

    📌 4. 회원 삭제 (delete.php)

    [삭제] 버튼 클릭
    => 회원 삭제 완료!
    

    🎯 최종 점검

    insert.php에서 회원 추가 기능 구현 완료
    index.php에서 회원 목록 출력 완료
    edit.php & update.php에서 회원 정보 수정 가능
    delete.php에서 회원 삭제 가능

    🚀 이제 웹에서 데이터를 추가, 조회, 수정, 삭제할 수 있는 기능이 완성되었습니다! 🚀

  • 5. 웹서버 운영하기 5th

    5. 웹서버 운영하기 5th

    📌 웹페이지와 데이터베이스 연동 (HTML + PHP + MySQL)

    이제 PHP와 HTML을 결합하여 사용자가 직접 데이터를 입력하고, 수정하고, 삭제할 수 있는 웹 인터페이스를 만들어 보겠습니다.
    즉, 웹페이지에서 폼을 이용해 회원을 추가하고, 리스트를 표시하고, 수정 및 삭제할 수 있도록 구현할 것입니다.

    이번 단계에서 만들 기능

    1. 회원 추가 폼 (insert.php) – 사용자가 이름과 나이를 입력하면 DB에 추가
    2. 회원 목록 조회 (index.php) – 테이블 형태로 DB의 회원 목록을 표시
    3. 회원 수정 기능 (edit.php & update.php) – 특정 회원 정보 변경
    4. 회원 삭제 기능 (delete.php) – 특정 회원 정보 삭제

    1️⃣ 회원 추가 폼 만들기 (HTML + PHP)

    사용자가 이름과 나이를 입력하여 회원을 추가하는 기능을 구현합니다.
    이전 단계에서는 insert.php에서 직접 값을 지정했지만, 이번에는 사용자가 입력할 수 있도록 합니다.

    📌 파일 경로: insert.php
    📌 아래 코드를 insert.php 파일로 저장하세요.

    📌 🔍 코드 해석

    1. <?php ... ?> : PHP 코드를 작성하는 영역입니다.
    2. include 'db.php'; : db.php를 불러와 데이터베이스에 연결합니다.
    3. $_SERVER["REQUEST_METHOD"] == "POST" : 사용자가 폼을 제출했을 때 실행됩니다.
    4. $_POST['name'], $_POST['age'] : 입력한 값(name, age)을 가져옵니다.
    5. INSERT INTO user (name, age) VALUES ('$name', '$age') : 입력한 데이터를 user 테이블에 저장합니다.
    6. <form> : HTML 폼(form)으로 입력 필드를 만듭니다.
    7. <input type="text" name="name"> : 사용자가 이름을 입력합니다.
    8. <input type="number" name="age"> : 사용자가 나이를 입력합니다.
    9. <button type="submit"> : 데이터를 제출합니다.
    <?php
    include 'db.php'; // 데이터베이스 연결
    
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $name = $_POST['name']; // 사용자가 입력한 이름
        $age = $_POST['age'];   // 사용자가 입력한 나이
    
        $sql = "INSERT INTO user (name, age) VALUES ('$name', '$age')";
        
        if ($conn->query($sql) === TRUE) {
            echo "<script>alert('회원 추가 성공!'); location.href='index.php';</script>";
        } else {
            echo "오류: " . $conn->error;
        }
    
        $conn->close();
    }
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>회원 추가</title>
    </head>
    <body>
        <h2>회원 추가</h2>
        <form method="post" action="insert.php">
            이름: <input type="text" name="name" required><br>
            나이: <input type="number" name="age" required><br>
            <button type="submit">추가</button>
        </form>
    </body>
    </html>
    

    브라우저에서 http://주소.com/insert.php 실행 후 회원을 추가해보세요.
    이제 index.php에서 추가된 회원을 확인할 수 있도록 만들어 보겠습니다.

    2️⃣ 회원 목록 조회 (index.php)

    회원 목록을 테이블 형태로 출력하는 페이지를 만듭니다.
    추가된 회원을 표 형태로 화면에 출력하고, 수정 및 삭제 버튼을 추가합니다.

    📌 파일 경로: index.php
    📌 아래 코드를 index.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>회원 목록</title>
    </head>
    <body>
        <h2>회원 목록</h2>
        <table border="1">
            <tr>
                <th>ID</th>
                <th>이름</th>
                <th>나이</th>
                <th>관리</th>
            </tr>
    
            <?php
            $sql = "SELECT * FROM user";
            $result = $conn->query($sql);
    
            if ($result->num_rows > 0) {
                while ($row = $result->fetch_assoc()) {
                    echo "<tr>
                            <td>{$row['id']}</td>
                            <td>{$row['name']}</td>
                            <td>{$row['age']}</td>
                            <td>
                                <a href='edit.php?id={$row['id']}'>수정</a> | 
                                <a href='delete.php?id={$row['id']}'>삭제</a>
                            </td>
                          </tr>";
                }
            } else {
                echo "<tr><td colspan='4'>등록된 회원이 없습니다.</td></tr>";
            }
    
            $conn->close();
            ?>
    
        </table>
        <br>
        <a href="insert.php">회원 추가</a>
    </body>
    </html>
    

    브라우저에서 http://주소.com/index.php 실행 후 회원 목록이 정상적으로 표시되는지 확인하세요.
    이제 수정(edit.php)삭제(delete.php) 기능을 추가하겠습니다.

    3️⃣ 회원 정보 수정 (edit.php & update.php)

    📌 3.1 회원 수정 폼 (edit.php)

    회원 정보를 수정할 수 있도록 수정 폼을 생성합니다.
    수정하려는 회원의 ID를 받아와 기존 정보를 표시하고, 새로운 정보를 입력받아 업데이트합니다.

    📌 파일 경로: edit.php
    📌 아래 코드를 edit.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    $id = $_GET['id']; // URL에서 회원 ID 가져오기
    $sql = "SELECT * FROM user WHERE id=$id";
    $result = $conn->query($sql);
    $row = $result->fetch_assoc();
    
    if (!$row) {
        echo "<script>alert('회원 정보를 찾을 수 없습니다.'); location.href='index.php';</script>";
    }
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>회원 정보 수정</title>
    </head>
    <body>
        <h2>회원 정보 수정</h2>
        <form method="post" action="update.php">
            <input type="hidden" name="id" value="<?php echo $row['id']; ?>">
            이름: <input type="text" name="name" value="<?php echo $row['name']; ?>" required><br>
            나이: <input type="number" name="age" value="<?php echo $row['age']; ?>" required><br>
            <button type="submit">수정</button>
        </form>
    </body>
    </html>
    

    회원 정보를 수정하는 update.php를 생성해야 합니다.

    📌 3.2 회원 정보 업데이트 (update.php)

    📌 파일 경로: update.php
    📌 아래 코드를 update.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    $id = $_POST['id'];
    $name = $_POST['name'];
    $age = $_POST['age'];
    
    $sql = "UPDATE user SET name='$name', age='$age' WHERE id=$id";
    
    if ($conn->query($sql) === TRUE) {
        echo "<script>alert('회원 정보 수정 완료!'); location.href='index.php';</script>";
    } else {
        echo "오류: " . $conn->error;
    }
    
    $conn->close();
    ?>
    

    이제 index.php에서 수정 버튼을 클릭하면 edit.php로 이동하여 정보를 수정할 수 있습니다. 🚀

    4️⃣ 회원 정보 삭제 (delete.php)

    회원 정보를 삭제하는 기능을 추가합니다.

    📌 파일 경로: delete.php
    📌 아래 코드를 delete.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    $id = $_GET['id']; // URL에서 ID 가져오기
    $sql = "DELETE FROM user WHERE id=$id";
    
    if ($conn->query($sql) === TRUE) {
        echo "<script>alert('회원 삭제 완료!'); location.href='index.php';</script>";
    } else {
        echo "오류: " . $conn->error;
    }
    
    $conn->close();
    ?>
    

    이제 index.php에서 삭제 버튼을 클릭하면 delete.php로 이동하여 해당 회원이 삭제됩니다. 🚀

    🎯 최종 점검

    insert.php에서 회원 추가 성공
    index.php에서 회원 목록 정상 출력
    edit.php & update.php에서 회원 정보 수정 가능
    delete.php에서 회원 삭제 가능

  • 4. 웹서버 운영하기 4th

    4. 웹서버 운영하기 4th

    📌 데이터 저장 및 조회 (CRUD 개념 – 상세 가이드)

    이제 PHP에서 **MariaDB(MySQL) 데이터베이스와 연동하여 데이터를 추가, 조회, 수정, 삭제(CRUD)**하는 방법을 배웁니다.
    웹사이트에서 회원 정보를 저장하고, 게시글을 관리하는 등의 기능을 구현할 때 필수적인 개념입니다.

    1️⃣ CRUD란?

    CRUD는 데이터베이스를 다루는 기본적인 4가지 기능입니다.

    기능SQL 명령어설명
    CreateINSERT INTO새로운 데이터를 추가
    ReadSELECT데이터를 조회
    UpdateUPDATE데이터를 수정
    DeleteDELETE데이터를 삭제

    이제 하나씩 실습을 진행해보겠습니다.

    2️⃣ 데이터 삽입 (INSERT INTO)

    우선, 회원 정보를 데이터베이스에 추가하는 기능을 구현해봅시다.

    📌 2.1 SQL로 데이터 삽입

    phpMyAdmin 또는 MySQL 콘솔에서 아래 SQL을 실행하세요.

    INSERT INTO com_test.user (name, age) VALUES ('이순신', 45);
    INSERT INTO com_test.user (name, age) VALUES ('강감찬', 50);
    INSERT INTO com_test.user (name, age) VALUES ('신사임당', 40);
    

    정상적으로 추가되었는지 확인

    SELECT * FROM com_test.user;
    

    출력 예시

    +----+--------+-----+
    | id | name   | age |
    +----+--------+-----+
    |  1 | 홍길동 |  30 |
    |  2 | 김철수 |  25 |
    |  3 | 이영희 |  28 |
    |  4 | 이순신 |  45 |
    |  5 | 강감찬 |  50 |
    |  6 | 신사임당 |  40 |
    +----+--------+-----+
    

    이제 PHP에서 이 데이터를 추가하는 코드도 만들어 보겠습니다. 🚀

    📌 2.2 PHP에서 데이터 삽입 (insert.php 파일 생성)

    이제 PHP 파일을 만들어서 회원 추가 기능을 구현합니다.

    📌 파일 경로: insert.php
    📌 아래 코드를 insert.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    // 회원 정보 추가
    $name = "안중근";
    $age = 35;
    $sql = "INSERT INTO user (name, age) VALUES ('$name', '$age')";
    
    if ($conn->query($sql) === TRUE) {
        echo "회원 추가 성공!";
    } else {
        echo "오류: " . $conn->error;
    }
    
    // 연결 종료
    $conn->close();
    ?>
    

    브라우저에서 http://주소.com/insert.php 실행 후 확인하세요.
    “회원 추가 성공!” 메시지가 나오면 정상적으로 데이터가 삽입된 것입니다. 🚀

    3️⃣ 데이터 조회 (SELECT)

    저장된 데이터를 웹페이지에서 출력하는 코드를 작성합니다.

    📌 파일 경로: select.php
    📌 아래 코드를 select.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    // 데이터 조회
    $sql = "SELECT id, name, age FROM user";
    $result = $conn->query($sql);
    
    if ($result->num_rows > 0) {
        while ($row = $result->fetch_assoc()) {
            echo "ID: " . $row["id"] . " | 이름: " . $row["name"] . " | 나이: " . $row["age"] . "<br>";
        }
    } else {
        echo "등록된 회원이 없습니다.";
    }
    
    // 데이터베이스 연결 종료
    $conn->close();
    ?>
    

    브라우저에서 http://주소.com/select.php 실행 후 회원 목록이 출력되는지 확인하세요. 🚀

    4️⃣ 데이터 수정 (UPDATE)

    이제 저장된 데이터를 수정하는 기능을 구현합니다.

    📌 4.1 SQL로 데이터 수정

    phpMyAdmin에서 아래 SQL을 실행하세요.

    UPDATE com_test.user SET age = 55 WHERE name = '이순신';
    

    정상적으로 수정되었는지 확인

    SELECT * FROM in_com_test.user WHERE name = '이순신';
    

    출력 예시 (나이 변경됨)

    +----+--------+-----+
    | id | name   | age |
    +----+--------+-----+
    |  4 | 이순신 |  55 |
    +----+--------+-----+
    

    이제 PHP에서 데이터를 수정하는 코드도 만들어 보겠습니다. 🚀

    📌 4.2 PHP에서 데이터 수정 (update.php 파일 생성)

    📌 파일 경로: update.php
    📌 아래 코드를 update.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    // 회원 정보 수정
    $id = 4;
    $new_age = 60;
    $sql = "UPDATE user SET age='$new_age' WHERE id=$id";
    
    if ($conn->query($sql) === TRUE) {
        echo "회원 정보 수정 완료!";
    } else {
        echo "오류: " . $conn->error;
    }
    
    // 연결 종료
    $conn->close();
    ?>
    

    브라우저에서 http://주소.com/update.php 실행 후 확인하세요.
    “회원 정보 수정 완료!” 메시지가 나오면 정상적으로 데이터가 수정된 것입니다. 🚀

    5️⃣ 데이터 삭제 (DELETE)

    이제 저장된 데이터를 삭제하는 기능을 구현합니다.

    📌 5.1 SQL로 데이터 삭제

    phpMyAdmin에서 아래 SQL을 실행하세요.

    DELETE FROM com_test.user WHERE name = '이순신';
    

    정상적으로 삭제되었는지 확인

    SELECT * FROM com_test.user;
    

    출력 예시 (이순신 데이터 삭제됨)

    +----+--------+-----+
    | id | name   | age |
    +----+--------+-----+
    |  1 | 홍길동 |  30 |
    |  2 | 김철수 |  25 |
    |  3 | 이영희 |  28 |
    |  5 | 강감찬 |  50 |
    |  6 | 신사임당 |  40 |
    +----+--------+-----+
    

    이제 PHP에서 데이터를 삭제하는 코드도 만들어 보겠습니다. 🚀

    📌 5.2 PHP에서 데이터 삭제 (delete.php 파일 생성)

    📌 파일 경로: delete.php
    📌 아래 코드를 delete.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    // 회원 삭제
    $id = 4;
    $sql = "DELETE FROM user WHERE id=$id";
    
    if ($conn->query($sql) === TRUE) {
        echo "회원 삭제 완료!";
    } else {
        echo "오류: " . $conn->error;
    }
    
    // 연결 종료
    $conn->close();
    ?>
    

    브라우저에서 http://주소.com/delete.php 실행 후 확인하세요.
    “회원 삭제 완료!” 메시지가 나오면 정상적으로 데이터가 삭제된 것입니다. 🚀

    🎯 최종 점검

    insert.php 실행 후 데이터 삽입 성공
    select.php 실행 후 회원 목록 정상 출력
    update.php 실행 후 데이터 변경 확인
    delete.php 실행 후 데이터 삭제 확인

  • 3. 웹서버 운영하기 3th

    3. 웹서버 운영하기 3th

    📌 데이터베이스 (MariaDB) 연결 및 활용

    이번 단계에서는 PHP와 MariaDB(MySQL)를 연동하여 데이터베이스를 다루는 방법을 배웁니다.
    이를 통해 웹사이트에서 데이터를 저장하고, 불러오는 기능을 구현할 수 있습니다.

    1️⃣ 데이터베이스 개념 이해

    📌 1.1 데이터베이스란?

    웹사이트에서 회원 정보, 게시글, 제품 목록 등을 저장하는 공간을 **데이터베이스(Database, DB)**라고 합니다.
    MariaDB는 MySQL과 거의 동일한 오픈소스 데이터베이스 관리 시스템입니다.

    ✅ PHP에서 MariaDB를 사용하려면 다음 과정이 필요합니다:

    1. 데이터베이스 연결
    2. 데이터 삽입 (INSERT)
    3. 데이터 조회 (SELECT)
    4. 데이터 수정 (UPDATE)
    5. 데이터 삭제 (DELETE)

    2️⃣ 데이터베이스 연결 (PHP에서 MariaDB 연결)

    📌 2.1 db.php 파일 생성

    PHP에서 MariaDB에 연결하는 파일을 생성합니다.

    📌 파일 경로: db.php
    📌 아래 코드를 db.php 파일로 저장하세요.

    <?php
    $host = "localhost"; // 서버 주소 (보통 localhost)
    $user = "root"; // 데이터베이스 사용자명
    $password = "비밀번호"; // 데이터베이스 비밀번호
    $database = "test"; // 사용할 데이터베이스 이름
    
    // 데이터베이스 연결
    $conn = new mysqli($host, $user, $password, $database);
    
    // 연결 확인
    if ($conn->connect_error) {
        die("데이터베이스 연결 실패: " . $conn->connect_error);
    }
    
    // 한글 깨짐 방지 설정
    $conn->set_charset("utf8");
    
    ?>
    

    이제 PHP에서 include 'db.php';로 이 파일을 불러와 사용하면 됩니다.
    db.php를 저장한 후 브라우저에서 http://주소/db.php를 실행하여 에러가 없는지 확인하세요.

    📌 2.2 데이터베이스 연결 확인

    db.php 파일을 실행했을 때, 아래처럼 나오면 정상적으로 연결된 것입니다.

    (아무 메시지도 출력되지 않음 = 정상)
    

    만약 오류가 발생한다면, 아래 사항을 점검하세요.

    1. db.php에서 $user, $password, $database가 올바른지 확인
    2. MySQL 서비스가 실행 중인지 확인 (sudo systemctl status mariadb)
    3. phpMyAdmin에서 직접 로그인해보고 계정이 올바른지 확인

    이제 데이터베이스 연결이 정상적으로 되었으면 다음 단계로 이동합니다. 🚀

    3️⃣ 데이터베이스 테이블 생성

    📌 3.1 테이블 확인

    phpMyAdmin 또는 MySQL 콘솔에서 com_test 데이터베이스에 user 테이블이 있는지 확인합니다.

    SHOW TABLES FROM com_test;
    

    테이블이 이미 있다면 다음 단계(데이터 삽입)로 이동하세요.
    테이블이 없으면 아래 SQL을 실행해서 생성하세요.

    📌 3.2 user 테이블 생성

    phpMyAdmin에서 SQL 실행 창(SQL 탭)에 아래 코드를 입력하고 실행합니다.

    CREATE TABLE IF NOT EXISTS user (
        id INT AUTO_INCREMENT PRIMARY KEY,  -- 회원 ID (자동 증가)
        name VARCHAR(100) NOT NULL,         -- 회원 이름
        age INT NOT NULL                    -- 나이 (숫자)
    );
    

    테이블이 정상적으로 생성되었는지 확인하려면 아래 SQL을 실행하세요.

    DESC com_test.user;
    

    정상적인 경우 결과 예시

    +-------+--------------+------+-----+---------+----------------+
    | Field | Type         | Null | Key | Default | Extra          |
    +-------+--------------+------+-----+---------+----------------+
    | id    | int(11)      | NO   | PRI | NULL    | auto_increment |
    | name  | varchar(100) | NO   |     | NULL    |                |
    | age   | int(11)      | NO   |     | NULL    |                |
    +-------+--------------+------+-----+---------+----------------+
    

    테이블이 정상적으로 생성되었으면 다음 단계로 이동합니다. 🚀

    4️⃣ 데이터 삽입 (INSERT INTO)

    이제 user 테이블에 데이터를 추가합니다.

    📌 4.1 SQL로 데이터 삽입

    phpMyAdmin에서 실행:

    INSERT INTO com_test.user (name, age) VALUES ('홍길동', 30);
    INSERT INTO com_test.user (name, age) VALUES ('김철수', 25);
    INSERT INTO com_test.user (name, age) VALUES ('이영희', 28);
    

    정상적으로 추가되었는지 확인

    SELECT * FROM com_test.user;
    

    출력 예시

    +----+--------+-----+
    | id | name   | age |
    +----+--------+-----+
    |  1 | 홍길동 |  30 |
    |  2 | 김철수 |  25 |
    |  3 | 이영희 |  28 |
    +----+--------+-----+
    

    📌 4.2 PHP에서 데이터 삽입

    📌 파일 경로: insert.php
    📌 아래 코드를 insert.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    // 회원 정보 추가
    $name = "이순신";
    $age = 45;
    $sql = "INSERT INTO user (name, age) VALUES ('$name', '$age')";
    
    if ($conn->query($sql) === TRUE) {
        echo "회원 추가 성공!";
    } else {
        echo "오류: " . $conn->error;
    }
    
    // 연결 종료
    $conn->close();
    ?>
    

    브라우저에서 http://주소.com/insert.php 실행 후 확인하세요.
    “회원 추가 성공!” 메시지가 나오면 정상적으로 데이터가 삽입된 것입니다. 🚀

    5️⃣ 데이터 조회 (SELECT)

    저장된 데이터를 웹페이지에서 출력하는 코드입니다.

    📌 파일 경로: select.php
    📌 아래 코드를 select.php 파일로 저장하세요.

    <?php
    include 'db.php'; // 데이터베이스 연결
    
    // 데이터 조회
    $sql = "SELECT id, name, age FROM user";
    $result = $conn->query($sql);
    
    if ($result->num_rows > 0) {
        while ($row = $result->fetch_assoc()) {
            echo "ID: " . $row["id"] . " | 이름: " . $row["name"] . " | 나이: " . $row["age"] . "<br>";
        }
    } else {
        echo "등록된 회원이 없습니다.";
    }
    
    // 연결 종료
    $conn->close();
    ?>
    

    브라우저에서 http://주소.com/select.php 실행 후 확인하세요.
    회원 목록이 정상적으로 출력되는지 확인하세요. 🚀


    🎯 최종 점검

    db.php를 통해 MariaDB 연결 성공
    com_test.user 테이블 생성 완료
    insert.php 실행 후 데이터 삽입 성공
    select.php 실행 후 회원 목록 정상 출력

  • 2. 웹서버 운영하기 2th

    2. 웹서버 운영하기 2th

    📌 배열과 함수 배우기

    이번 단계에서는 배열과 함수를 배웁니다.
    배열을 이용하면 여러 개의 데이터를 저장할 수 있고, 함수를 사용하면 코드의 재사용성을 높일 수 있습니다.

    1️⃣ 배열 (Array)

    배열이란 하나의 변수에 여러 개의 값을 저장할 수 있는 구조입니다.
    예를 들어, "사과", "바나나", "딸기"라는 값을 개별 변수에 저장하는 대신, 배열을 사용하면 한 번에 관리할 수 있습니다.

    1.1 인덱스 배열 (순서대로 저장)

    인덱스 배열은 **숫자로 자동 인덱스(순서)**가 부여되는 배열입니다.
    배열의 첫 번째 요소는 0, 두 번째는 1, 세 번째는 2 … 이런 식으로 인덱스가 증가합니다.

    <?php
    $fruits = array("사과", "바나나", "딸기"); // 배열 선언
    echo $fruits[0]; // "사과" 출력
    ?>
    

    📌 실습 문제 1

    아래 배열에서 첫 번째 색상을 출력하는 코드를 작성하세요.

    <?php
    $colors = ["빨강", "파랑", "초록"];
    // 여기에 코드를 작성하세요.
    ?>
    

    🏆 정답 1

    <?php
    $colors = ["빨강", "파랑", "초록"];
    echo "첫 번째 색상: " . $colors[0];
    ?>
    

    🔍 출력 결과

    첫 번째 색상: 빨강
    

    🔍 정답 해석

    • $colors = ["빨강", "파랑", "초록"];
      "빨강", "파랑", "초록" 세 가지 값을 가진 배열을 생성했습니다.
    • $colors[0]
      첫 번째 값(인덱스 0)을 가져옵니다. 결과는 "빨강"입니다.

    1.2 연관 배열 (키-값 형태)

    연관 배열은 숫자 대신 키(key)를 직접 정해서 값(value)을 저장하는 배열입니다.
    예를 들어 "이름" => "홍길동", "나이" => 30 처럼 사용할 수 있습니다.

    <?php
    $user = array(
        "이름" => "홍길동",
        "나이" => 30
    );
    echo "이름: " . $user["이름"];
    ?>
    

    📌 실습 문제 2

    아래 배열에서 “직업” 키에 해당하는 값을 출력하는 코드를 작성하세요.

    <?php
    $person = ["이름" => "김철수", "나이" => 25, "직업" => "개발자"];
    // 여기에 코드를 작성하세요.
    ?>
    

    🏆 정답 2

    <?php
    $person = ["이름" => "김철수", "나이" => 25, "직업" => "개발자"];
    echo "직업: " . $person["직업"];
    ?>
    

    🔍 출력 결과

    직업: 개발자
    

    🔍 정답 해석

    • "직업" => "개발자"
      "직업"이라는 키를 만들고 "개발자"라는 값을 저장했습니다.
    • $person["직업"]
      "직업" 키의 값을 가져와서 출력합니다. 결과는 "개발자"입니다.

    1.3 배열 반복 (foreach)

    foreach 문을 사용하면 배열의 모든 값을 자동으로 하나씩 꺼내서 사용할 수 있습니다.

    <?php
    $animals = ["강아지", "고양이", "코끼리"];
    foreach ($animals as $animal) {
        echo "동물: $animal <br>";
    }
    ?>
    

    📌 실습 문제 3

    아래 배열에서 모든 과일을 출력하는 foreach 반복문을 작성하세요.

    <?php
    $fruits = ["사과", "배", "포도"];
    // 여기에 코드를 작성하세요.
    ?>
    

    🏆 정답 3

    <?php
    $fruits = ["사과", "배", "포도"];
    foreach ($fruits as $fruit) {
        echo "과일: $fruit <br>";
    }
    ?>
    

    🔍 출력 결과

    과일: 사과  
    과일: 배  
    과일: 포도  
    

    🔍 정답 해석

    • foreach ($fruits as $fruit)
      → 배열 $fruits의 각 요소를 순서대로 변수 $fruit에 저장하여 실행합니다.
    • echo "과일: $fruit";
      → 각 요소를 화면에 출력합니다.

    2️⃣ 함수 (Function)

    함수는 특정 동작을 수행하는 코드 블록입니다.
    함수를 사용하면 코드를 재사용할 수 있고 가독성이 높아집니다.

    2.1 기본 함수

    <?php
    function greet() {
        echo "안녕하세요!<br>";
    }
    greet();
    ?>
    

    📌 실습 문제 4

    아래 함수를 완성하여 **”환영합니다!”를 출력하는 함수를 만드세요.

    <?php
    function welcome() {
        // 여기에 코드를 작성하세요.
    }
    welcome();
    ?>
    

    🏆 정답 4

    <?php
    function welcome() {
        echo "환영합니다!<br>";
    }
    welcome();
    ?>
    

    🔍 출력 결과

    환영합니다!
    

    🔍 정답 해석

    • function welcome()
      welcome이라는 이름의 함수를 정의했습니다.
    • echo "환영합니다!<br>";
      "환영합니다!"를 출력하는 기능을 추가했습니다.
    • welcome();
      → 함수를 호출하여 실행했습니다.

    2.2 매개변수와 반환값

    함수는 매개변수(인자)를 받을 수도 있고, 값을 반환할 수도 있습니다.

    <?php
    function add($a, $b) {
        return $a + $b;
    }
    echo add(3, 4); // 7 출력
    ?>
    

    📌 실습 문제 5

    아래 함수를 완성하여 두 숫자를 곱한 결과를 반환하는 함수를 작성하세요.

    <?php
    function multiply($x, $y) {
        // 여기에 코드를 작성하세요.
    }
    echo multiply(5, 6);
    ?>
    

    🏆 정답 5

    <?php
    function multiply($x, $y) {
        return $x * $y;
    }
    echo multiply(5, 6); // 30 출력
    ?>
    

    🔍 출력 결과

    30
    

    🔍 정답 해석

    • function multiply($x, $y)
      multiply라는 이름의 함수를 만들고, xy를 매개변수로 받았습니다.
    • return $x * $y;
      xy를 곱한 결과를 반환합니다.
    • echo multiply(5, 6);
      multiply(5, 6)을 실행하면 5 × 6 = 30을 반환하여 출력됩니다.

    🎯 정리

    배열 (Array)

    1. 인덱스 배열: 숫자로 인덱싱된 배열
    2. 연관 배열: 키-값 형태의 배열
    3. **반복문 foreach**로 배열 출력

    함수 (Function)

    1. 기본 함수: 특정 기능을 수행하는 코드 블록
    2. 매개변수: 함수에 값을 전달하는 방법
    3. **반환값 (return)**을 이용한 결과 반환

    🎉 이제 실습을 진행해 보시고, 성공하면 네 번째 단계(데이터베이스 연결)로 넘어가겠습니다! 🚀

  • 1. 웹서버 운영하기 1th

    1. 웹서버 운영하기 1th

    💡 어떤 방식으로 진행할까요?

    1. 기본 개념 익히기
      • 웹 개발의 기본 개념: HTML, CSS, JavaScript, PHP, 데이터베이스(MariaDB)
      • PHP 문법 및 코드 작성 방법
      • PHP에서 MySQL(MariaDB) 데이터베이스 연결과 활용
    2. 현재 사이트 분석 및 수정 방법 배우기
      • 운영중인 사이트의 PHP 코드 구조 분석
      • 필요한 기능을 수정하는 방법
      • 에러 해결 방법 및 디버깅
    3. 사이트 성능 최적화 및 유지보수
      • 동시 접속자 수 증가를 위한 최적화
      • 보안 설정 및 서버 유지보수

    📌 PHP 기초 배우기

    우선, PHP 기본 문법부터 익혀야 합니다. 현재 서버에 PHP 7.4-FPM이 설치되어 있으므로 이 버전을 기준으로 진행하겠습니다.

    ✅ 첫 번째 미션: PHP 코드 실행해보기

    NAS에 test.php 파일을 만들어 PHP 코드가 정상적으로 실행되는지 확인해 보세요.

    1. 파일 만들기
      • /web/test.php 파일을 생성합니다.
      • 아래 코드를 작성한 후 저장합니다.

        <?php echo "안녕하세요, PHP가 정상적으로 실행됩니다!"; ?>
    2. 브라우저에서 실행해보기
      • http://********.com/test.php 또는 http://NAS_IP/test.php 에 접속합니다.
      • “안녕하세요, PHP가 정상적으로 실행됩니다!” 라는 메시지가 보이면 성공입니다.

    이제 본격적으로 PHP 기초를 배우면서 ********.com의 코드를 분석하고 수정하는 방법을 익혀봅시다.

    📌 PHP 기본 문법 배우기

    ********.com을 수정하려면 PHP 기본 문법을 알아야 합니다. 가장 중요한 개념부터 하나씩 배워볼게요.

    1. 변수와 데이터 타입

    PHP에서는 변수를 $ 기호로 선언합니다.

    📌 실습 미션 1: 변수 사용해보기

    아래 코드를 /web/variable_test.php 파일에 작성하고 브라우저에서 실행해 보세요.

    <?php
    $name = "********.com";  // 문자열 변수
    $year = 2025;  // 정수 변수
    $price = 1500.75;  // 실수 변수
    $isOpen = true;  // 불리언 변수
    
    // 출력하기
    echo "사이트 이름: " . $name . "<br>";
    echo "운영 연도: " . $year . "<br>";
    echo "서비스 가격: " . $price . "원<br>";
    echo "운영 중인가요? " . ($isOpen ? "예" : "아니오") . "<br>";
    ?>
    

    🔍 실행 결과 예시:

    사이트 이름: ********.com  
    운영 연도: 2025  
    서비스 가격: 1500.75원  
    운영 중인가요? 예  
    

    2. 조건문 (if, else)

    사이트에서 특정 조건(예: 로그인 상태, 관리자 여부 등)에 따라 다르게 동작하게 하려면 if 문을 사용합니다.

    📌 실습 미션 2: 로그인 확인 기능 만들기

    아래 코드를 /web/login_check.php 파일에 저장하고 실행해 보세요.

    <?php
    $user_logged_in = true; // 사용자가 로그인했다고 가정
    
    if ($user_logged_in) {
        echo "환영합니다! 사이트를 자유롭게 이용하세요.";
    } else {
        echo "로그인이 필요합니다. 로그인 페이지로 이동합니다.";
    }
    ?>
    

    🔍 실행 결과 예시:

    환영합니다! 사이트를 자유롭게 이용하세요.
    

    (변수 $user_logged_in = false; 로 변경하면 “로그인이 필요합니다.”가 출력됩니다.)

    3. 반복문 (for, while)

    반복문을 이용하면 같은 코드를 여러 번 실행할 수 있습니다.

    📌 실습 미션 3: 1부터 10까지 숫자 출력

    아래 코드를 /web/loop_test.php 파일에 저장하고 실행하세요.

    <?php
    for ($i = 1; $i <= 10; $i++) {
        echo "숫자: $i <br>";
    }
    ?>
    

    🔍 실행 결과 예시:

    숫자: 1  
    숫자: 2  
    숫자: 3  
    ...
    숫자: 10  
    

    잠깐, (), {}, ++ 이 세 가지는 PHP에서 매우 중요한 역할을 합니다. 하나씩 쉽게 설명해 드릴게요.

    1️⃣ () (괄호)

    괄호 ()는 주로 다음과 같은 경우에 사용됩니다.

    1.1 함수의 인자(매개변수) 전달

    • 함수를 호출할 때 값을 전달할 때 사용합니다.
    <?php
    function sayHello($name) {
        echo "안녕하세요, $name 님!<br>";
    }
    
    sayHello("철수");
    sayHello("영희");
    ?>
    

    📌 실행 결과:

    안녕하세요, 철수 님!
    안녕하세요, 영희 님!
    

    1.2 조건문 및 반복문에서 사용

    • if, for, while 등에서 조건을 검사할 때 사용됩니다.
    <?php
    $age = 20;
    if ($age >= 18) { // (조건)
        echo "성인입니다.<br>";
    }
    ?>
    
    <?php
    for ($i = 1; $i <= 5; $i++) { // (초기값; 조건; 증가)
        echo "반복 횟수: $i <br>";
    }
    ?>
    

    2️⃣ {} (중괄호)

    중괄호 {}코드 블록을 정의할 때 사용됩니다.

    2.1 조건문과 반복문에서 사용

    • if, for, while 등의 코드 블록을 그룹화합니다.
    <?php
    $score = 85;
    
    if ($score >= 90) {
        echo "A 학점입니다.<br>";
    } elseif ($score >= 80) {
        echo "B 학점입니다.<br>";
    } else {
        echo "C 학점입니다.<br>";
    }
    ?>
    
    <?php
    for ($i = 1; $i <= 3; $i++) {
        echo "반복 중: $i <br>";
    }
    ?>
    

    2.2 함수와 클래스에서 사용

    • 함수 및 클래스 정의할 때 코드 블록을 감쌉니다.
    <?php
    function greet() {
        echo "안녕하세요!<br>";
    }
    
    greet();
    ?>
    

    3️⃣ ++ (증가 연산자)

    ++ 연산자는 변수의 값을 1 증가시킵니다.

    3.1 사용 예시

    <?php
    $count = 1;
    $count++; // count = count + 1
    echo "현재 값: $count"; // 2 출력
    ?>
    

    3.2 ++의 위치에 따른 차이

    연산자설명
    $i++현재 값을 먼저 사용하고, 이후 1 증가 (후위 증가)
    ++$i먼저 1 증가한 후에 값 사용 (전위 증가)
    <?php
    $i = 5;
    echo $i++; // 5 출력 (먼저 출력 후 증가)
    echo "<br>";
    echo $i; // 6 출력 (이전 증가 반영)
    ?>
    
    <?php
    $i = 5;
    echo ++$i; // 6 출력 (먼저 증가 후 출력)
    ?>
    

    📌 정리

    1. () : 함수 호출, 조건문, 반복문 등에 사용
    2. {} : 코드 블록을 감싸는 역할
    3. ++ : 변수를 1 증가시키는 연산자

    ✅ 연습 문제:
    아래 PHP 코드를 실행해 보고 결과를 예측해 보세요!

    <?php
    $num = 10;
    if ($num > 5) {
        echo "5보다 큽니다.<br>";
    }
    
    for ($i = 1; $i <= 3; $i++) {
        echo "반복: $i <br>";
    }
    
    $counter = 5;
    echo $counter++; // ?
    echo "<br>";
    echo ++$counter; // ?
    ?>
    

    실행 후 다음 단계로 넘어갈게요! 🚀

  • 시놀로지 920+ 웹서버 최적화 설정하기

    시놀로지 920+ 웹서버 최적화 설정하기

    ✅ Intel Celeron J4125 + DDR4 20GB RAM + SSD 캐시(NVMe 512GB×2) + RAID 4TB×2 + 기가비트 듀얼 랜 + MariaDB + Nginx + PHP 7.4-FPM + ionCube 구동시 접속 가능 인원 및 최적화 방법

    📌 1. 예상 동시 접속 가능 인원 분석

    동시 접속 가능 인원은 CPU 성능, RAM, SSD 캐시, 웹서버 최적화, 네트워크 설정 등에 따라 달라집니다.

    🔹 현재 사양에서 예상 동시 접속자

    서버 구성웹서버캐싱 적용 여부예상 동시 접속자
    기본 설정 (최적화 없음)Nginx + PHP 7.4-FPMX1,000~2,000명
    기본 최적화 (PHP-FPM + OPcache 적용)Nginx + PHP 7.4-FPMO2,500~3,500명
    고급 최적화 (Redis + Memcached + CDN 적용 + 듀얼 랜포트 LACP)Nginx + PHP 7.4-FPM + RedisO4,500~5,500명

    기본 설정으로는 최대 2,000명 수준
    PHP-FPM + OPcache 적용하면 3,500명까지 가능
    Redis / Memcached / CDN 적용 시 최대 5,500명 동시 접속 가능

    📌 2. Synology DS920+ 최적화 방법

    현재 서버의 병목 지점은 **CPU (Celeron J4125)**와 **네트워크(1Gbps 한계)**입니다. 하지만 최적화 적용 시 동시 접속자를 5,500명까지 확장 가능합니다.

    1️⃣ 네트워크 최적화 (듀얼 랜포트 활용)

    920+에는 1GbE 듀얼 랜포트가 있으므로 LACP(Link Aggregation) 또는 Load Balancing을 설정하여 네트워크 부하를 줄일 수 있습니다.

    설정 방법
    Synology DSM → 제어판(Control Panel) → 네트워크(Network) → 네트워크 인터페이스(Network Interface)
    두 개의 랜포트 선택 후 “Create Bond” → “IEEE 802.3ad Dynamic Link Aggregation (LACP)” 설정
    (⚠️ 사용 중인 스위치에서 LACP 지원 여부 확인 필요)

    효과:
    ✔ 네트워크 부하 감소 (최대 2Gbps)
    ✔ 동시 접속 시 데이터 병목 해소

    2️⃣ 웹서버 최적화 (Nginx + PHP-FPM)

    920+의 리소스를 최대한 활용하려면 PHP-FPM 프로세스 관리 및 Nginx 설정 최적화가 필요합니다.

    Nginx 최적화 설정 (/etc/nginx/nginx.conf 수정)

    ini

    worker_processes auto;
    worker_rlimit_nofile 65535;

    events {
    worker_connections 8192;
    multi_accept on;
    }

    http {
    keepalive_timeout 15;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    client_max_body_size 200M;
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;
    }

    효과:
    ✔ 더 많은 동시 접속 처리 가능
    ✔ 웹사이트 응답 속도 향상

    PHP-FPM 최적화 설정 (/etc/php/7.4/fpm/pool.d/www.conf 수정)

    ini

    pm = dynamic
    pm.max_children = 300
    pm.start_servers = 80
    pm.min_spare_servers = 40
    pm.max_spare_servers = 150
    pm.process_idle_timeout = 10s;
    pm.max_requests = 5000

    효과:
    ✔ PHP 프로세스 처리 속도 증가
    ✔ PHP-FPM 과부하 방지

    3️⃣ MariaDB 최적화 (데이터베이스 속도 향상)

    MariaDB 설정을 최적화하여 DB 쿼리 처리 속도를 증가시킬 수 있습니다.

    MariaDB 설정 (/etc/mysql/my.cnf 수정)

    ini

    [mysqld]
    max_connections = 500
    query_cache_size = 512M
    innodb_buffer_pool_size = 8G
    innodb_log_file_size = 512M
    tmp_table_size = 256M
    max_heap_table_size = 256M
    table_open_cache = 5000

    효과:
    ✔ DB 성능 향상 (쿼리 처리 속도 증가)
    ✔ 동시 접속자가 많아질 때 DB 부하 감소

    4️⃣ 캐싱 최적화 (Redis & Memcached 적용)

    PHP-FPM과 DB 부하를 줄이기 위해 Redis와 Memcached를 적용하면 성능이 크게 향상됩니다.

    설치 명령어 (Synology SSH 접속 후 실행)

    sh

    sudo apt update
    sudo apt install redis memcached -y

    Redis 설정 (/etc/redis/redis.conf)

    ini복사편집maxmemory 2gb
    maxmemory-policy allkeys-lru
    

    Memcached 설정 (/etc/memcached.conf)

    ini복사편집-m 1024
    

    효과:
    ✔ DB 쿼리 캐싱으로 속도 향상
    ✔ 서버 부하 감소

    5️⃣ CDN 적용 (Cloudflare 또는 AWS CloudFront)

    정적 리소스를 CDN으로 오프로드하면 서버 부하가 감소하고 응답 속도가 향상됩니다.

    Cloudflare 사용 시 적용 방법

    1. Cloudflare 계정 생성 및 사이트 등록
    2. CDN 설정에서 정적 파일(이미지, CSS, JS) 캐싱 활성화
    3. DNS를 Cloudflare 네임서버로 변경

    효과:
    ✔ 웹서버 부하 감소
    ✔ 동시 접속자 증가 시 속도 유지

    📌 3. 최적화 적용 후 동시 접속 증가 예상

    최적화 적용 전최적화 적용 후
    기본 설정 (1,000~2,000명)PHP-FPM + OPcache 적용 (2,500~3,500명)
    Nginx/MariaDB 최적화 (4,000명 가능)Redis + Memcached + CDN 적용 (5,500명 가능)

    듀얼 랜포트 설정 & 웹서버 최적화 시 최대 5,500명까지 가능
    920+의 CPU 제한이 있으므로, 6,000명 이상 접속 시 더 강력한 서버 필요

    📌 4. 결론 및 추천

    • 현재 설정으로 최대 2,000명 동시 접속 가능
    • 듀얼 랜포트, Nginx 최적화, MariaDB 캐싱 적용 시 4,500~5,500명 동시 접속 가능
    • 920+의 Celeron J4125 CPU 성능이 동시 6,000명 이상을 처리하기에는 한계 있음

    즉, 920+의 최적화를 적용하면 최대 5,500명까지 동시 접속 가능하지만, 그 이상을 원하면 CPU 업그레이드 필요 🚀