Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

Leeyanggoo

[PHP] 게시판1 -> 회원가입 로그인 기능 만들기!! 본문

2023/MySQL

[PHP] 게시판1 -> 회원가입 로그인 기능 만들기!!

Leeyanggoo 2023. 4. 19. 23:31

by 생활코딩 opentutorials.org

 

 

PHP란?

PHP는 서버 측 스크립팅 언어이며, HTML, CSS, JavaScript와 함께 사용되며, 사용자 입력을 처리하고 데이터베이스와 상호 작용하는 데에도 자주 사용됩니다.

MySQL 데이터베이스와 상호 작용하여 동적 웹 페이지를 생성하는 데 주로 사용됩니다. MySQLi는 PHP에서 MySQL 데이터베이스와 상호 작용하는 데 사용되는 확장 라이브러리입니다.

PHP와 MySQLi를 연동하기 위해서는 먼저 PHP에서 MySQLi 확장을 활성화해야 합니다. 이를 위해서는 php.ini 파일에서 mysqli 확장을 활성화하거나, PHP 코드에서 mysqli_connect() 함수를 사용하여 연결할 수 있습니다.

 

connect.php

<?php
    // phpinfo();
    $host = "localhost";
    $user = "root";
    $pw = "root";
    $db = "phpClass";
    $connect = new mysqli($host, $user, $pw, $db);
    $connect -> set_charset("utf-8");

    if(mysqli_connect_errno()){
        echo "database Connect False";
    } else {
        // echo "database Connet True";
    }
?>

 

위 코드는 PHP에서 mysqli를 사용하여 MySQL 데이터베이스에 연결하는 예시입니다. 코드에서는 먼저 localhost, root, root, phpClass 값을 갖는 $host, $user, $pw, $db 변수를 설정하고, mysqli 객체를 생성합니다.

그리고 set_charset() 함수를 사용하여 문자 집합을 설정합니다. 이를 통해 데이터베이스와의 상호 작용 시 문자 인코딩에 문제가 발생하지 않도록 합니다.

마지막으로, mysqli_connect_errno() 함수를 사용하여 연결이 성공했는지 확인하고, 실패한 경우 "database Connect False"를 출력합니다.

 

회원가입

 

join.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>회원가입 페이지</title>

    <?php include "../include/head.php" ?>
</head>
<body class="gray">
    
    <?php include "../include/skip.php" ?>
    <!-- //skip -->

    <?php include "../include/header.php" ?>
    <!-- //header -->

    <main id="main" class="container">
        <div class="intro__inner center bmStyle">
            <div class="intro__images">
                <picture>
                    <source srcset="../assets/img/join01.png, ../assets/img/join01@2x.png 2x, ../assets/img/join01@3x.png 3x">
                    <img src="../assets/img/join01.png" alt="회원가입 이미지">
                </picture>
            </div>
            <p class="intro__text">
                회원가입을 해주시면 다양한 정보를 자유롭게 볼 수 있습니다.
            </p>
        </div>
        <!-- //intro__inner -->
        <div class="join__inner container">
            <h2>회원가입</h2>
            <div class="join__form">
                <form action="joinSave.php" name="join" method="post">
                    <fieldset>
                        <legend class="blind">회원가입 영역</legend>
                        <div>
                            <label for="youEmail" class="labelStyle required">이메일</label>
                            <input type="email" id="youEmail" name="youEmail" class="inputStyle" placeholder="이메일을 적어주세요!" required>
                        </div>
                        <div>
                            <label for="youName" class="labelStyle required">이름</label>
                            <input type="text" id="youName" name="youName" class="inputStyle" placeholder="이름을 적어주세요!" required>
                        </div>
                        <div>
                            <label for="youPass" class="labelStyle required">비밀번호</label>
                            <input type="password" id="youPass" name="youPass" class="inputStyle" placeholder="비밀번호를 적어주세요!" required>
                        </div>
                        <div>
                            <label for="youPassC" class="labelStyle required">비밀번호 확인</label>
                            <input type="password" id="youPassC" name="youPassC" class="inputStyle" placeholder="다시 한번 비밀번호를 적어주세요." required>
                        </div>
                        <div>
                            <label for="youPhone" class="labelStyle required">연락처</label>
                            <input type="text" id="youPhone" name="youPhone" class="inputStyle" placeholder="연락처를 적어주세요!" required>
                        </div>
                        <button type="submit" class="btnStyle">회원가입 완료</button>
                    </fieldset>
                </form>
            </div>
        </div>
    </main>
    <!-- //main -->
