본문 바로가기
테크노트/PHP

웹개발 - PHP 활용편 : 미니홈페이지 만들기

by 테크한스 2021. 11. 24.

그동안 몇편에 걸쳐서 PHP라는 개발언어의 기본을 알아보았습니다.

매일 문법만 공부하면 재미가 없고 지치겠죠?

자~ 이제는 웹개발을 위한 기초를 다루었고 이제 간단하게 로그인 가능한 미니홈페이지를 

만들어 보겠습니다.

 

지금부터 기술적으로 막히는 부분에 대해서는 걱정할 필요가 없습니다.

그때 그때 찾아서 알아가면서 적용하면 되니까요

 

모든 개발자의 시작은 "자기학습"입니다.

 

그러므로 모르는 부분이 나온다고 해서 기죽을 필요도 없고 답답해 할 필요도 없습니다.

그냥 열심히 해당내용을 찾아서 익히면 됩니다.

 

자~ 그럼 시작해 보겠습니다.

 

우선 시작은 잘 만들어진 샘플코드 부터 시작하는 것이 빠릅니다.

하나하나 자신이 찾아서 타이핑을 치며 배우는 것도 중요하지만 가성비를 맞춰서 코딩 실력을 키우려면 다양한 잘 만들어진 고수의 소스코드를 보면서 차용하면서 내것으로 만드는 것이 휠씬 빠른다는 것이 중요합니다.

 

이제부터 알아볼 로그인 미니 홈페이지는 아래의 사이트에서 오픈소스로 공유된 소스를 사용하였고요

다양한 오픈소스 PHP 미니프로젝트가 공개되어 있습니다. 

여러분이 만약 기획하고 있는 홈피가 있다면 이곳에서 아이디어를 얻을 수도 있답니다.

 

https://www.sourcecodester.com/

 

 

이제부터 보여질 로그인 미니 홈피는 일전에 소개드린 HTML프레임워크인 bootstrap을 이용해서 작성한 html을 기반으로 만들어져 있습니다.

이런 템플릿같은 html을 사용하지 않으면 웹디자이너님이 만들어 주신 (퍼블리싱 해주신) html 코드를 받아야 하거나 자신이 직접 수천백라인 html과 css를 만들어가야 하는 노력을 해야 겠죠. (언제 개발하냐?)

 

우리가 만들어보려는 index.php 상단에 선언되어 있는 

        <link rel="stylesheet" type="text/css" href="css/bootstrap.css"/>
 
를 보면 알수가 있는 것이죠. 그러니 여기 소스에서는 기본적인 html을 익히는 것과 함께 주로 php개발을 어떤식으로 태크와 함께 하는지를 계속 눈여겨 보면서 여러분도 타이핑으로 직접 치면서 감을 익히는게 목적입니다.
 
여기서 잠깐~
 
PHP 개발은 서버사이드 개발이라고 했다면 이 미니프로젝트는 분명 데이터베이스(Database)와 연동하여 만들어질텐데 라고 생각하신 분들이 계실겁니다. 맞습니다. 우리가 일전에 미리 설정해 놓은 마리아DB를 가지고 PHP를 개발할것입니다
 
그러므로 개발하기 전에 우리는 디비 스키마를 작성하여 해당 데이터베이스에 테이블을 생성해야 합니다.
우리가 흔히 말하는 DBA(Database Administrator)들이 이런 작업을 도와주거나 만들어주거나 할텐데, 개발자들도 어느정도의 디비 모델링 작업을 할줄 알아야 합니다.
 
그것이 코더(coder)가 아닌 개발자(프로그램)가 되는 것입니다.
 
그말은 즉슨 어떤 시스템을 만들려고 할때는 어떤 서비스나 시스템을 분석/설계해야 한다는 의미이고
여기에는 바로 1) 화면설계 와 2) 데이터설계 2가지로 작업이 진행되게 됩니다.
 
첫번째로 화면설계는 아래와 같이 첫화면을 만들어 보겠습니다.
 

웹개발 할때 첫번째로 화면설계를 해야하는 이유는 이 화면에 나와있는 데이터를 기반으로 데이터설계를 할 수 있기 때문입니다.  만약 이화면을 보고 뽑여 나와야 할 데이터가 안보이면 아직 초심자(?)인 것이죠

 

우선 이화면에서는 보이는 그대로 (^^) username 과 password 가 보이겠습니다.

 

화면설계시 화면이 한개는 아니겠죠? 하하

