풀스택 도전! PHP로 나만의 블로그 만들기
소개
안녕하세요! 웹스토리보이입니다. 이 강의는 디자인, 코딩, 및 개발을 한번에 경험할 수 있는 풀스택 도전 튜토리얼을 제공합니다. 개인이 디자인부터 코딩, 그리고 개발까지 진행하며 전체적인 웹사이트 구조와 흐름을 이해할 수 있도록 도와줍니다. 디자인 작업은 피그마를 활용하며, 코딩은 HTML5/CSS3를 사용하고, 개발은 PHP를 활용합니다. 이 프로세스를 통해 풀스택 개발에 도전하며 전체적인 웹사이트 제작 과정을 이해할 수 있습니다. 또한 PHP를 사용하여 게시판 및 로그인을 구현함으로써 웹사이트의 활용성을 높일 수 있습니다.
인덱스
디자인
- 1. 메인 디자인
- 1.1 카드 유형 디자인
- 2. 블로그 디자인
- 2.1 블로그 메인
- 2.2 블로그 카테고리 영역
- 2.3 블로그 뷰 영역
- 3. 게시판 디자인
- 3.1 게시판 메인
- 3.2 게시판 글쓰기
- 3.3 게시판 수정하기
- 3.4 게시판 보기
- 3.5 게시판 검색
- 4. 로그인 디자인
- 4.1 로그인
- 4.2 아이디 찾기
- 4.3 비밀번호 찾기
- 5. 회원가입 디자인
- 5.1 이용 약관
- 5.2 정보 입력
- 5.3 가입 완료
코딩
- 1. 기본 셋팅하기
- 1.1 vscode 셋팅하기
- 1.2. 호스팅 셋팅하기
- 1.3. 파일질라 셋팅하기
- 1.4. ftp-simple 셋팅하기
- 2. CSS 셋팅하기
- 2.1 style.css 만들기
- 2.2 fonts.css 만들기
- 2.3 vars.css 만들기
- 2.4 resets.css 만들기
- 2.5 commons.css 만들기
- 3. 기본 섹션 코딩하기
- 3.1 기본 레이아웃 잡기
- 3.2 헤더 영역 코딩하기
- 3.3 푸터 영역 코딩하기
- 4. 인트로 유형 코딩하기
- 4.1 메인 인트로 코딩하기
- 4.2 블로그 인트로 코딩하기
- 4.3 회원가입 인트로 코딩하기
- 5. 카드 유형 코딩하기
- 5.1 메인 카드 유형1 코딩하기
- 5.2 메인 카드 유형2 코딩하기
- 5.3 메인 카드 유형3 코딩하기
- 5.4 블로그 카드 유형1 코딩하기
- 5.5 블로그 카드 유형2 코딩하기
- 5.6 블로그 카드 유형3 코딩하기
- 5.7 카드 유형 반응형 코딩하기
- 6. 사이드 영역 코딩하기
- 6.1 인트로 영역 코딩하기
- 6.2 카테고리 코딩하기
- 6.3 인기 포스트 코딩하기
- 6.4 최신 댓글 코딩하기
- 6.5 게시판 코딩하기
- 6.6 메인 공지사항, 댓글 코딩하기
- 7. 블로그 뷰 페이지 코딩하기
- 7.1 블로그 뷰 영역 코딩하기
- 7.2 블로그 인덱스 영역 코딩하기
- 7.3 블로그 관련글 영역 코딩하기
- 7.4 블로그 댓글 영역 코딩하기
- 8. 게시판 페이지 코딩하기
- 8.1 게시판 코딩하기
- 8.2 게시판 글쓰기 코딩하기
- 8.3 게시판 글보기 코딩하기
- 9. 회원가입 페이지 코딩하기
- 9.1 기본 회원가입 코딩하기
- 9.2 회원가입 이용약관 코딩하기
- 9.3 회원가입 정보입력 코딩하기
- 9.4 회원가입 가입완료 코딩하기
- 10. 로그인 페이지 코딩하기
- 10.1 로그인 코딩하기
- 10.2 아이디 찾기 코딩하기
- 10.3 비밀번호 찾기 코딩하기
개발
- 1. 기본 셋팅하기
- 1.1 DB 연동하기
- 1.2 MyAdmin 접속하기
- 1.3 회원 테이블 만들기
- 1.4 include 사용하기
- 2. 회원가입 작업하기
- 1.1 약식 회원가입 작업하기
- 1.2 회원가입 이용약관 작업하기
- 1.3 회원가입 정보입력 작업하기
- 1.4 회원가입 가입완료 작업하기
1. 기본 셋팅하기
1.1 약식 회원가입 작업하기
아직 우리는 개발에 대해서 아무것도 모릅니다. 하지만 어렵지 않습니다. 저장된 데이터를 불러오고 데이티를 잘 저장하면 됩니다. 오히려 코딩보다 쉬울 수 있습니다. 데이터 전달만 깔끔하게 하면 됩니다. 그럼 시작해보겠습니다.🤩
우선 회원가입을 해보겠습니다. 이번 회원가입은 데이터를 저장 출력하는 방법을 배우기 위해 약식으로 작업한 것입니다. 코딩은 이미 다 해놨으니 소스만 복사해서 쓰시면 됩니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="디자인, 코딩, 개발을 이용하여 나만의 블로그 사이트를 만드는 강의입니다." />
<meta name="keyword" content="포트폴리오, PHP, 디자인, 풀스택, 코딩, 블로그, 웹표준, 피그마, Figma, 웹스토리보이" />
<title>풀스택 도전! PHP로 나만의 블로그 만들기 🤨</title>
<?php include "../include/link.php" ?>
<!-- //link -->
</head>
<body>
<?php include "../include/skip.php" ?>
<!-- //skip -->
<?php include "../include/header.php" ?>
<!-- //header -->
<main id="main" role="main">
<div class="container">
<section class="intro__wrap joinStyle borderBomStyle">
<div class="intro__inner">
<div class="intro__img"></div>
<div class="intro__text">
안녕하세요! <em>회원가입</em> 정보 입력 페이지입니다.
</div>
</div>
</section>
<!-- //intro__inner -->
<section class="join__inner">
<h2>회원 가입</h2>
<div class="join__basic">
<form action="joinSave.php" name="joinSave" method="post">
<fieldset>
<legend class="blind">회원가입 영역</legend>
<div>
<label for="youID" class="required">아이디</label>
<input type="text" id="youID" name="youID" placeholder="아이디을 적어주세요!"
class="input__style">
</div>
<div>
<label for="youName" class="required">이름</label>
<input type="text" id="youName" name="youName" placeholder="이름을 적어주세요!"
class="input__style">
</div>
<div>
<label for="youEmail" class="required">이메일</label>
<input type="email" id="youEmail" name="youEmail" placeholder="이메일을 적어주세요!"
class="input__style">
</div>
<div>
<label for="youPass" class="required">비밀번호</label>
<input type="password" id="youPass" name="youPass" placeholder="비밀번호를 적어주세요!"
autocomplete="off" class="input__style">
</div>
<div>
<label for="youPassC" class="required">비밀번호 확인</label>
<input type="password" id="youPassC" name="youPassC" placeholder="다시 한번 비밀번호를 적어주세요!"
autocomplete="off" class="input__style">
</div>
<div class="center">
<button type="submit" class="btn__style">회원가입</button>
</div>
</fieldset>
</form>
</div>
</section>
<!-- //join__inner -->
</div>
</main>
<!-- //main -->
<?php include "../include/footer.php" ?>
<!-- //footer -->
</body>
</html>
코드는 퍼블리싱 한 소스랑 차이가 없습니다.
단지 버튼을 누르면 post
방식으로 joinSave.php
페이지로 넘어갑니다.
이 부분이 조금 다릅니다.
PHP에서 POST 방식과 GET 방식은 웹 애플리케이션에서 서버로 데이터를 전송하는 두 가지 주요 방법입니다. 이 두 방식은 HTTP 프로토콜을 사용하여 데이터를 전송하며, 각각의 특징과 사용 용도가 있습니다.
-- GET 방식 --
- 데이터 전송 방법: URL의 쿼리 문자열(query string)을 통해 데이터를 전송합니다.
- 가시성: 전송되는 데이터가 URL에 노출되므로 보안에 취약합니다.
- 데이터 길이 제한: 브라우저 및 서버에 따라 전송 가능한 데이터의 길이에 제한이 있을 수 있습니다.
- 캐싱 가능: 동일한 요청이 반복되면 브라우저에서 결과를 캐시할 수 있습니다.
- 사용 예시: 검색어, 페이지 번호 등의 매개변수 전달에 주로 사용됩니다.
-- POST 방식 --
- 데이터 전송 방법: HTTP 요청 본문(body)에 데이터를 포함하여 전송합니다.
- 가시성: 데이터가 URL에 노출되지 않아 GET 방식에 비해 보안적입니다.
- 데이터 길이 제한: 일반적으로 GET 방식보다 더 많은 데이터를 전송할 수 있으며, 길이 제한은 설정에 따라 다를 수 있습니다.
- 캐싱 불가능: POST 요청은 기본적으로 캐시되지 않습니다.
- 사용 예시: 로그인 정보, 폼 데이터, 파일 업로드 등에 주로 사용됩니다.
데이터를 받은 joinSave.php
는 다음과 같이 코딩합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="디자인, 코딩, 개발을 이용하여 나만의 블로그 사이트를 만드는 강의입니다." />
<meta name="keyword" content="포트폴리오, PHP, 디자인, 풀스택, 코딩, 블로그, 웹표준, 피그마, Figma, 웹스토리보이" />
<title>풀스택 도전! PHP로 나만의 블로그 만들기 🤨</title>
<?php include "../include/link.php" ?>
<!-- //link -->
</head>
<body>
<?php include "../include/skip.php" ?>
<!-- //skip -->
<?php include "../include/header.php" ?>
<!-- //header -->
<main id="main" role="main">
<div class="container">
<section class="intro__wrap joinStyle borderBomStyle">
<div class="intro__inner">
<div class="intro__img"></div>
<div class="intro__text">
축하합니다. <em>회원가입</em>이 완료되었습니다.
</div>
</div>
</section>
<!-- //intro__inner -->
<section class="join__inner">
<?php
include "../connect/connect.php";
$youID = $_POST['youID'];
$youEmail = $_POST['youEmail'];
$youName = $_POST['youName'];
$youPass = $_POST['youPass'];
$youPassC = $_POST['youPassC'];
$regTime = time();
// echo $youID $youEmail, $youName, $youPass, $youPassC, $regTime;
// 데이터 넣기
$sql = "INSERT INTO member(youID, youEmail, youName, youPass, regTime) VALUES('$youID', '$youEmail', '$youName', '$youPass', '$regTime')";
$result = $connect -> query($sql);
// 데이터 가져오기
$viewSql = "SELECT * FROM member";
$viewResult = $connect -> query($viewSql);
if($viewResult){
$count = $viewResult -> num_rows;
if($count > 0){
for($i=0; $i<$count; $i++){
$info = $viewResult -> fetch_array(MYSQLI_ASSOC);
echo "<ul>";
echo "<li> 아이디 : ".$info['youID']."</li>";
echo "<li> 이메일 : ".$info['youEmail']."</li>";
echo "<li> 이름 : ".$info['youName']."</li>";
echo "<li> 패스워드 : ".$info['youPass']."</li>";
echo "<li> 시간 : ".$info['regTime']."</li>";
echo "</ul>";
}
}
}
?>
</section>
</div>
</main>
<!-- //main -->
<?php include "../include/footer.php" ?>
<!-- //footer -->
</body>
</html>
MyAdmin에도 데이터가 들어오는 것을 확인 할 수 있습니다.
1.2 회원가입 이용약관 작업하기
이번에는 약식이 아닌 정식으로 회원가입을 만들어보겠습니다. 우선 이용약관 체크부터 확인해 보겠습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="디자인, 코딩, 개발을 이용하여 나만의 블로그 사이트를 만드는 강의입니다." />
<meta name="keyword" content="포트폴리오, PHP, 디자인, 풀스택, 코딩, 블로그, 웹표준, 피그마, Figma, 웹스토리보이" />
<title>풀스택 도전! PHP로 나만의 블로그 만들기 🤨</title>
<?php include "../include/link.php" ?>
<!-- //link -->
</head>
<body>
<?php include "../include/skip.php" ?>
<!-- //skip -->
<?php include "../include/header.php" ?>
<!-- //header -->
<main id="main" role="main">
<div class="container">
<section class="intro__wrap joinStyle borderBomStyle">
<div class="intro__inner">
<div class="intro__img"></div>
<div class="intro__text">
안녕하세요! <em>회원가입</em> 정보 입력 페이지입니다.
</div>
</div>
</section>
<!-- //intro__inner -->
<section class="join__inner">
<h2>이용약관</h2>
<div class="join__index">
<ul>
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
<div class="join__agree">
<div class="agree__box">
<h3 class="blind">웹쓰 블로그 이용약관</h3>
<div class="scroll scroll__style">1. 서론
1.1 이 이용약관은 [블로그 이름] ("블로그" 또는 "저희")를 이용하는 모든 사용자(이하 "사용자" 또는 "회원")에게 적용됩니다. 이용약관을 읽고 이해하신
후, 본 블로그를 이용하시기 전에 본 이용약관을 주의 깊게 살펴보시기를 권장합니다.
2. 이용자 권리와 책임
2.1 회원은 본 블로그를 사용함으로써 다음을 동의합니다:
2.1.1 다른 회원의 개인 정보를 존중하며 개인 정보 보호 정책을 준수합니다.
2.1.2 불법 콘텐츠의 게시, 공유, 또는 홍보를 하지 않으며 타인의 저작권 및 상표권을 존중합니다.
2.1.3 사용자들 간의 존중과 상호 작용을 촉진하기 위해 다른 회원에 대한 비방, 괴롭힘, 혐오 발언 등을 허용하지 않습니다.
3. 콘텐츠 관리
3.1 블로그 관리자는 회원이 게시한 콘텐츠를 심사하고 필요한 경우 수정, 삭제 또는 거부할 권리가 있습니다.
3.2 회원은 자신의 콘텐츠가 법률, 규정 또는 이용약관을 위반하지 않도록 주의하여야 합니다.
4. 저작권
4.1 회원이 게시한 콘텐츠의 권리는 해당 회원에게 속하며, 블로그는 회원의 콘텐츠를 상업적으로 이용하지 않습니다.
5. 책임 제한
5.1 블로그는 회원 간의 상호 작용 및 제3자 웹사이트나 서비스와의 연결에 대한 책임을 지지 않습니다.
5.2 블로그는 시스템 장애 또는 서비스 일시 중단으로 인한 손해에 대한 책임을 부인합니다.
6. 이용약관 변경
6.1 블로그는 언제든 이용약관을 변경하거나 수정할 권리를 보유하며, 변경된 약관은 블로그 내에서 공지됩니다.
7. 종료
7.1 회원은 언제든지 본 블로그 이용을 중단할 수 있으며, 블로그 또한 회원에 대한 액세스를 종료할 권리를 보유합니다.
8. 연락처 정보
8.1 본 블로그와 관련된 문의 사항 또는 불만 사항은 다음 연락처를 통해 문의할 수 있습니다:
</div>
<div class="check">
<label for="agreeCheck1">
블로그 이용약관에 동의합니다.
<input type="checkbox" name="agreeCheck1" id="agreeCheck1">
<span class="indicator"></span>
</label>
</div>
</div>
<div class="agree__box">
<h3 class="blind">웹쓰 블로그 개인정보취급방침</h3>
<div class="scroll scroll__style">1. 개인 정보 수집
1.1 본 블로그는 회원 가입 및 콘텐츠 작성을 위해 필요한 개인 정보를 수집할 수 있습니다. 수집되는 정보는 다음과 같을 수 있습니다:
- 이름, 이메일 주소, 프로필 사진, 기타 선택적 정보
1.2 개인 정보는 회원의 동의 하에 수집되며, 회원은 언제든지 개인 정보를 제공하지 않을 권리가 있습니다. 그러나 일부 정보는 블로그를 이용하기 위해 필요할 수
있습니다.
2. 개인 정보 사용
2.1 블로그는 수집한 개인 정보를 다음 목적으로 사용할 수 있습니다:
- 회원 가입 및 로그인 관리, 콘텐츠 작성 및 수정, 연락과 응답, 블로그 서비스의 향상, 법적 요구 사항 준수
3. 개인 정보 보호
3.1 블로그는 회원의 개인 정보를 안전하게 보호하기 위해 적절한 보안 조치를 취하며, 무단 액세스, 유출, 변경 또는 파괴를 방지하기 위해 최선을 다합니다.
4. 개인 정보 공유
4.1 블로그는 회원의 개인 정보를 본 방침에 명시된 목적 외에는 공유하지 않으며, 법적 요구 사항이나 다른 합법적인 사유에 따라 정보를 공유할 수 있습니다.
5. 쿠키와 추적 기술
5.1 블로그는 쿠키와 유사한 기술을 사용하여 사용자의 활동을 추적하고 분석하는 목적으로 정보를 수집할 수 있습니다. 이 정보는 사용자 경험을 향상시키기 위해
사용됩니다.
6. 개인 정보 열람 및 수정
6.1 회원은 언제든지 자신의 개인 정보를 열람하고 수정할 권리가 있습니다. 개인 정보 열람 및 수정은 회원의 프로필 설정을 통해 가능합니다.
7. 개인 정보 보유 기간
7.1 블로그는 회원의 개인 정보를 더 이상 필요하지 않은 경우에만 보관하며, 법률적인 의무 또는 다른 합법적인 이유로 인해 정보를 보관할 수 있습니다.
8. 연락처 정보
8.1 본 블로그와 관련된 개인 정보 취급 방침과 관련된 문의 사항은 다음 연락처를 통해 문의할 수 있습니다:
</div>
<div class="check">
<label for="agreeCheck2">
블로그 개인정보 수집 및 이용에 동의합니다.
<input type="checkbox" name="agreeCheck2" id="agreeCheck2">
<span class="indicator"></span>
</label>
</div>
</div>
<div class="agree__btn">
<a href="#" id="agreeButton" class="btn__style">동의하기</a>
</div>
</div>
</section>
<!-- //join__inner -->
</div>
</main>
<!-- //main -->
<?php include "../include/footer.php" ?>
<!-- //footer -->
</body>
</html>
스크립트는 제이쿼리 또는 자바스크립트를 사용할 수 있습니다. php 자체가 옛날 언어이기 때문에 제이쿼리를 써서 작업하겠습니다.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$("#agreeButton").on("click", function(e) {
e.preventDefault();
const agreeCheck1 = $("#agreeCheck1");
const agreeCheck2 = $("#agreeCheck2");
if (agreeCheck1.prop("checked") && agreeCheck2.prop("checked")) {
window.location.href = "joinInsert.php";
} else {
alert("이용약관과 개인정보 수집 및 이용에 동의해야 합니다.");
}
});
// document.getElementById("agreeButton").addEventListener("click", (e) => {
// e.preventDefault();
// const agreeCheck1 = document.getElementById("agreeCheck1");
// const agreeCheck2 = document.getElementById("agreeCheck2");
// if (agreeCheck1.checked && agreeCheck2.checked) {
// window.location.href = "joinInsert.php";
// } else {
// alert("이용약관과 개인정보 수집 및 이용에 동의해야 합니다.");
// }
// });
</script>
1.3 회원가입 정보입력 작업하기
이용약관을 통과하면 정보입력을 하겠습니다. 정보입력을 할 때에는 Ajax라는 기술을 사용하겠습니다.
AJAX(Asynchronous JavaScript and XML)는 웹 페이지에서 비동기적으로 서버와 통신하는 기술을 말합니다. 이를 통해 페이지 전체를 새로 고치지 않고도 서버와 데이터를 교환하고, 동적으로 페이지의 일부를 업데이트할 수 있습니다. AJAX는 JavaScript, HTML, CSS 및 XMLHttpRequest 객체 등을 사용하여 구현됩니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="디자인, 코딩, 개발을 이용하여 나만의 블로그 사이트를 만드는 강의입니다." />
<meta name="keyword" content="포트폴리오, PHP, 디자인, 풀스택, 코딩, 블로그, 웹표준, 피그마, Figma, 웹스토리보이" />
<title>풀스택 도전! PHP로 나만의 블로그 만들기 🤨</title>
<?php include "../include/link.php" ?>
<!-- //link -->
</head>
<body>
<?php include "../include/skip.php" ?>
<!-- //skip -->
<?php include "../include/header.php" ?>
<!-- //header -->
<main id="main" role="main">
<div class="container">
<section class="intro__wrap joinStyle borderBomStyle">
<div class="intro__inner">
<div class="intro__img"></div>
<div class="intro__text">
안녕하세요! <em>회원가입</em> 정보 입력 페이지입니다.
</div>
</div>
</section>
<!-- //intro__inner -->
<section class="join__inner">
<h2>정보 입력</h2>
<div class="join__index">
<ul>
<li>1</li>
<li class="active">2</li>
<li>3</li>
</ul>
</div>
<div class="join__insert">
<form action="joinResult.php" name="joinResult" method="post" onsubmit="return joinChecks();">
<fieldset>
<legend class="blind">회원가입 영역</legend>
<div>
<label for="youID" class="required">아이디</label>
<div class="check">
<input type="text" id="youID" name="youID" placeholder="아이디을 적어주세요!"
class="input__style">
<div class="btn" onclick="idChecking()">아이디 중복 검사</div>
</div>
<p class="msg" id="youIDComment"></p>
</div>
<div>
<label for="youName" class="required">이름</label>
<input type="text" id="youName" name="youName" placeholder="이름을 적어주세요!"
class="input__style">
<p class="msg" id="youNameComment"></p>
</div>
<div>
<label for="youEmail" class="required">이메일</label>
<div class="check">
<input type="email" id="youEmail" name="youEmail" placeholder="이메일을 적어주세요!"
class="input__style">
<div class="btn" onclick="emailChecking()">이메일 중복 검사</div>
</div>
<p class="msg" id="youEmailComment"></p>
</div>
<div>
<label for="youPass" class="required">비밀번호</label>
<input type="text" id="youPass" name="youPass" placeholder="비밀번호를 적어주세요!"
autocomplete="off" class="input__style">
<p class="msg" id="youPassComment"></p>
</div>
<div>
<label for="youPassC" class="required">비밀번호 확인</label>
<input type="text" id="youPassC" name="youPassC" placeholder="다시 한번 비밀번호를 적어주세요!"
autocomplete="off" class="input__style">
<p class="msg" id="youPassCComment"></p>
</div>
<div>
<label for="youAddress1">주소</label>
<div class="check">
<input type="text" id="youAddress1" name="youAddress1" placeholder="우편번호"
class="input__style">
<div class="btn" id="addressCheck">주소 찾기</div>
</div>
<label for="youAddress2" class="required blind">주소</label>
<input type="text" id="youAddress2" name="youAddress2" placeholder="주소"
class="input__style">
<label for="youAddress3" class="required blind">상세 주소</label>
<input type="text" id="youAddress3" name="youAddress3" placeholder="상세 주소"
class="input__style">
<p class="msg" id="youAddressComment"></p>
</div>
<div>
<label for="youPhone">연락처</label>
<input type="text" id="youPhone" name="youPhone" placeholder="연락처는 하이픈 없이 숫자만 적어주세요!"
class="input__style">
<p class="msg" id="youPhoneComment"></p>
</div>
<div class="center">
<button type="submit" id="submitBtn" class="btn__style">회원가입 완료</button>
</div>
</fieldset>
</form>
</div>
</section>
<!-- //join__inner -->
</div>
</main>
<!-- //main -->
<?php include "../include/footer.php" ?>
<!-- //footer -->
<div id="layer">
<img src="//t1.daumcdn.net/postcode/resource/images/close.png" id="btnCloseLayer" alt="닫기 버튼">
</div>
</body>
</html>
jQuery를 사용하여 폼 데이터의 유효성을 검사하고, AJAX를 통해 아이디와 이메일의 중복 여부를 확인한 후 회원 가입을 수행하는 코드입니다. 자세한 사항은 영상을 참고해주세요!
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
let isIdCheck = false;
let isEmailCheck = false;
function idChecking(){
let youID = $("#youID").val();
if (youID == null || youID == ''){
$("#youIDComment").text("➟ 아이디를 입력해주세요!");
} else {
// 아이디 유효성 검사
let getyouID = RegExp(/^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]{4,20}$/);
if(!getyouID.test($("#youID").val())){
$("#youIDComment").text("➟ 아이디는 영어와 숫자를 포함하여 4~20글자 이내로 작성이 가능합니다.");
$("#youID").val('')
$("#youID").focus();
return false;
}
$.ajax({
type: "POST",
url: "joinCheck.php",
data: {"youID": youID, "type": "isIdCheck"},
dataType: "json",
success: function(data){
if(data.result == "good"){
$("#youIDComment").text("➟ 사용 가능한 아이디입니다.");
isIdCheck = true;
} else {
$("#youIDComment").text("➟ 이미 존재하는 아이디입니다.");
isIdCheck = false;
}
}
})
}
}
function emailChecking(){
let youEmail = $("#youEmail").val();
if (youEmail == null || youEmail == ''){
$("#youEmailComment").text("➟ 이메일을 입력해주세요!");
} else {
// 이메일 유효성 검사
let getYouEmail = RegExp(/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([\-.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i);
if(!getYouEmail.test($("#youEmail").val())){
$("#youEmailComment").text("➟ 올바른 이메일 주소를 입력해주세요");
$("#youEmail").val('')
$("#youEmail").focus();
return false;
}
$.ajax({
type: "POST",
url: "joinCheck.php",
data: {"youEmail": youEmail, "type": "isEmailCheck"},
dataType: "json",
success: function(data){
if(data.result == "good"){
$("#youEmailComment").text("➟ 사용 가능한 이메일입니다.");
isEmailCheck = true;
} else {
$("#youEmailComment").text("➟ 이미 존재하는 이메일입니다.");
isEmailCheck = false;
}
}
})
}
}
function joinChecks(){
// 이름 유효성 검사
if( $("#youName").val() == '' ){
$("#youNameComment").text("➟ 이름을 작성해주세요!");
$("#youName").focus();
return false;
} else {
let getYouName = RegExp(/^[가-힣]{3,5}$/);
if(!getYouName.test($("#youName").val())){
$("#youNameComment").text("➟ 이름은 한글(3~5글자)만 사용할 수 있습니다.");
$("#youName").val('');
$("#youName").focus();
return false;
}
}
// 비밀번호 유효성 검사
if($("#youPass").val() == ''){
$("#youPassComment").text("➟ 비밀번호를 입력해주세요!");
$("#youPass").focus();
return false;
} else {
let getYouPass = $("#youPass").val();
let getYouPassNum = getYouPass.search(/[0-9]/g);
let getYouPassEng = getYouPass.search(/[a-z]/ig);
let getYouPassSpe = getYouPass.search(/[`~!@@#$%^&*|₩₩₩'₩";:₩/?]/gi);
if(getYouPass.length < 8 || getYouPass.length > 20){
$("#youPassComment").text("➟ 8자리 ~ 20자리 이내로 입력해주세요");
return false;
} else if (getYouPass.search(/\s/) != -1){
$("#youPassComment").text("➟ 비밀번호는 공백없이 입력해주세요!");
return false;
} else if (getYouPassNum < 0 || getYouPassEng < 0 || getYouPassSpe < 0 ){
$("#youPassComment").text("➟ 영문, 숫자, 특수문자를 혼합하여 입력해주세요!");
return false;
}
// else {
// $("#youPassComment").text("➟ 사용가능합니다");
// }
}
// 비밀번호 확인 유효성 검사
if($("#youPassC").val() == ''){
$("#youPassCComment").text("➟ 확인 비밀번호를 입력해주세요!");
$("#youPassC").focus();
return false;
}
// 비밀번호 동일한지 체크
if($("#youPass").val() !== $("#youPassC").val()){
$("#youPassCComment").text("➟ 비밀번호가 일치하지 않습니다.");
$("#youPass").focus();
return false;
}
// else {
// $("#youPassCComment").text("➟ 비밀번호가 일치합니다.");
// }
// 연락처 유효성 검사
let getYouPhone = RegExp(/^[0-9]{10,11}$/); // 10자리 또는 11자리 숫자);
if(!getYouPhone.test($("#youPhone").val())){
$("#youPhoneComment").text("➟ 휴대폰 번호가 정확하지 않습니다.(하이픈 없이 숫자만 적어주세요!)");
$("#youPhone").val('');
$("#youPhone").focus();
}
// 중복 확인이 이루어졌는지 검사
if (!isIdCheck || !isEmailCheck) {
alert("중복 확인 먼저 진행해주세요.");
return false;
} else {
alert("회원가입이 성공적으로 이루어졌습니다.");
}
}
</script>
우편번호 데이터 API를 이용하여 작업하였습니다.
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
// 우편번호 찾기 화면을 넣을 element
const layer = document.querySelector("#layer");
const searchIcon = document.querySelector("#addressCheck");
const layerCloseBtn = document.querySelector("#btnCloseLayer");
searchIcon.addEventListener('click', searchBtnClick);
layerCloseBtn.addEventListener('click', closeDaumPostcode);
function closeDaumPostcode() {
// iframe을 넣은 element를 안보이게 한다.
layer.style.display = 'none';
}
const themeObj = {
//bgColor: "", //바탕 배경색
searchBgColor: "#0B65C8", //검색창 배경색
//contentBgColor: "", //본문 배경색(검색결과,결과없음,첫화면,검색서제스트)
//pageBgColor: "", //페이지 배경색
//textColor: "", //기본 글자색
queryTextColor: "#FFFFFF" //검색창 글자색
//postcodeTextColor: "", //우편번호 글자색
//emphTextColor: "", //강조 글자색
//outlineColor: "", //테두리
};
function searchBtnClick() {
new daum.Postcode({
theme: themeObj,
oncomplete: function (data) {
// 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.
// 각 주소의 노출 규칙에 따라 주소를 조합한다.
// 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
let addr = ''; // 주소 변수
let extraAddr = ''; // 참고항목 변수
//사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
addr = data.roadAddress;
} else { // 사용자가 지번 주소를 선택했을 경우(J)
addr = data.jibunAddress;
}
document.querySelector('#youAddress1').value = data.zonecode; // 우편번호
document.querySelector("#youAddress2").value = addr; // 주소
document.querySelector("#youAddress3").focus();
// iframe을 넣은 element를 안보이게 한다.
// (autoClose:false 기능을 이용한다면, 아래 코드를 제거해야 화면에서 사라지지 않는다.)
layer.style.display = 'none';
},
width: '100%',
height: '100%',
maxSuggestItems: 5
}).embed(layer);
// iframe을 넣은 element를 보이게 한다.
layer.style.display = 'block';
// iframe을 넣은 element의 위치를 화면의 가운데로 이동시킨다.
initLayerPosition();
}
// 브라우저의 크기 변경에 따라 레이어를 가운데로 이동시키고자 하실때에는
// resize이벤트나, orientationchange이벤트를 이용하여 값이 변경될때마다 아래 함수를 실행 시켜 주시거나,
// 직접 layer의 top,left값을 수정해 주시면 됩니다.
function initLayerPosition() {
const width = 500; //우편번호서비스가 들어갈 element의 width
const height = 500; //우편번호서비스가 들어갈 element의 height
const borderWidth = 5; //샘플에서 사용하는 border의 두께
// 위에서 선언한 값들을 실제 element에 넣는다.
layer.style.width = width + 'px';
layer.style.height = height + 'px';
layer.style.border = borderWidth + 'px solid';
// 실행되는 순간의 화면 너비와 높이 값을 가져와서 중앙에 뜰 수 있도록 위치를 계산한다.
layer.style.left = (((window.innerWidth || document.documentElement.clientWidth) - width) / 2 - borderWidth) + 'px';
layer.style.top = (((window.innerHeight || document.documentElement.clientHeight) - height) / 2 - borderWidth) + 'px';
}
</script>
<!-- // 주소찾기 -->
1.4 회원가입 가입완료 작업하기
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="디자인, 코딩, 개발을 이용하여 나만의 블로그 사이트를 만드는 강의입니다." />
<meta name="keyword" content="포트폴리오, PHP, 디자인, 풀스택, 코딩, 블로그, 웹표준, 피그마, Figma, 웹스토리보이" />
<title>풀스택 도전! PHP로 나만의 블로그 만들기 🤨</title>
<?php include "../include/link.php" ?>
<!-- //link -->
</head>
<body>
<?php include "../include/skip.php" ?>
<!-- //skip -->
<?php include "../include/header.php" ?>
<!-- //header -->
<main id="main" role="main">
<div class="container">
<section class="intro__wrap joinStyle borderBomStyle">
<div class="intro__inner">
<div class="intro__img"></div>
<div class="intro__text">
축하합니다. <em>회원가입</em>이 완료되었습니다.
</div>
</div>
</section>
<!-- //intro__inner -->
<section class="join__inner">
<h2>가입 완료</h2>
<div class="join__index">
<ul>
<li>1</li>
<li>2</li>
<li class="active">3</li>
</ul>
</div>
<div class="join__result">
<span class="span pumping" data-text="축하합니다."></span>
</div>
</section>
<!-- //join__inner -->
</div>
</main>
<!-- //main -->
<?php include "../include/footer.php" ?>
<!-- //footer -->
</body>
</html>
<?php
include "../connect/connect.php";
// 폼에서 POST로 전달된 데이터 받기
$youID = mysqli_real_escape_string($connect, $_POST['youID']);
$youName = mysqli_real_escape_string($connect, $_POST['youName']);
$youEmail = mysqli_real_escape_string($connect, $_POST['youEmail']);
$youPass = mysqli_real_escape_string($connect, $_POST['youPass']);
$youPhone = mysqli_real_escape_string($connect, $_POST['youPhone']);
$youAddress = mysqli_real_escape_string($connect, $_POST['youAddress1']."*".$_POST['youAddress2']."*".$_POST['youAddress3']);
$youRegTime = time();
// 비밀번호 해싱
$hashedPass = password_hash($youPass, PASSWORD_DEFAULT);
// SQL 쿼리 생성
$sql = "INSERT INTO members(youID, youName, youEmail, youPass, youPhone, youRegTime, youAddress) VALUES ('$youID', '$youName', '$youEmail', '$youPass', '$youPhone', '$youRegTime', '$youAddress')";
$connect -> query($sql);
// 결과 표시
if (!$result) {
die("쿼리 실행에 실패했습니다: " . $connect->error);
}
// 데이터베이스 연결 닫기
mysqli_close($connect);
?>
<script>
// 축하 애니메이션
const colors = ['#FC4F4F', '#FFBC80', '#FF9F45', '#F76E11']
const shapes = ['heart']
const randomIntBetween = (min, max) => {
return Math.floor(Math.random() * (max - min + 1) + min)
}
class Particle {
constructor({ x, y, rotation, shape, color, size, duration, parent }) {
this.x = x
this.y = y
this.parent = parent
this.rotation = rotation
this.shape = shape
this.color = color
this.size = size
this.duration = duration
this.children = document.createElement('div')
}
draw() {
this.children.style.setProperty('--x', this.x + 'px')
this.children.style.setProperty('--y', this.y + 'px')
this.children.style.setProperty('--r', this.rotation + 'deg')
this.children.style.setProperty('--c', this.color)
this.children.style.setProperty('--size', this.size + 'px')
this.children.style.setProperty('--d', this.duration + 'ms')
this.children.className = `shape ${this.shape}`
this.parent.append(this.children)
}
animate() {
this.draw()
const timer = setTimeout(() => {
this.parent.removeChild(this.children)
clearTimeout(timer)
}, this.duration)
}
}
function animateParticles({ total }) {
for (let i = 0; i < total; i++) {
const particle = new Particle({
x: randomIntBetween(-300, 300),
y: randomIntBetween(-100, -500),
rotation: randomIntBetween(-360 * 5, 360 * 5),
shape: shapes[randomIntBetween(0, shapes.length - 1)],
color: colors[randomIntBetween(0, colors.length - 1)],
size: randomIntBetween(4, 7),
duration: randomIntBetween(400, 800),
parent
})
particle.animate()
}
}
let intervalTimer = setInterval(() => {
animateParticles({ total: 8 })
}, 100)
const parent = document.querySelector('.span');
parent.addEventListener("touchstart", () => { }, false);
parent.addEventListener('click', e => {
if (intervalTimer) {
clearInterval(intervalTimer)
intervalTimer = null
parent.classList.remove('pumping')
}
animateParticles({ total: 40 })
})
</script>
데이터가 잘 들어온 것을 확인할 수 있습니다.
댓글