[Project] *사용자 사이트 구축* / PHP / 2. 회원가입
2023.06.10 - [사이드 프로젝트 도전기] - [Project] *사용자 사이트 구축* / PHP / 1. 환경 구축 부터 로그인까지
한걸음부터 다시 시작하기 프로젝트!
간단한 사용자 사이트를 서버부터 페이지까지 만들어보기
2. 회원가입
1. 환경구축 및 로그인편에서 이어집니다!
기술스택요약
- 사용언어 : PHP, HTML, SQL
- 데이터베이스 : mySQL
- 서버 : Apache
- 사용툴 및 환경 : 챗 GPT, 휴먼지능(본인), VsCode, XAMPP
프로젝트 요약 (회원가입)
- HTML을 통한 웹 기능 및 디자인
- PHP를 통한기능 구현 (데이터베이스 연결 및 HTML 입력값을 받아 데이터베이스에 추가하여 회원가입을 완료시킨다.)
구현 느낀점 요약
- 앞글에서도 언급했지만 회원가입은 내생각보다 더 까다로웠다.
- 버튼은 submit이 아니므로 동기화를 시켜줘야한다.
- 생각보다 경우의 수가 너무 다양해서 구현하기 힘들었다.
- HTML 에서 버튼은 Submit이 아니므로 버튼을 누를때마다 통신하려면 아작스를 이용해야한다.
- GPT에게 코드를 완전 맡기는 것 보다 기본틀을 제공받고 본인이 수정하는 게 좀더 빨랐다… → 이부분에서 굉장히 삽질했음. 😂💃 (쉬운길은없어..)
기본적으로 로그인 페이지에서 회원가입 페이지를 누르면 연결하도록 하였다.
Login_page.html
<a href="Join_page.html">회원가입</a>
경로를 연결할때는 항상 절대경로와 상대경로그리고 이름을 잘확인하여야 한다.
기능 및 디자인 정리
회원가입을 만들다가 요소를 추가하고 추가하고 추가하다 보니까 정리가 잘안되어서 내가 원하는 기능 이나 디자인을 부분을 정리해보기로 했다.
- 회원가입 양식은 필수 양식임.
- 사용자는 유효한 이메일 형식을 사용해야함.
→ 사용자는 이메일형식이 아닌 다른 형식을 사용할때 페이지를 넘어가지 않고 수정할 수 있도록 해야함. - 기존에 데이터베이스에 있는 중복 ID를 사용할 수 없음 → ID중복확인을 눌렀을때 사용자가 페이지를 넘어가지 않고 해당 화면에서 확인할 수 있어야함.
→ 버튼을 눌렀을 때 페이지가 이동되지 않고 통신으로 계속 값을 받아와야함. - 유효한 이메일 형식을 사용하였더라도 Password와 Password Confirm 이 맞지않으면 가입이 안됨.
- Password ↔ Password Confirm이 일치하더라도 유효한 이메일(양식, 중복) 상태일때 ID를 다시 확인하라는 문구가 작성됨.
- 모든 필수 칸이 유효할 때 데이터베이스에 ID,PW 전송하여 회원가입완료!
페이지를 넘어가지않고 특정한 양식에 값을 검사해야한다는 부분이 조금 발목을잡았던 것 같다.
나는 해당 기능을 프로젝트 중간에 정리하여 지체했지만 앞으로는 조금더 자세히 명시하여 시작할 필요가 있는 것 같다.
join_page.html
//Join.HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입</title>
</style>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
function clearDefaultValue(input) {
if (input.value === input.defaultValue) {
input.value = "";
}
}
var duplicate_message = '';
function id_duplication() {
/* ID 중복 확인 버튼을 클릭했을 때 실행할 코드 */
/* PHP 파일로부터 받은 응답을 처리하는 코드*/
var email = document.getElementById("email").value;
$.ajax({
url: 'check_duplicate.php', // PHP 파일의 경로
type: 'POST',
dataType: 'html',
data: {email:email}, // PHP 파일로 전달할 데이터
success: function(response) {
$('#duplicate_message').html(response); // 결과를 표시할 요소에 HTML 삽입
duplicate_message = $('#duplicate_message').text();
confirm_error();
},
error: function() {
alert('오류가 발생했습니다.');
}
});
}
function confirm_error() {
/* PHP 파일로부터 받은 응답을 처리하는 코드*/
var password = document.getElementById("password").value;
var password_confirm = document.getElementById("password_confirm").value;
var ID_confirm = duplicate_message;
// 특정 조건 확인
if (password === "" | password_confirm === ""){
$('#password_confirm_error').html("패스워드를 입력해주세요")
}
else {
if (password === password_confirm) {
$('#password_confirm_error').html("패스워드가 일치합니다.")
if(duplicate_message==="사용 가능한 ID입니다."){
return true;
}
else {
console.log(ID_confirm);
$('#confirm_error').html("ID를 다시 확인해 주세요.");
return false;
}
} else {
// 조건 미충족 시 페이지 이동 중지
$('#password_confirm_error').html("패스워드가 일치하지 않습니다.");
return false;
}
}
}
</script>
<style>
/* 스타일링을 위한 CSS 코드 */
body {
font-family: Arial, sans-serif;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 400px;
height: auto;
border: 1px solid #ccc;
background-color: #f4f4f4;
padding: 20px;
}
h2 {
text-align: center;
font-size: 24px;
margin-bottom: 20px;
}
input[type="text"]:focus,
input[type="password"]:focus {
/* 포커스 시 기본값 숨김 */
background-color: white;
}
.form-group {
margin-bottom: 20px;
text-align: center;
}
.input-row {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.input-label {
font-size: 18px;
margin-right: 10px;
}
input[type="text"],
input[type="password"] {
flex: 1;
padding: 10px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px;
}
input[type="text"]:focus,
input[type="password"]:focus {
/* 포커스 시 기본값 숨김 */
background-color: white;
}
input[type="submit"] {
width: 100%;
padding: 10px;
background-color: #4CAF50;
color: white;
border: none;
cursor: pointer;
font-size: 18px;
}
.register-link {
text-align: center;
margin-top: 10px;
font-size: 16px;
color: #888;
}
.register-link a {
text-decoration: none;
color: #888;
}
.message {
margin-top: 10px;
font-size: 14px;
color: #888;
}
.error-message {
margin-top: 10px;
font-size: 14px;
color: red;
}
.custom-button {
padding: 10px 20px;
font-size: 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<h2>🏃Join US🏃</h2>
<form action="join.php" method="post" onsubmit="return confirm_error()">
<form action="check_duplicate.php" method="post">
<div class="form-group">
<!--ID 중복체크-->
<div class="input-row">
<label for="email" class="input-label">ID:</label>
<input type="text" id="email" name="email" required
onfocus="clearDefaultValue(this)" value="example@abc.com">
<button type="button" onclick="id_duplication()" class="custom-button">ID 중복 확인</button>
</div>
<div class="error-message"><p id="duplicate_message"></p></div>
<!--회원가입-->
<div class="form-group">
<div class="input-row">
<label for="password" class="input-label">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<div class="error-message"></div>
<div class="input-row">
<label for="password_confirm" class="input-label">Password Confirm:</label>
<input type="password" id="password_confirm" name="password_confirm" required>
</div>
<div class="error-message"><p id="password_confirm_error"></p></div>
<div class="error-message"><p id="confirm_error"></p></div>
</div>
<input type="submit" onclick="confirm_error()" value="회원가입" name="join">
</form>
</form>
</div><p></p></div>
</body>
</html>
check_duplicate.php
이메일의 유효값을 검사하는 기능을 분리했다.
이메일 형식을 검사하며, 중복을 검사한다.
<?php
include "db_conn.php";
$email_pattern = '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'];
// 중복 확인
$sql = "SELECT email FROM users WHERE email='$email'";
$result = $conn->query($sql);
if(preg_match($email_pattern, $email)){
if ($email==="example@abc.com"){
echo "예시 이메일은 사용하실 수 없습니다.<br>";
}
else if (mysqli_num_rows($result)) {
echo "중복된 ID입니다.<br>";
} else {
echo "사용 가능한 ID입니다.<br>";
$id_confirm = true;
}
}
else {
echo "유효하지 않은 이메일 주소입니다.";
}
}
?>
join.php
앞에 이메일 유혀성검사가 끝나고 패스워드 확인까지 마치면, 가입이 완료된다.
include "db_conn.php";
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$password = $_POST['password'];
$password_confirm = $_POST['password_confirm'];
$email = $_POST['email'];
$name = $_POST['name'];
if($password === $password_confirm){
$sql = "INSERT INTO users (email, password, username) VALUES ('$email', '$password', '$name')";
$result = $conn->query($sql);
echo "회원가입 되었습니다! <br>";
echo "반갑습니다!".$email." 회원님";
}
else{
echo "패스워드가 일치하지 않습니다.";
}
}
<핵심코드 해설>
ID 중복 확인 아작스를 통해서 버튼을 눌렀을 때 페이지가 이동되지 않고 HTML → PHP → DB → HTML 통신을 해야함.
HTML에서 Script로 아작스를 통해 값을 받아 올 수 있도록 구성 → PHP 기능 분리를 통해 중복만 체크하는 PHP 생성 → DB 쿼리로 중복값체크 → 해당값을 아작스로 HTML 수신
Join_page.html (중복확인 함수 만들기)
function id_duplication() {
/* ID 중복 확인 버튼을 클릭했을 때 실행할 코드 */
/* PHP 파일로부터 받은 응답을 처리하는 코드*/
var email = document.getElementById("email").value;
$.ajax({
url: 'check_duplicate.php', // PHP 파일의 경로
type: 'POST',
dataType: 'html',
data: {email:email}, // PHP 파일로 전달할 데이터
success: function(response) {
$('#duplicate_message').html(response); // 결과를 표시할 요소에 HTML 삽입
duplicate_message = $('#duplicate_message').text();
receive();
},
error: function() {
alert('오류가 발생했습니다.');
}
});
}
버튼이 눌렀을때 email 값을 PHP로 보내 DB쿼리를 실행하고 다시 결과를 가져와서 HTML에 표현한다.
해당 ID가 중복된 ID인지, 사용가능한 ID인지 확인
Join_page.html(패스워드가 일치해도 ID가 유효하지 않으면 ID를 확인해야하는 함수 작성)
function receive(){
password = document.getElementById("password").value;
password_confirm = document.getElementById("password_confirm").value;
ID_confirm = duplicate_message;
}
function confirm_error() {
receive()
// 특정 조건 확인
if (password === "" | password_confirm === ""){
$('#password_confirm_error').html("패스워드를 입력해주세요")
}
else {
if (password === password_confirm) {
$('#password_confirm_error').html("패스워드가 일치합니다.")
if(duplicate_message==="사용 가능한 ID입니다."){
return true;
}
else {
console.log(ID_confirm);
$('#confirm_error').html("ID를 다시 확인해 주세요.");
return false;
}
} else {
// 조건 미충족 시 페이지 이동 중지
$('#password_confirm_error').html("패스워드가 일치하지 않습니다.");
return false;
}
}
}
패스워드가 동일해도 ID유효성을 검사하고 회원가입을 완료해야 하기 때문에, 고민하다가
먼저 유효성을 검사하고, 나오는 에러 메세지로 페이지를 이동하는 것으로 정했다.
사용자는 ID 중복검사를누르면 id_duplication()함수가 실행된다. id_duplication()실행시 recevie() 함수가 실행되게 되어
사용가능한 ID 인지, 중복된 ID인지 결과값을 저장하게된다.
이 값은 저장되고,
회원가입 버튼을 누르면 confirm_id()가 최종적으로 실행된다.
이 함수에서 최종적으로 패스워드와 패스워드 확인이 일치한지 검사하고, 두 비밀번호가 일치한다면 ID가 유효한지 검사한다.
*receive() 함수와 confirm_id()함수를 분리한 이유는 두 함수가 id_duplication()에서 실행되면 ID중복버튼을 누를때 패스워드도 동시에 검사하게 되는 사소한 버그가 있었다.
새로운아이디를 입력하면
페이지 가 이동되고 아이디를 출력하게 했다.
데이터베이스에도 가입한 회원의 정보가 잘 들어간것을 확인할 수있다.