PHP & MySQL

09. PHP MySQL CRUD 애플리케이션 만들기(Procedural)

drizzle0925 2021. 10. 24. 16:53
728x90

PHP와 MySQL을 이용해서 간단한 CRUD 애플리케이션을 만들어 보겠습니다. 

애플리케이션 제작방법은  Procedural(함수형), Object Oriented(객체 지향), PDO(PHP Data Object) 3가지 방법으로 제작해볼 예정이며 이 게시글에서는 Procedural 방법으로 제작해 보겠습니다.

 

CRUD란?

CRUD는 4가지 단어의 약자로 C는 Create, R는 Read, U는 Update, D는 Delete를 의미합니다.

CRUD는 데이터베이스의 기본 데이터 조작으로 데이터 생성, 읽기, 업데이트, 삭제 작업을 뜻합니다.


데이터베이스 & 테이블을 만들기

 

아래 SQL 쿼리를 이용해서 실습에 이용할 데이터 베이스를 생성합니다.

CREATE DATABASE tutorials;

 

tutorials 데이터베이스 선택 쿼리

use tutorials;

 

아래 SQL 쿼리를 이용해서 tutorials 데이터베이스 내부에 employees라는 테이블을 생성합니다.

CREATE TABLE employees (
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    address VARCHAR(255) NOT NULL,
    salary INT(10) NOT NULL
);

DB 연결 설정 스크립트 만들기

 

데이터베이스를 생성했으면 PHP 스크립트 작성합니다.

config.php라는 파일을 만들고 그 안에 다음 코드를 입력합니다. 

나중에 require_once() 함수를 사용하여 이 파일을 다른 페이지에 포함시킬 겁니다.

<?php 
define('DB_SERVER','127.0.0.1'); // 호스트 주소
define('DB_USERNAME','root'); // MySQL 사용자 계정
define('DB_PASSWORD','111111'); // MySQL 사용자 비밀번호
define('DB_NAME','tutorials'); // 사용할 데이터베이스 이름

// 데이터 베이스 연결
$link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);

// 연결 체크 
if($link === false){
    die("에러: 연결할 수 없습니다. " . mysqli_connect_error());
}
?>

랜딩 페이지 만들기

우선 직원 데이터베이스 테이블의 레코드를 표시하는 랜딩페이지를 만듭니다. 랜딩 페이지 생성은 부트스트랩을 이용해서 간편하게 만들어 보겠습니다.

 

index.php 파일을 만들고 그 안에 아래 코드를 입력합니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dashboard</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
    <style>
        .wrapper{
            width: 600px;
            margin: 0 auto;
        }
        table tr td:last-child{
            width: 120px;
        }
    </style>
    <script>
        $(document).ready(function(){
            $('[data-toggle="tooltip"]').tooltip();   
        });
    </script>
</head>
<body>
<div class="wrapper">
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-12">
                    <div class="mt-5 mb-3 clearfix">
                        <h2 class="pull-left">직원 목록</h2>
                        <a href="create.php" class="btn btn-success pull-right"><i class="fa fa-plus"></i> 새 직원 등록하기</a>
                    </div>
                    <?php
                    // config파일을 불러옵니다.
                    require_once "config.php";
                    
                    // select 쿼리를 실행합니다.
                    $sql = "SELECT * FROM employees";
                    if($result = mysqli_query($link, $sql)){
                        if(mysqli_num_rows($result) > 0){
                            echo '<table class="table table-bordered table-striped">';
                                echo "<thead>";
                                    echo "<tr>";
                                        echo "<th>#</th>";
                                        echo "<th>이름</th>";
                                        echo "<th>주소</th>";
                                        echo "<th>급여</th>";
                                        echo "<th>옵션</th>";
                                    echo "</tr>";
                                echo "</thead>";
                                echo "<tbody>";
                                while($row = mysqli_fetch_array($result)){
                                    echo "<tr>";
                                        echo "<td>" . $row['id'] . "</td>";
                                        echo "<td>" . $row['name'] . "</td>";
                                        echo "<td>" . $row['address'] . "</td>";
                                        echo "<td>" . $row['salary'] . "</td>";
                                        echo "<td>";
                                            echo '<a href="read.php?id='. $row['id'] .'" class="mr-3" title="View Record" data-toggle="tooltip"><span class="fa fa-eye"></span></a>';
                                            echo '<a href="update.php?id='. $row['id'] .'" class="mr-3" title="Update Record" data-toggle="tooltip"><span class="fa fa-pencil"></span></a>';
                                            echo '<a href="delete.php?id='. $row['id'] .'" title="Delete Record" data-toggle="tooltip"><span class="fa fa-trash"></span></a>';
                                        echo "</td>";
                                    echo "</tr>";
                                }
                                echo "</tbody>";                            
                            echo "</table>";
                            // 쿼리 결과를 메모리에서 해제합니다.
                            mysqli_free_result($result);
                        } else{
                            echo '<div class="alert alert-danger"><em>등록된 정보가 없습니다.</em></div>';
                        }
                    } else{
                        echo "에러가 발생했습니다. 잠시 후에 다시 시도해 주세요.";
                    }
 
                    // 연결을 종료합니다.
                    mysqli_close($link);
                    ?>
                </div>
            </div>        
        </div>
    </div>