</body>
</html>

 

PHP에서 include는 다른 PHP 파일이나 HTML 파일 등 외부 파일을 현재 PHP 파일에 포함시키는 기능을 제공합니다. 즉, include를 사용하여 외부 파일의 내용을 현재 파일에 복사하거나 가져올 수 있습니다.

웹 페이지의 공통적으로 쓰이는 부분들을 별도의 php 파일에 담아서 관리할 수 있습니다.

해당 예제에서는 head, header, skip 부분을 include를 통해 가져옵니다. head.php에는 CSS 파일이 링크되어 있습니다.

 

form 태그는 HTML에서 사용되며, 사용자로부터 정보를 입력받아 서버로 전송할 때 사용됩니다.

 

  • action : 데이터를 처리할 서버 측 스크립트 파일의 경로를 지정합니다.
  • method : HTTP 요청 방식을 지정합니다. 일반적으로 GET 또는 POST 방식을 사용합니다.
  • name : 태그의 이름을 지정합니다.
  • id : 태그의 고유 식별자를 시정합니다.

 

form 태그 내부의 input, label 등의 form 요소들은 name 속성을 가집니다.

이 name 속성은 데이터를 서버로 전송할 때, 데이터의 이름을 지정하는 역할을 합니다.

input 요소의 type 속성은 이메일, 비밀번호, 전화번호 등의 입력 필드를 생성할 때 사용합니다.

label 요소의 for 속성 값과 input 요소의 id 속성 값은 동일해야 합니다. 이는 label 요소가 input 요소를 참조하기 위한 것입니다. for 속성은 label 요소가 참조하는 input 요소의 id 값을 지정하는데, 이로써 사용자가 레이블을 클릭했을 때 해당 입력 요소가 선택되도록 합니다.

마지막 form 태그의 submit 버튼을 클릭하면 form 태그의 action 속성에 지정된 경로(joinSave.php)로 데이터가 전송됩니다.

 

joinSave.php

