코드는 Morden PHP 라고 보기에는 좀 약할 수 있다. 하지만 참고하면 도움이 될 코드가 엄청 많다.
회원가입과 로그인, 최신 패스워드 권장 적용방식, 중복체크가 가능하고 방식은 Ajax 방식으로 처리한다.
jQuery, CSS 코드, PHP Class 함수는 안드로이드폰 로그인과의 연동부분까지 고려되어 있으니 입문 개발자에게는 훌륭한 샘플이 될 것이다.
메인 화면 Layout 구성은 초간단으로 기능 동작 중심이다. 회원가입과 로그인만 제대로 되는지 체크하는 용도라고 보면 된다.
== 회원가입 폼 === <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="form.css" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> $(document).ready(function(){ // 회원가입처리 $('#join-submit').click(function(e){ e.preventDefault(); var userNM = $("input[name='userNM']"); if( userNM.val() =='') { alert("성명을 입력하세요"); userNM.focus(); return false; }
var email = $("input[name='email']"); if(email.val() == ''){ alert('이메일을 입력하세요'); email.focus(); return false; } else { var emailRegex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/; if (!emailRegex.test(email.val())) { alert('이메일 주소가 유효하지 않습니다. ex)abc@gmail.com'); email.focus(); return false; } }
var mobileNO = $("input[name='mobileNO']"); if(mobileNO.val() ==''){ alert('휴대폰 번호를 입력하세요'); mobileNO.focus(); return false; } else if(!/^[0-9]{10,11}$/.test(mobileNO.val())){ alert("휴대폰 번호는 숫자만 10~11자리 입력하세요."); return false; } else if(!/^(01[016789]{1}|02|0[3-9]{1}[0-9]{1})([0-9]{3,4})([0-9]{4})$/.test(mobileNO.val())){ alert("유효하지 않은 전화번호 입니다."); return false; }
var password = $("input[name='Password']"); var repassword = $("input[name='rePassword']"); if(password.val() =='') { alert("비밀번호를 입력하세요!"); password.focus(); return false; } if(password.val().search(/\s/) != -1){ alert("비밀번호는 공백없이 입력해주세요."); return false; } if(!/^[a-zA-Z0-9!@#$%^&*()?_~]{8,20}$/.test(password.val())){ alert("비밀번호는 숫자, 영문, 특수문자(!@$%^&*?_~ 만 허용) 조합으로 8~20자리를 사용해야 합니다."); return false; } // 영문, 숫자, 특수문자 2종 이상 혼용 var chk=0; if(password.val().search(/[0-9]/g) != -1 ) chk ++; if(password.val().search(/[a-z]/ig) != -1 ) chk ++; if(password.val().search(/[!@#$%^&*()?_~]/g) != -1) chk ++; if(chk < 2){ alert("비밀번호는 숫자, 영문, 특수문자를 두가지이상 혼용하여야 합니다."); return false; } // email이 아닌 userID 인 경우에는 체크하면 유용. email은 특수 허용문자에서 걸러진다. /* if(password.val().search(userID.val())>-1){ alert("userID가 포함된 비밀번호는 사용할 수 없습니다."); return false; } */ if(repassword.val() =='') { alert("비밀번호를 다시 한번 더 입력하세요!"); repassword.focus(); return false; } if(password.val()!== repassword.val()){ alert('입력한 두 개의 비밀번호가 일치하지 않습니다'); return false; }
//var loginpath =$("#ajaxPath").attr('data-path'); $.ajax({ url: 'a.register.php', type: 'POST', data: { userNM:userNM.val(), userID:email.val(), password:password.val(), mobileNO:mobileNO.val() }, dataType: "json", // json, text success: function (response) { //alert(response); //text 로 하고 a.register.php 에서 print_r을 사용하면 넘어간 데이터를 확인 가능 if(response.result == 1){ alert('가입 완료'); location.replace('index.php'); // 화면 갱신 } else if(response.result == 0){ alert('이미 가입된 아이디입니다'); } else if(response.result == -2){ alert('입력 데이터를 확인하세요'); } else { //alert('등록중에 에러가 발생했습니다' + response); alert('등록중에 에러가 발생했습니다'); } }, error: function(jqXHR, textStatus, errorThrown){ alert("arjax error : " + textStatus + "\n" + errorThrown); } });
});
// userID(e-mail) 가입여부 검사 $("#checkid").click(function(e){ e.preventDefault(); var email = $("input[name='email']"); if(email.val() == ''){ alert('이메일을 입력하세요'); email.focus(); return false; } else { var emailRegex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/; if (!emailRegex.test(email.val())) { alert('이메일 주소가 유효하지 않습니다. ex)abc@gmail.com'); email.focus(); return false; } }
$.ajax({ url: 'a.joinChk.php', type: 'POST', data: {userID:email.val()}, dataType: "json", success: function (msg) { //alert(msg); // 확인하고 싶으면 dataType: "text" 로 변경한 후 확인 가능 if(msg.result == 1){ alert('사용 가능합니다'); } else if(msg.result == 0){ alert('이미 가입된 아이디입니다'); email.val(''); } }, error: function(jqXHR, textStatus, errorThrown){ alert("arjax error : " + textStatus + "\n" + errorThrown); } }); });
}); </script> </head> <body> <div class="container"> <h2>회원가입 Form 예제</h2> <form method="post" action="a.register.php"> <table> <tr> <td style='width:100px'>이름</td> <td><input type="text" size=37 name="userNM" value=""></td> </tr> <tr> <td>E-Mail</td> <td> <input type="text" size=25 name="email" value=""> <input type="button" id="checkid" value="중복체크"> </td> </tr> <tr> <td>휴대폰번호</td> <td><input type="text" size=37 name="mobileNO" value=""></td> </tr> <tr> <td>비밀번호</td> <td><input type="password" size=37 name="Password"></td> </tr> <tr> <td>비밀번호(확인)</td> <td><input type="password" size=37 name="rePassword"></td> </tr> <tr> <td colspan='2' align='center'> <input type="button" id="join-submit" value="회원가입"> </td> </tr> </table> </fom> </div> </body> </html>
|
=== 회원가입 a.register.php === <?php if (!isset($_SESSION)) { session_start(); }
// 파일을 직접 실행하면 동작되지 않도록 하기 위해서 if(isset($_POST) && $_SERVER['REQUEST_METHOD'] == "POST"){ @extract($_POST); // $_POST['loginID'] 라고 쓰지 않고, $loginID 라고 써도 인식되게 함 //echo '<pre>';print_r($_POST);echo '</pre>'; // 전송받은 배열을 확인하고 싶을 때 사용 if(isset($userID) && !empty($userID) && isset($password) && !empty($password)) { include_once 'dbController.php'; require_once 'loginClass.php'; $c = new LoginClass(); if ($c->isUserExisted($userID)==1) { echo '{"result":"0"}'; // echo json_encode(array('result' => '0')); 과 동일 } else { $mobileNO = preg_replace("/[^0-9]/", "", $mobileNO); //전화번호 숫자만 남기고 제거 // 회원 등록 $user = $c->storeUser($userID, $userNM, $password, $mobileNO); if ($user) {// 회원 등록 성공 $_SESSION['userID'] = $user['userID']; $_SESSION['admin'] = $user['admin']; echo json_encode(array('result' => '1')); } else { // 회원 등록 실패 echo json_encode(array('result' => '-1')); } } }else {// 입력받은 데이터에 문제가 있을 경우 echo json_encode(array('result' => '-2')); } } ?>
|
=== 로그인 폼 === <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="form.css" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> $(document).ready(function(){ $('#login-submit').click(function(e){ var userID = $("input[name='userID']"); if( userID.val() =='') { alert("아이디를 입력하세요"); userID.focus(); return false; }
var password = $("input[name='password']"); if(password.val() =='') { alert("비밀번호를 입력하세요!"); password.focus(); return false; } $.ajax({ url: 'a.loginChk.php', type: 'POST', data: {userID:userID.val(), password:password.val()}, dataType: "json", success: function (response) { if(response.result == 1){ //alert('로그인 성공'); location.href='index.php'; } else if(response.result == -2){ alert('입력한 값에 문제가 있습니다'); } else { alert('로그인 실패'); } }, error: function(jqXHR, textStatus, errorThrown){ alert("arjax error : " + textStatus + "\n" + errorThrown); } }); }); }); </script> </head> <body> <div class="container"> <h2>로그인 Form 예제</h2> <form method="post" action="a.loginChk.php"> <table> <tr> <td style="font-size:14px">로그인 ID</td> <td><input type="text" name="userID" value=""></td> </tr> <tr> <td style="font-size:14px">패스워드</td> <td><input type="password" name="password"></td> </tr> <tr> <td colspan='2' align=left> <input type="button" id="login-submit" value="로그인"> </td> </tr> <tr> <td colspan='2'><p>Don't have an account? <a href="joinForm.php">Sign up now</a>.</p></td> </tr> </table> </fom> </div> </body> </html>
|
=== 로그인 체크 === <?php // 파일을 직접 실행하는 비정상적 동작을 방지 하기 위한 목적 if(isset($_POST) && $_SERVER['REQUEST_METHOD'] == "POST"){ @extract($_POST); // $_POST['loginID'] 라고 쓰지 않고, $loginID 라고 써도 인식되게 함 if(isset($userID) && !empty($userID) && isset($password) && !empty($password)) { include_once 'dbController.php'; require_once 'loginClass.php'; $c = new LoginClass(); $user = $c->getUser($userID, $password); if ($user != false) { $_SESSION['userID'] = $user['userID']; $_SESSION['userNM'] = $user['userNM']; $_SESSION['admin'] = $user['admin']; echo json_encode(array('result' => '1')); } else { echo json_encode(array('result' => '0')); } }else {// 입력받은 데이터에 문제가 있을 경우 echo json_encode(array('result' => '-2')); } } else { // 비정상적인 접속인 경우 echo 0; // a.loginChk.php 파일을 직접 실행할 경우에는 화면에 0을 찍어준다. exit; } ?>
|
== 가입여부 체크 === <?php // 파일을 직접 실행하면 동작되지 않도록 하기 위해서 if(isset($_POST) && $_SERVER['REQUEST_METHOD'] == "POST"){ @extract($_POST); // $_POST['loginID'] 라고 쓰지 않고, $loginID 라고 써도 인식되게 함 // db 접속파일 include 및 정상 로그인 여부 체크하는 함수 실행후 결과 반환처리 하면 된다. include_once 'dbController.php'; require_once 'loginClass.php'; $d = new DBController(); $c = new LoginClass(); $rs = $c->isUserExisted($userID); if($rs == '0'){ echo '{"result":"1"}'; } else { echo '{"result":"0"}'; // echo json_encode(array('result' => '0')); 과 동일 } } ?>
|
주요코드는 위에 열거하였고 나머지 코드에 대해서는 첨부파일을 참조하면 된다.
첨부파일에는 SQL 테이블 구조까지 포함되어 있고, 100% 동작되는지 여부를 확인한 코드다.
login.zip
인터넷에 올려진 코드가 잘 동작하지 않는 것은 변수명을 살짝 바꾸거나, 한두개 핵심적인 것을 빼먹어서 그런 경우가 참 많다. 코드가 제대로 동작 안되는 것은 본문에 있는 내용과 어떤 부분이 약간 다른지 확인하면 해결될 문제인데, 일단 시도를 안해보는 거 같다. 첨부한 예제는 오래된 책에 나온 구닥다리 PHP 와는 비교되지 않는 좋은 샘플 예제다.
무조건 실행해서 결과가 OK 되는 걸 원하는 건 초보자로서 당연할 수 있다.
하지만 개념 이해를 위한 공부를 해야 내 것이 된다.
login.zip 파일과 login_2.zip 파일 내용을 비교하면서 뭐가 틀려서 안되었던 걸까 하고 이해를 해야 한다.
이해를 하기 위해서는 파일 비교하는 방법을 알아야 한다.
https://link2me.tistory.com/1327 에 AcroDiff.exe 라는 파일이 있다.
최근에 개발자들이 Visual Studio Code 를 선호하여 AcroEdit 라는 툴이 있는지 모를 수 있지만, 이 에디터에 포함된 AcroDiff.exe 파일은 파일의 내용 비교에는 최고의 툴이다.
이걸 이용해서 파일을 서로 비교해보면 어디가 달라져 있고, 무엇 때문에 질문을 했는지 이해가 될 것이다.
login_2.zip