</body>
</html>

 

index.php에 접속하면 아래와 같이 표시됩니다.

 

MySQL창을 실행시켜 몇 건의 데이터를 등록하고 다시 index.php 페이지를 확인해 보겠습니다.


등록 페이지 만들기

CRUD의 C인 Create 기능을 구현해 보겠습니다.

create.php 파일을 만들고 그 안에 아래 코드를 입력합니다. 직원 테이블에 레코드를 삽입하는 데 사용할 페이지를 만듭니다.

<?php 
// 설정 파일을 불러옵니다.
require_once "config.php";

// 변수를 초기화 합니다.
$name = $address = $salary = "";
$name_err = $address_err = $salary_err = "";

// form 데이터가 전송됐을 때 처리 로직입니다.
if($_SERVER["REQUEST_METHOD"] == "POST"){
    // 이름 확인
    $input_name = trim($_POST['name']);
    if(empty($input_name)){
        $name_err = "이름을 입력해 주세요.";
    }elseif(!filter_var($input_name, FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>"/^[ㄱ-ㅎ가-힣a-zA-Z\s]+$/")))){
        $name_err = "한글 또는 영어만 입력해 주세요.";
    }else{
        $name = $input_name;
    }

    // 주소 확인
    $input_address = trim($_POST["address"]);
    if(empty($input_address)){
        $address_err = "주소를 입력해 주세요.";
    }else{
        $address = $input_address;
    }

    // 급여 확인
    $input_salary = trim($_POST['salary']);
    if(empty($input_salary)){
        $salary_err = "급여를 입력해 주세요";
    }elseif(!ctype_digit($input_salary)){
        $salary_err = "숫자만 입력이 가능합니다. 다시 입력해 주세요.";
    }else{
        $salary = $input_salary;
    }

    // 데이터베이스에 삽입하기 전에 입력 오류 확인
    if(empty($name_err) && empty($address_err) && empty($salary_err)){
        $sql = "INSERT INTO employees (name, address, salary) VALUES (?,?,?)";

        if($stmt = mysqli_prepare($link, $sql)){
            mysqli_stmt_bind_param($stmt, "sss", $param_name, $param_address, $param_salary);

            // 매개변수 설정
            $param_name = $name;
            $param_address = $address;
            $param_salary = $salary;

            // 준비된 명령문 실행
            if(mysqli_stmt_execute($stmt)){
                // 레코드가 생성에 성공했을 경우
                header("Location: index.php");
                exit();
            }else{
                echo "레코드 생성에 실패했습니다. 잠시 후에 다시 시도해 주세요.";
            }
        }
        // statement 종료
        mysqli_stmt_close($stmt);
    }
    // 접속 종료
    mysqli_close($link);
}
?>

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>등록하기</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <style>
        .wrapper{
            width: 600px;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-12">
                    <h2 class="mt-5">등록하기</h2>
                    <p>아래 내용을 작성하여 데이터베이스에 직원을 등록해주세요.</p>
                    <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
                        <div class="form-group">
                            <label>이름</label>
                            <input type="text" name="name" class="form-control <?php echo (!empty($name_err)) ? 'is-invalid' : ''; ?>" value="<?php echo $name; ?>">
                            <span class="invalid-feedback"><?php echo $name_err;?></span>
                        </div>
                        <div class="form-group">
                            <label>주소</label>
                            <textarea name="address" class="form-control <?php echo (!empty($address_err)) ? 'is-invalid' : ''; ?>"><?php echo $address; ?></textarea>
                            <span class="invalid-feedback"><?php echo $address_err;?></span>
                        </div>
                        <div class="form-group">
                            <label>급여</label>
                            <input type="text" name="salary" class="form-control <?php echo (!empty($salary_err)) ? 'is-invalid' : ''; ?>" value="<?php echo $salary; ?>">
                            <span class="invalid-feedback"><?php echo $salary_err;?></span>
                        </div>
                        <input type="submit" class="btn btn-primary" value="등록하기">
                        <a href="index.php" class="btn btn-secondary ml-2">취소하기</a>
                    </form>
                </div>
            </div>        
        </div>
    </div>
</body>
</html>

 

create.php 파일로 접속하면 아래와 같은 화면이 출력됩니다.

 

공백으로 등록하기를 선택할 경우 유효성 검사가 동작하는 것을 확인할 수 있습니다.

 

전부 입력하고 등록하면 정상적으로 등록되는 것을 확인할 수 있습니다.


읽기 페이지 만들기

CRUD의 R인 Read 기능을 구현해보겠습니다.

read.php 파일을 만들고 그 안에 아래 코드를 입력합니다. 직원의 id 속성을 이용하여 직원 테이블에서 레코드를 검색합니다. 

<?php 
// get parameter 확인
if(isset($_GET["id"]) && !empty(trim($_GET["id"]))){
    // config 파일 불러오기
    require_once "config.php";

    // select문 준비
    $sql = "SELECT * FROM employees WHERE id = ?";

    if($stmt = mysqli_prepare($link, $sql)){
        // 준비된 명령문에 변수를 매개변수로 바인딩
        mysqli_stmt_bind_param($stmt, "i", $param_id);

        // parameters 셋팅
        $param_id = trim($_GET['id']);

        // 준비된 명령문 실행시도
        if(mysqli_stmt_execute($stmt)){
            $result = mysqli_stmt_get_result($stmt);

            if(mysqli_num_rows($result) == 1){
                // 열과 행을 연관 배열로 가져옵니다.
                // id로 조회하기 때문에 하나의 행만 포함하므로 while 루프를 사용할 필요가 없습니다.
                $row = mysqli_fetch_array($result, MYSQLI_ASSOC);

                // 개별 필드 값 검색
                $name = $row["name"];
                $address = $row["address"];
                $salary = $row["salary"];
            }else{
                // 유효한 ID 매개변수가 없는 경우 오류 페이지로 이동
                header("location: error.php");
                exit();
            }
        }else{
            echo "문제가 발생했습니다. 나중에 다시 시도해 주세요.";
        }
    }
    // prepare statement를 닫습니다.
    mysqli_stmt_close($stmt);

    // 열어둔 데이터베이스 접속을 종료합니다.
    mysqli_close($link);
}else{
    // URL에 id 매개변수가 없습니다. 오류 페이지로 이동
    header("location: error.php");
    exit();
}
?>

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>View Record</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <style>
        .wrapper{
            width: 600px;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-12">
                    <h1 class="mt-5 mb-3">View Record</h1>
                    <div class="form-group">
                        <label for="">이름</label>
                        <p><b><?php echo $row["name"]; ?></b></p>
                    </div>
                    <div class="form-group">
                        <label for="">주소</label>
                        <p><b><?php echo $row["address"]; ?></b></p>
                    </div>
                    <div class="form-group">
                        <label for="">급여</label>
                        <p><b><?php echo $row["salary"]; ?></b></p>
                    </div>
                    <p><a href="index.php" class="btn btn-primary">Back</a></p>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

 

 

눈 모양 아이콘을 클릭하면 View Record(read.php) 페이지로 이동합니다.


업데이트 페이지 만들기

CRUD의 U, Update 기능을 구현하겠습니다.

 

update.php라는 파일을 만들고 그 안에 다음 코드를 넣습니다. 직원의 id 속성을 기반으로 직원 테이블의 기존 레코드를 업데이트합니다.

<?php 
require_once "config.php";

$name = $address = $salary = "";
$name_err = $address_err = $salary_err = "";

if(isset($_POST["id"]) && !empty($_POST["id"])){
    $id = $_POST["id"];

    $input_name = trim($_POST["name"]);
    if(empty($input_nme)){
        $name_err = "이름을 입력해 주세요.";
    }elseif(!filter_var($input_name, FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>"\^[a-zA-zㄱ-ㅎ가-힣]+$/")))){
        $name_err = "유효한 이름을 입력해 주세요.";
    }else{
        $name = $input_name;
    }

    $input_address = trim($_POST["address"]);
    if(empty($input_address)){
        $address_err = "주소를 입력해 주세요";
    }else{
        $address = $input_address;
    }

    $input_salary = trim($_POST["salary"]);
    if(empty($input_slary)){
        $salary_err = "급여를 입력해 주세요.";
    }elseif(!ctype_digit($input_salary)){
        $salary_err = "정수를 입력해 주세요.";
    }else{
        $salary = $input_salary;
    }

    if(empty($name_err) && empty($address_err) && empty($salary_err)){
        $sql = "UPDATE employees SET name=?, address=?, salary=? WHERE id=?";

        if($stmt = mysqli_prepare($link, $sql)){
            mysqli_stmt_bind_param($stmt, "sssi", $param_name, $param_address, $param_salary, $param_id);

            $param_name = $name;
            $param_address = $address;
            $param_salary = $salary;
            $param_id = $id;

            if(mysqli_stmt_execute($stmt)){
                header("location: index.php");
                exit();
            }else{
                echo "에러가 발생했습니다. 잠시 후에 다시 시도해 주세요.";
            }
        }
        mysqli_stmt_close($stmt);
    }
    mysqli_close($link);
}else{
    if(isset($_GET["id"]) && !empty(trim($_GET["id"]))){
        $id = trim($_GET["id"]);

        $sql = "SELECT * FROM employees WHERE id = ?";
        if($stmt = mysqli_prepare($link, $sql)){
            mysqli_stmt_bind_param($stmt, "i", $param_id);

            $param_id = $id;

            if(mysqli_stmt_execute($stmt)){
                $result = mysqli_stmt_get_result($stmt);

                if(mysqli_num_rows($result) == 1){
                    $row = mysqli_fetch_array($result, MYSQLI_ASSOC);

                    $name = $row["name"];
                    $address = $row["address"];
                    $salary = $row["salary"];
                }else{
                    header("loction: error.php");
                    exit();
                }

            }else{
                echo "에러가 발생했습니다. 잠시 후에 다시 시도해 주세요.";
            }
        }

        mysqli_stmt_close($stmt);

        mysqli_close($link);
    }else{
        header("location: error.php");
        exit();
    }
}
?>

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>레코드 수정하기</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <style>
        .wrapper{
            width: 600px;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-12">
                    <h2 class="mt-5">레코드 수정하기</h2>
                    <p>입력 값을 편집하고 제출하여 직원 기록을 업데이트하십시오.</p>
                    <form action="<?php echo htmlspecialchars(basename($_SERVER['REQUEST_URI']));?>" method="post">
                        <div class="form-group">
                            <label for="">이르</label>
                            <input type="text" name="name" class="form-control <?php echo (!empty($name_err)) ? 'is-invalid' : '';?>" value="<?php echo $name?>">
                            <span class="invalid-feedback"><?php echo $name_err;?></span>
                        </div>
                        <div class="form-group">
                            <label for="">주소</label>
                            <input type="text" name="address" class="form-control <?php echo (!empty($address_err)) ? 'is-invalid' : '';?>" value="<?php echo $address?>">
                            <span class="invalid-feedback"><?php echo $address_err;?></span>
                        </div>
                        <div class="form-group">
                            <label for="">급여</label>
                            <input type="text" name="salary" class="form-control <?php echo (!empty($salary_err)) ? 'is-invalid' : '';?>" value="<?php echo $salary?>">
                            <span class="invalid-feedback"><?php echo $salary_err;?></span>
                        </div>
                        <input type="hidden" name="id" value="<?php echo $id;?>" />
                        <input type="submit" class="btn btn-primary" value="Submit">
                        <a href="index.php" class="btn btn-secondary ml-2">Cancel</a>
                    </form>
                </div>
            </div>
        </div>
    </div>
</body>
</html>


삭제 페이지 만들기

CRUD의 D인 Delete 기능을 구현하겠습니다. 

 

delete.php라는 파일을 만들고 그 안에 다음 코드를 넣습니다. 직원의 id 속성을 기반으로 직원 테이블에서 기존 레코드를 삭제합니다.

<?php 
// 확인 후 삭제 작업 처리
if(isset($_POST["id"]) && !empty($_POST["id"])){
    // config file 포함
    require_once "config.php";

    // 삭제 문 준비
    $sql = "DELETE FROM employees WHERE id = ?";

    if($stmt = mysqli_prepare($link, $sql)){
        // 준비된 명령문에 변수를 매개변수로 바인딩
        mysqli_stmt_bind_param($stmt, "i", $param_id);

        // 매개변수 설정
        $param_id = trim($_POST["id"]);

        // 준비된 명령문 실행 시도
        if(mysqli_stmt_execute($stmt)){
            // 레코드가 성공적으로 삭제되었습니다. index 페이지로 이동
            header("location: index.php");
            exit();
        }else{
            echo "문제가 발생했습니다. 나중에 다시 시도하십시오.";
        }
    }

    // statement 닫기
    mysqli_stmt_close($stmt);

    // 접속 닫기
    mysqli_close($link);
}else{
    // id 매개변수의 존재 확인
    if(empty(trim($_GET["id"]))){
        // URL에 id 매개변수가 없습니다. 오류 페이지로 이동
        header("location: error.php");
        exit();
    }
}
?>

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>레코드 삭제하기</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <style>
        .wrapper{
            width: 600px;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-12">
                    <h2 class="mt-5 mb-3">레코드 삭제하기</h2>
                    <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
                    <div class="alert alert-danger">
                        <input type="hidden" name="id" value="<?php echo trim($_GET["id"]);?>" />
                        <p>이 직원 기록을 삭제하시겠습니까?</p>
                        <p>
                            <input type="submit" value="네" class="btn btn-danger">
                            <a href="index.php" class="btn btn-secondary">아니요</a>
                        </p>
                    </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</body>
</html>


오류 페이지 만들기

마지막으로 "error.php" 파일을 생성하겠습니다. 요청이 유효하지 않은 경우(예: URL 쿼리 문자열에서 id 매개변수가 누락되었거나 유효하지 않은 경우) 이 페이지가 표시됩니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>오류</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <style>
        wrapper{
            width: 600px;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-12">
                    <h2 class="mt-5 mb-3">잘못된 요청입니다.</h2>
                    <div class="alert alert-danger">죄송합니다. 잘못된 요청을 하셨습니다. <a href="index.php" clss="alert-link">이전페이지</a>로 돌아가 다시 시도해 주세요.</div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>


Github : https://github.com/jun0925/php-CURD

 

728x90

'PHP & MySQL' 카테고리의 다른 글

08. 글삭제  (0) 2021.03.27
07. 글수정  (0) 2021.03.26
06. PHP & MySQL 보안  (0) 2021.03.26
05. 글읽기  (0) 2021.03.18
04. PHP와 MySQL의 연동과 SELECT  (0) 2021.03.18