<?php
    include "../connect/connect.php";

    $youEmail = $_POST['youEmail'];
    $youName = $_POST['youName'];
    $youPass = $_POST['youPass'];
    $youPassC = $_POST['youPassC'];
    $youPhone = $_POST['youPhone'];
    $regTime = time();

    // echo $youEmail, $youName, $youPass, $youPhone;
    // $sql = "INSERT INTO members(youEmail, youName, youPass, youPhone, regTime) VALUES('$youEmail', '$youName', '$youPass', '$youPhone', '$regTime')";
    // $connect -> query($sql);

    //메세지 출력
    function msg($alert){
        echo "<p class='intro__text'>$alert</p>";
    }

    //이메일 유효성 검사
    $check_mail = preg_match("/^[a-z0-9_+.-]+@([a-z0-9]+\.)+[a-z0-9]{2,4}$/", $youEmail);
    if($check_mail == false){
        msg("이메일이 잘못되었습니다. 다시 한번 확인해주세요.");
        exit;
    }

    //이름 유효성 검사
    $check_name = preg_match("/^[가-힣]{9,15}$/", $youName);
    if($check_name == false){
        msg("이름은 한글 3~5글자만 가능합니다.");
        exit;
    } 

    //비밀번호 유효성 검사
    if($youPass !== $youPassC){
        msg("비밀번호가 일치하지 않습니다. 다시 한번 확인해주세요.");
        exit;
    } 
    //비밀번호 암호화
    // $youPass = sha1($youPass);

    //휴대폰 번호 유효성 검사
    $check_number = preg_match("/^(010|011|016|017|018|019)-[0-9]{3,4}-[0-9]{4}$/", $youPhone);
    if($check_number == false){
        msg("번호가 정확하지 않습니다. 올바른 번호(000-0000-0000) 형식으로 작성해주세요!");
        exit;
    }

    //이메일 중복 검사
    $isEmailCheck = false;

    $sql = "SELECT youEmail FROM members WHERE youEmail = '$youEmail'";
    $result = $connect -> query($sql);

    if($result){
        $count = $result -> num_rows;

        if($count == 0){
            $isEmailCheck = true;
        } else {
            msg("이미 회원가입이 되어 있습니다. 로그인해주세요!");
            exit;
        }
    } else {
        msg("에러발생1 : 관리자에게 문의하세요.");
        exit;
    }

    //핸드폰 중복 검사
    $isPhoneCheck = false;

    $sql = "SELECT youPhone FROM members WHERE youPhone = '$youPhone'";
    $result = $connect -> query($sql);

    if($result){
        $count = $result -> num_rows;

        if($count == 0){
            $isPhoneCheck = true;
        } else {
            msg("이미 회원가입이 되어 있습니다. 로그인 해주세요!");
            exit;
        }
    } else {
        msg("에러발생2 : 관리자에게 문의하세요.");
        exit;
    }

    //회원가입
    if($isEmailCheck == true && $isPhoneCheck == true){
        //데이터 입력하기
        $sql = "INSERT INTO members(youEmail, youName, youPass, youPhone, regTime) VALUES('$youEmail', '$youName', '$youPass', '$youPhone', '$regTime')";
        $connect -> query($sql);

        if($result){
            msg("회원가입을 축하합니다! 로그인 해주세요! <br><div class='intro__btn'><a href='../login/login.php'>로그인</a></div>");
        } else {
            msg("에러발생3 : 관리자에게 문의하세요.");
            exit;
        }
    } else {
        msg("이미 회원가입이 되어 있습니다. 로그인 해주세요!");
        exit;
    }
?>

 

joinSave.php는 회원가입 정보를 저장하는 페이지입니다.

먼저 connect.php 파일을 include 하여 데이터베이스에 접속합니다. 그다음, POST 방식으로 전송된 회원가입 정보를 변수에 저장합니다.

 

그 후, 유효성 검사를 진행합니다. 이메일, 이름, 비밀번호, 핸드폰 번호의 유효성을 검사하고, 이상이 있을 경우 메시지를 출력하고 프로그램을 종료합니다.

preg_match는 PHP에서 정규식 패턴을 이용한 문자열 검색 함수 중 하나입니다. preg_match 함수는 주어진 정규식 패턴에 대한 문자열 검색을 수행하여 검색 결과를 반환합니다. 각각의 유효성 검사는 정규식을 이용하여 검사하고 있습니다.

 

  • 이메일 : preg_match("/^[a-z0-9_+.-]+@([a-z0-9]+\.)+[a-z0-9]{2,4}$/", $youEmail);
  • 이름 : preg_match("/^[가-힣]{3,5}$/", $youName);
  • 비밀번호 : $youPass !== $youPassC //youPassC는 사용자가 한 번 더 입력한 비밀번호
  • 핸드폰 번호 : preg_match("/^(010|011|016|017|018|019)-[0-9]{3,4}-[0-9]{4}$/", $youPhone);

 

msg()는 매개변수로 전달된 메시지를 출력하는 함수입니다.

exit는 PHP에서 프로그램의 실행을 중단하고 종료시키는 함수입니다. 주로 오류 처리나 예외 처리에서 사용됩니다.

만약 사용자가 조건에 맞지 않는 양식으로 회원가입을 하려고 하면 메시지를 보내고 exit 함수로 종료합니다.

 

이메일과 핸드폰 번호는 다른 사용자와 구별되는 양식이므로 중복 검사를 수행합니다.

각각의 검사를 '$isEmailCheck'와 '$isPhoneCheck' 변수에 저장하고, 둘 다 올바르게 작성한 경우에만(true) 데이터베이스에 회원가입 정보를 저장합니다.

회원가입 정보는 SQL 쿼리문(INSERT INTO 테이블명 (열1, 열2, ...) VALUES (값1, 값2, ...))으로 작성되어 $connect->query() 메서드를 사용하여 데이터베이스에 저장됩니다.