다른 화면도 확인해 볼까요?

여기에 해당되는 데이터가 모든 나와 있네요? 너무 쉽네요 ~

우선 보이는대로 보자면

- firstname

- lastname

- username

- password

를 기반으로 데이터 설계를 해봅니다.

 

테이블을 설계하는 스키마 스크립트는 표준 SQL 문장에 맞추어 디비벤더회사에서 그렇게 지원하여 만든 제품이므로 그것에 따르면 됩니다. 우리가 개발환경에서 구축한 마리아DB에서만 적용되는 스키마 스크립트는 아니라는 말이죠

 

CREATE TABLE `member` (
  `mem_id` int(11) NOT NULL,
  `firstname` varchar(50) NOT NULL,
  `lastname` varchar(50) NOT NULL,
  `username` varchar(30) NOT NULL,
  `password` varchar(12) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

여기는 이렇게 데이터 설계가 되어 있습니다. 

(우리가 설치한 개발환경 마리아DB character set 이 UTF로 설정되어 있어서 테이블도 CHARSET=latin1 보다는 CHARSET=utf8mb4 이 좋을 수도 있습니다.) 

 

여기서 자신의 생각대로 만들어도 됩니다.

 

예를 들어 username은 유져ID의 성격이 있는 unique한 데이터 이기에 이 키를 Primary Key로 잡고 만들어도 됩니다만

다른 의미로 여기서는 mem_id라는 sequence numbering을 통해(auto increment 적용하여 1씩 자동 증가) Primary Key로 잡고 만든 예입니다.

 

어떤 형태식으로 데이터 설계를 하든 이 테이블의 목적은 사용자관리 테이블인 것이죠

그래서 같은 이름은 로그인 미니 홈페이지 시스템이라고 해도 시스템 내부적으로 보면 이렇듯 각각의 사이트의 사정에 맞추어서 조금씩 달라져서 구성되어지곤 합니다. 쿨럭~

 

해당 되는 테이블을 create 하였다면 그것을 기반으로 몇가지를 set 해주어야 합니다.

ALTER TABLE `member`
  ADD PRIMARY KEY (`mem_id`);

이와같이 컬럼중에 Primary Key를 설정하고요

추가적으로 mem_id 라는 컬럼에 auto increment (row데이터가 인서트되면 자동 1증가) 옵션을 set 하도록 하겠습니다

ALTER TABLE `member`
  MODIFY `mem_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;COMMIT;

 

우리가 일전에 Database 마리아DB를 설치할 때 설치시에 root 계정의 패스워드를 미리 set 하도록 요구받았듯이 여기 설명하는 미니 홈페이지도 로그인이 가능한 것이기에, 미리 administrator (root,수퍼관리자 역할) 의 데이터를 한건 미리 등록할 필요가 있는 것입니다. 

 

그래서 마지막으로 해야주어야 할 데이터 작업은

INSERT INTO `member` (`mem_id`, `firstname`, `lastname`, `username`, `password`) VALUES
(1, 'Administrator', '', 'admin', 'admin');

이렇게 되면 우리가 이전에 설치한 디비관리툴(Dbeaver)에서 select 해보면 

이렇게 member 테이블의 어드민 데이터가 인서트되어 있다는 것을 확인해 보았습니다.

 

자~ 이제 데이터 설계와 구현 끝났습니다.

 

이제는 화면설계를 통해 개발 및 쿼리 작업을 통해 html과 php코드를 가지고 어떻게 전환하면 개발하는지 화면의 흐름을 보면 이해해 보겠습니다.

화면에서 보듯이 index.php에서 2가지 페이지로 이동합니다.

 

-index.php ---> login_query.php

              +--> registration.php

 

1) 로그인이 정상이면 로그인프로세스로 이동

2) 회원가입이 안되어 있으면 등록화면으로 이동

 

index.php 소스 내용중에 다음과 같이 해당 페이지들을 이동시킵니다. 

1) form 태그를 이용한 GET/POST 방식

2) href 태그를 이용한 방식

 

우선 form 태그는 "html기초편"에도 언급했듯이 당연히 <body></body> 태크 안에 존재할 것입니다.

<form action="login_query.php" method="POST">	
	<h4 class="text-success">Login here...</h4>
	<hr style="border-top:1px groovy #000;">
	<div class="form-group">
		<label>Username</label>
		<input type="text" class="form-control" name="username" />
	</div>
	<div class="form-group">
		<label>Password</label>
		<input type="password" class="form-control" name="password" />
	</div>
	<br />
	<div class="form-group">
		<button class="btn btn-primary form-control" name="login">Login</button>
	</div>
	<a href="registration.php">Registration</a>
</form>

<form> 태그는 POST 방식으로 input 태그에 있는 username과 password 데이터를 action=loing_query.php에 넘기는 형식으로 되어 있음을 확인할 수 있습니다.

 

( 관련 html 중 해당 태크 내용 확인)

<form action="login_query.php" method="POST"> 

<input type="text" class="form-control" name="username" />

<input type="password" class="form-control" name="password" />

 

등록 href 링크 부분은 단순하게 <a href~> A링크라고 부르겠습니다. A링크를 호출하여 해당 페이지 registration.php로 넘깁니다.

<a href="registration.php">Registration</a>

 

솔직히 여기까지 어려운게 있나요?  너무 쉽네요.

PHP로 웹개발 시작한 것을 잘했다고 생각하시죠?  그렇습니다. ^^

 

계속해서 로그인 프로세스를 타는 login_query.php로 넘어가 볼까요?

 

(참고) Java Spring 환경에서는 이와같이 php 와 html로 이동하지 않고 주로 Class 객체지향 설계를 이용해서 개발

 

사실 login_query.php의 역할은 서버사이드 개발파트입니다.

즉 이전화면에서 넘어온 username과 password가 해당 데이터베이스 테이블에 존재하느냐 안하느냐를 분기처리해 주는 부분입니다.

 

그러니 실제 해당 php는 html 태그가 거의 들어가지 않습니다.

 

<?php
	session_start();
	
	require_once 'conn.php';
	
	if(ISSET($_POST['login'])){
		if($_POST['username'] != "" || $_POST['password'] != ""){
			$username = $_POST['username'];
			// md5 encrypted
			// $password = md5($_POST['password']);
			$password = $_POST['password'];
			$sql = "SELECT * FROM `member` WHERE `username`=? AND `password`=? ";
			$query = $conn->prepare($sql);
			$query->execute(array($username,$password));
			$row = $query->rowCount();
			$fetch = $query->fetch();
			if($row > 0) {
				$_SESSION['user'] = $fetch['mem_id'];
				header("location: home.php");
			} else{
				echo "
				<script>alert('Invalid username or password')</script>
				<script>window.location = 'index.php'</script>
				";
			}
		}else{
			echo "
				<script>alert('Please complete the required field!')</script>
				<script>window.location = 'index.php'</script>
			";
		}
	}
?>

 

서버사이드 개발은 백엔드에서 TCP같은 소켓이나 Open API를 연동하지 않는다면 거의 다가 DB 테이블 쿼리 작업이 다수 입니다. (그러므로 개발자는 쿼리를 중,상급 레벨까지 올려서 작성개발 스킬을 높여야 하는 과제가 있습죠)

 

가장 상단에는 기본적으로 디비 접속하기 위한 conn.php 가 보입니다.

너무나 기본적인 흐름입니다. 디비 query를 하기전에 해당 디비가 살아있는지(live) 확인하는 프로세스가 들어가야 하죠

 

<?php
	$db_username = 'test';
	$db_password = 'test';
	$conn = new PDO( 'mysql:host=localhost;dbname=test_db', $db_username, $db_password );
	if(!$conn){
		die("Fatal Error: Connection Failed!");
	}
?>

해당 되는 내용도 사실은 100% 서버 사이드 개발 부분입니다만 이전에 우리가 개발환겨설정시 마리아DB 커넥션을 만들어 볼때 사용하던 소스와 유사합니다. 설치된 마리아 DB 접근 아이디와 패스워드(여기서 테이블로 만든 아이디와 패스워드가 아님)를 넣고 해당하는 커넥션으로 접속확인하는 소스입니다. 

 

정상인경우 에러 없이 바로 다음 프로세스를 진행합니다.

즉 다시 돌아와 login_query.php에서 해당 쿼리를 실행하는 것이죠

$sql = "SELECT * FROM `member` WHERE `username`=? AND `password`=? ";

여기에 있는 sql 문장은 보이는 그대로 member테이블에서 넘어온 username과 password 데이터를 ? 에 대입하여 값이 있는지 없는지 확인합니다. 즉 여기서 만약 username이 'admin' 이고 패스워드가 'admin'이라고 가정한다면

실제 쿼리 수행 문장은 이렇게 되겠죠?

 

SELECT * FROM member WHERE username='admin' AND password='admin'
 
실제 DB쿼리툴(DBeaver) 로 확인해보면 

값이 있네요 그러므로 if($row > 0) 이것의 조건은 만족하는 것이고 아래와 같이 home.php로 이동하겠습니다.

			if($row > 0) {
				$_SESSION['user'] = $fetch['mem_id'];
				header("location: home.php");
			} else{
				echo "
				<script>alert('Invalid username or password')</script>
				<script>window.location = 'index.php'</script>
				";
			}

하지만 입력한 값과 DB값이 다르다면 alert 을 "Invalid username or password"라고 띄우고 다시 원래 화면인 index.php 초기 화면으로 돌아가는 것이죠?  참 쉽죠? 어려운 것이 없습니다.

 

그럼 정상적인 로그인 절차를 계속 알아보기 위해 home.php로 다시 돌아가 보겠습니다.

바로 이 화면입니다. 이 화면은 로그인 이후에 처리된 세션값이 존재하는 메인 페이지입니다. 즉 로그인 하지 않고는 볼 수 없는 화면인 것이죠. 그러나 세션(특정 사용자값 몇가지)을 가지고 인증하는 것은 시간 제한을 두어 특정시간이 반응 없이 방치될 경우 페이지가 세션이 끊어져 다시 원래 index.php 로그인 페이지로 돌아가게 하는 것이 웹개발 로그인 프로세스의 기본입니다. 그러므로 이소스의 가장 상단에는 현재의 세션 체크를 하는 부분이 늘 존재합니다.

때로는 이러한 세션 체크 부분을 따로 php로 빼서 include 해서 사용하기도 합니다.

<?php
	require 'conn.php';
	session_start();
	
	if(!ISSET($_SESSION['user'])){
		header('location:index.php');
	}
?>

 

여기서 세션을 유지하면서 사용자에게 필요한 컨텐츠 페이즈를 메뉴를 만들어서 붙여 나가면 그게 홈페이지이고 그것이 웹개발의 시작이다 라고 말할 수 있습니다.

 

마지막으로 로그아웃 부분을 보겠습니다. 

 

위의 로그아웃 버튼을 클릭하면 

            <a href = "logout.php">Logout</a>

이렇게 A링크로 logout.php를 호출합니다.

 

<?php
	session_start();
	session_destroy();
	header('location: index.php');
?>

logout 페이지는 서버사이드 페이지입니다. 

해당 세션을 invalidate시키고 (무효화 또는 리셋) index.php 메인로그인 페이지로 이동시킵니다.

 

여기서 추가적으로 사용자 등록페이지에서 실제로 등록하는 내용도 보겠습니다.

다시 메인페이지에서 Registration 버튼을 누르면 등록화면으로 이동하며 

사용자 등록을 해보면

 

여기서 register 등록을 한다는 의미는 <form>태그로 submit 했다는 의미이며 해당 소스를 보면

<form action="register_query.php" method="POST">	
	<h4 class="text-success">Register here...</h4>
	<hr style="border-top:1px groovy #000;">
	<div class="form-group">
		<label>Firstname</label>
		<input type="text" class="form-control" name="firstname" />
	</div>
	<div class="form-group">
		<label>Lastname</label>
		<input type="text" class="form-control" name="lastname" />
	</div>
	<div class="form-group">
		<label>Username</label>
		<input type="text" class="form-control" name="username" />
	</div>
	<div class="form-group">
		<label>Password</label>
		<input type="password" class="form-control" name="password" />
	</div>
	<br />
	<div class="form-group">
		<button class="btn btn-primary form-control" name="register">Register</button>
	</div>
	<a href="index.php">Login</a>
</form>

여기서 form action 에 있는 register_query.php 로 submit 되어 페이지가 이동됩니다.

 

해당되는 register_query.php 도 서버사이드 디비쿼리 코딩 내용입니다.

 

<?php
	session_start();
	require_once 'conn.php';
 
	if(ISSET($_POST['register'])){
		if($_POST['firstname'] != "" || $_POST['username'] != "" || $_POST['password'] != ""){
			try{
				$firstname = $_POST['firstname'];
				$lastname = $_POST['lastname'];
				$username = $_POST['username'];
				// md5 encrypted
				// $password = md5($_POST['password']);
				$password = $_POST['password'];
				$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//				$sql = "INSERT INTO `member` VALUES ('','$firstname', '$lastname', '$username', '$password')";
				$sql = "INSERT INTO member(firstname,lastname,username,password) VALUES ('$firstname', '$lastname', '$username', '$password')";
				$conn->exec($sql);
			}catch(PDOException $e){
				echo $e->getMessage();
			}
			$_SESSION['message']=array("text"=>"User successfully created.","alert"=>"info");
			$conn = null;
			header('location:index.php');
		}else{
			echo "
				<script>alert('Please fill up the required field!')</script>
				<script>window.location = 'registration.php'</script>
			";
		}
	}
?>

 

이 과정에서도 약간의 오류가 있어서 디버그 및 수정작업이 있었으니 여러분들도 개발하면서 오류를 찾아가면서 잡아가기 바랍니다. 그것도 과정이니깐요 흑 ㅠ

 

아래의 password 컬럼에도 비밀번호가 그대로 노출되어 보이는데요 실제 이렇게 코딩하면 나중에 보안취약점에 걸려서 재개발할 수도 있으니 이것도 MD5나 기타 암호화모듈을 생각하여 추가수정 개발해보세요

 

 

실제로 디비에는 위와 같이 한개의 데이터 row가 추가됨을 볼 수가 있습니다.

 

해당 아이디로 로그인해 보면 됩니다.

 

 

성공적으로 로그인을 할 수가 있음을 볼 수 있습니다.

 

 

여기까지 우리는 로그인처리를 하는 미니 웹페이지를 만들어 보았습니다.

작은 프로젝트지만 개발을 처음하는 분들은 해당되는 개발의 프로세스를 맛보았을 것이고

여기서부터 시작하여 복잡한 개발 프로세스와 기타 시스템 연동등이 시작되는 것입니다.

 

너무 간단하다고요? 아주 좋은 현상입니다.

 

여기서 여러분들에게 과제를 드리자면

 

로그인 한 후에 메인페이지에서 어드민 관리자 페이지를 (아니면 사용자 페이지 등) 만들어보세요

즉 사용자가 사용자 등록하면 member테이블에 사용자 데이터 쌓일 텐데 이 데이터가 등록되면 

수정, 삭제 또는 임의 입력 같은 화면을 몇개 추가해서 완성해 보세요

즉 admin 으로 로그인 하면 해당되는 member 테이블의 데이터를 뿌려주고 이것도 건수가 많아지면

게시판 형태로 페이징(paging)도 넣어야 겠죠? 아하~ 이제 좀 복잡해지죠?

 

그 리스트에서 각각의 사용자 데이터를 수정도 하고 삭제도 가능한 페이지를 만들어 보세요

이정도 해주면 웹개발의 기본은 했다고 볼 수 있습니다.

 

이것이 어느정도 자유자재로 완료되면
이제는 좀더 심화하셔도 되고 다른 정말 내가 하고 싶은 언어로 넘어가면서
이제는 정말 쉽게 적응하며 개발하실 수 있습니다

 

더 좋은 소스 코드를 보고 싶은 분들은

위에 알려준 사이트에 많은 오픈소스 PHP 프로젝트가 공개되어 있습니다.

 

 

(PHP 개발 참고사이트)

 

https://www.sourcecodester.com/tutorials/php/12348/php-pdo-login-and-registration.html

 

Creating a Login and Registration Form using PHP PDO Tutorial | Free Source Code, Projects & Tutorials

Creating a Login and Registration Form using PHP PDO Tutorial

www.sourcecodester.com

 

 

https://www.c-sharpcorner.com/blogs/curd-operation-with-user-profile-in-php-mysql

 

CRUD Operation On A User Profile In PHP/ MySQL

In this article, I’ll show you how to perform the CRUD operation on a user profile in PHP/MySQL.

www.c-sharpcorner.com

 

http://ww1.phpcodify.com/

 

http://ww1.phpcodify.com/

 

ww1.phpcodify.com

 

감사합니다.

'테크노트 > PHP' 카테고리의 다른 글

PHP에서 세션을 어떻게 사용하는가?  (0) 2021.12.03
PHP 날짜 함수 사용하기  (0) 2021.12.03
웹개발 - PHP 문법 클래스편  (0) 2021.11.15
웹개발 - PHP 문법 배열편  (0) 2021.11.15
웹개발 - PHP 문법 함수편  (0) 2021.11.14

댓글