$connect->query()는 MySQL 쿼리를 실행하기 위한 메서드입니다. 이 메서드는 mysqli 객체의 메서드 중 하나로, $connect 변수는 데이터베이스 연결 정보를 저장하는 mysqli 객체입니다.

MySQL 데이터베이스에 쿼리문을 전송하고, 결과를 반환합니다. 이 메서드는 SELECT 쿼리를 실행할 때는 결과를 반환하며, INSERT, UPDATE, DELETE 쿼리를 실행할 때는 적용된 행 수를 반환합니다.

저장에 성공하면 축하 메시지를 출력합니다. 그렇지 않으면 에러 메시지를 출력하고 프로그램을 종료합니다.

 

로그인

 

login.php

<main id="main" class="container">
	<div class="login__inner">
        <h2>로그인</h2>
        <p>로그인을 하시면 게시글 및 댓글 작성이 가능합니다.<br>회원가입을 하시면 로그인이 가능합니다.<br>admin@admin.com/1234</p>
        <div class="login__form btStyle bmStyle">
            <form action="loginSave.php" name="loginSave" method="post">
                <fieldset>
                    <legend class="blind">로그인 영역</legend>
                    <div>
                        <label for="youEmail" class="labelStyle blind required">이메일</label>
                        <input type="email" id="youEmail" name="youEmail" class="inputStyle" placeholder="이메일을 적어주세요!" required>
                    </div>
                    <div>
                        <label for="youPass" class="labelStyle blind required">비밀번호</label>
                        <input type="password" id="youPass" name="youPass" class="inputStyle" placeholder="비밀번호를 적어주세요!" required>
                    </div>
                    <button type="submit" class="btnStyle2 mt20">로그인</button>
                </fieldset>
            </form>
        </div>
        <div class="login__footer">
            <ul class="listStyle2">
                <li>회원가입을 하지 않았다면 회원가입을 먼저 해주세요! <a href="join.html">회원가입</a></li>
                <li>아이디가 기억나지 않는다면? <a href="#">아이디 찾기</a></li>
                <li>비밀번호가 기억나지 않는다면? <a href="#">비밀번호 찾기</a></li>
            </ul>
        </div>
    </div>
</main>

 

로그인 페이지는 사용자에게 필요한 정보를 입력하도록 하고 그 정보를 form 태그의 action 속성에 지정된 경로로 로그인 정보를 전송합니다.

회원가입 페이지에서 여러 사용자 정보를 요구했다면 로그인 페이지는 비교적 적은 입력 필드를 가지게 됩니다.

placeholder 속성은 input 입력 필드에 미리 보여줄 힌트 메시지를 지정하여, 사용자가 어떤 정보를 입력해야 하는지 알려주고 있습니다.

required 속성은 해당 입력 필드가 필수 입력 사항임을 나타내는 속성입니다.

로그인 페이지 또한 회원가입 페이지처럼 form 태그를 통해 서버 데이터베이스에 데이터를 전달합니다.

 

또한 하단에 여러 안내 문구를 배치하여 사용자에게 회원가입 및 아이디, 비밀번호 찾기 페이지로 이동할 수 있도록 구성되어 있습니다.

 

loginSave.php

<?php
    include "../connect/connect.php";
    include "../connect/session.php";

    $youEmail = $_POST['youEmail'];
    $youPass = $_POST['youPass'];

    // echo $youEmail, $youPass;

    //데이터 출력
    function msg($alert){
        echo "<p class='intro__text'>$alert</p>";
    }

    //데이터 조회
    $sql = "SELECT memberID, youEmail, youName, youPass FROM members WHERE youEmail = '$youEmail' AND youPass = '$youPass'";
    $result = $connect -> query($sql);

    if($result){
        $count = $result -> num_rows;

        if($count == 0){
            msg("이메일 또는 비밀번호가 틀렸습니다. 다시 한번 확인해주세요.<br><div class='intro__btn'><a href='../login/login.php'>로그인</a></div>");
        } else {
            // 로그인 성공
            $memberInfo = $result -> fetch_array(MYSQLI_ASSOC);

            // echo "<pre>";
            // var_dump($memberInfo);
            // echo "</pre>";

            // 세션 생성
            $_SESSION['memberID'] = $memberInfo['memberID'];
            $_SESSION['youEmail'] = $memberInfo['youEmail'];
            $_SESSION['youName'] = $memberInfo['youName'];

            Header("Location:../main/main.php");
        }
    }
?>

 

loginSave.php는 로그인 정보를 검증하는 페이지입니다.

로그인 form에서 입력된 이메일과 비밀번호를 POST 방식으로 받아와서, 입력된 정보를 데이터베이스에서 조회합니다.

데이터베이스 조회는 SQL의 SELECT 쿼리문을 통해 youEmail과 youPass 열에 들어있는 사용자 정보와 일치하는지 비교하게 됩니다.

num_rows는 쿼리의 결과로 반환된 집합의 행 수를 반환합니다. 이를 통해 결과 집합에 반환된 레코드 수를 확인할 수 있으므로, 결과 집합이 존재하는지 여부를 확인할 수 있습니다.

만약 데이터 조회 결과가 0이면 해당 데이터가 없는 것이므로, 메시지를 출력하고 다시 로그인 페이지로 이동합니다.

 

결과가 0이 아니라면, 로그인이 성공한 것으로 판단하고 조회한 회원 정보를 기반으로 세션을 생성합니다.

fetch_array() 메서드는 쿼리 결과의 첫 번째 레코드를 배열 형태로 반환합니다.

MYSQLI_ASSOC 옵션은 필드(컬럼) 이름을 키(key)로 사용하여 반환합니다.

따라서 fetch_array(MYSQLI_ASSOC) 메서드를 사용하게 되면, 데이터베이스로부터 레코드를 연관 배열 형태로 가져올 수 있습니다. 이때, 각 필드의 이름이 배열의 키(key)가 되며, 그에 해당하는 값이 배열의 값(value)이 됩니다.

연관 배열은 인덱스가 문자열 또는 숫자로 사용할 수 있는 배열을 말합니다.

 

세션(Session)은 서버 측에서 데이터를 저장하기 위한 방법으로, PHP에서 제공하는 기능입니다.

세션을 사용하면, 로그인과 같이 다른 페이지에서도 유저의 정보를 사용해야 하는 상황에서 유용하게 사용할 수 있습니다.

로그인한 유저의 정보를 세션 변수에 저장해두고, 다른 페이지에서도 이 변수를 사용하여 유저 정보를 가져올 수 있습니다.

$_SESSION은 PHP에서 세션을 다루기 위한 내장 변수로, 로그인 정보를 서버 측에서 유지하기 위해 사용됩니다.

세션을 사용하기 위해서는 session_start() 함수를 호출해야 합니다.

이 함수는 session.php에서 호출하고 있으며, include로 호출 페이지를 불러오고 있습니다.

이 함수를 호출하면, PHP는 서버에 세션 ID를 생성하고, 이 ID를 클라이언트에게 쿠키(cookie) 형태로 전달합니다. 이후에 클라이언트가 다시 접속할 때는 이 쿠키를 이용하여 서버에서 세션 ID를 확인하고, 해당 세션에 저장된 변수를 사용할 수 있습니다.

 

Header()는 PHP에서 HTTP 헤더를 보내는 함수입니다. 이 함수는 웹 페이지를 동적으로 생성하는 PHP 스크립트에서 다른 페이지로 이동하거나, 다운로드할 파일을 제공하거나, 캐시 제어 등의 용도로 사용됩니다.

 

위 코드에서는 로그인에 성공한 경우, mysqli_fetch_array() 메서드를 통해 반환된 배열을 $memberInfo 변수에 할당하고, 이 변수의 값을 세션 변수에 저장하고 있습니다. 이후, Header() 함수를 사용하여 페이지를 이동시킵니다. 이렇게 함으로써, 로그인에 성공한 경우에만 세션 변수를 설정하고, 이를 사용하여 로그인 상태를 유지할 수 있습니다.

 


 

 

 

🚀 코드 보러 가기

🚀 index.html로 쳐들어 가기(HTML만 방문 가능)