2023.03.13 - 안드로이드 앱개발자 과정

CHA·2023년 3월 13일
0

Web



HTTP 통신

HTTP 요청 규약에는 GET 방식과 POST 방식이 있습니다. GET 방식은 URL 에 데이터를 추가하여, key-value 의 형식으로 데이터를 보내는 방식입니다. 다만, URL 에 직접 데이터를 추가하여 데이터를 보내다 보니, 보안상의 문제점이 생깁니다. 그래서 보안이 중요한 데이터의 경우에는 POST 방식을 이용하여 데이터를 보냅니다. 이번에는 HTTP 통신을 하는 방법 중에 GET 방식과 POST 방식이 어떠한 과정에 의해 데이터 전달이 이루어지는지 알아봅시다.


GET 방식

<!DOCTYPE html>
<html>
    <head>
        <title>HttpRequest</title>
        <meta charset="utf-8">
    </head>
    <body>
        <h2>This is Http Request Test Page</h2>
        <fieldset>
            <legend>GET METHOD</legend>
            <form action="./getTest.php" method="GET">

                <p>
                    <label for="">title : </label>
                    <input type="text" name="title">
                </p>
                <p>
                    <label for="">message : </label>
                    <input type="text" name="msg">
                </p>
                <p>
                    <input type="submit">
                </p>
            </form>
        </fieldset>
    </body>
</html>

<form> 태그를 이용하면, 서버의 다른 문서를 실행시킬 수 있습니다. 즉, HTTP 요청을 할 수 있게 됩니다. 위 코드에서는 getTest.php 파일을 실행합니다. 또한 method 속성을 이용하여 GET 방식 혹은 POST 방식을 선택합니다. 우리는 GET 방식을 확인해보아야 하므로, 속성값으로 GET 을 넣어줍시다.

그리고 나서 제출 버튼을 누르면, getTest.php 파일이 실행되는데, 아직 우리는 그 파일을 만든적은 없으니 파일을 찾을수 없다고 나옵니다. 단, 주소창을 보면 다음과 같이 나타납니다.

GET 방식을 이용해 데이터를 보냈기 때문에, ?& 을 이용하여 보낸 데이터가 어떠한 키값과 데이터를 갖는지 알 수 있습니다. 자 그러면 이제 우리가 입력한 데이터를 보낼 getTest.php 문서를 만들어 줍시다. getTest.php 문서에서는 우리가 보낸 title 과 message 를 받아주기만 하면 됩니다.

<?php
    header('Content-Type:text/html; charset=utf-8');

    // $title= $_GET[0];
    // $message= $_GET[1];
    $title= $_GET['title'];
    $message= $_GET['msg'];

    echo "제목 : ".$title."<br>";
    echo "메세지 : ".$message;
?>
  • header('Content-Type:text/html; charset=utf-8');
    php 를 만들기 위해 필수적으로 들어가야 하는 속성이며, php 문서가 응답하는 데이터의 형식지정과 한글깨짐의 방지를 해줍니다.

  • $title= $_GET['title'];
    php 에서는 변수를 $ 를 이용하여 지정한다는 점을 기억합시다. html 에서 보낸 title 과 message 를 받을 변수 $title$message 를 만든 뒤, GET 방식으로 받아주어야 하므로 $_GET[] 을 이용하여 받아줍시다. 우리가 보낸 데이터는 titlemessage 로 , 여러개 이기 때문에 배열로 처리해주어야 합니다. 또한 배열의 인덱스로 숫자값을 넣어줄 수 도 있지만, html 에서 설정해주었던 name 속성값을 키값으로 사용할 수도 있습니다.

  • echo "제목 : ".$title."<br>";
    데이터를 잘 받았는지 확인하기 위해 응답을 할 수 있는데, 이럴 때 사용하는게 echo 입니다. 또한 php 의 경우 따로 인터프리터를 설치하지 않는 이상 php 문서를 해독할 수 없습니다. 다만, 우리가 신청했던 호스팅 서버의 경우 내부적으로 php 의 인터프리터가 설치되어있기 때문에, 서버에 파일만 올려주면 자동으로 해독됩니다.


POST 방식

POST 방식의 테스트도 GET 방식의 테스트와 크게 다르지 않습니다. 코드부터 봅시다.

<!DOCTYPE html>
<html>
    <head>
        <title>HttpRequest</title>
        <meta charset="utf-8">
    </head>
    <body>
        <h2>This is Http Request Test Page</h2>
      
        ... 중략 

        <fieldset>
            <legend>POST METHOD</legend>
            <form action="./postTest.php" method="POST">
                <p>
                    <label for="">ID : </label>
                    <input type="text" name="id">
                </p>
                <p>
                    <label for="">Password : </label>
                    <input type="password" name="pw">
                </p>
                <p>
                    <input type="submit">
                    <input type="reset">
                </p>
            </form>
        </fieldset>
    </body>
</html>

<input> 의 타입으로 reset 을 지정하면, 초기화 버튼을 사용할 수 있습니다. 또한 두번째 레이블의 타입을 password 로 하면 우리가 흔히 보던 패스워드의 입력 형식으로 입력할 수 있습니다.

그리고 나서, 제출을 해보면 역시 아직 php 파일을 만들어주지 않았으므로 파일을 찾을 수 없다고 뜨지만, 주소창을 보면 다음과 같이 표시됩니다.

GET 방식이 보안이 취약해 그 부분을 보완하는게 POST 방식이므로, URL 에 직접적으로 데이터를 표시하지 않습니다. 그러면 이제 php 파일을 만들어봅시다.

<?php
    header('Content-Type:text/html; charset=utf-8');

    $id = $_POST['id'];
    $password = $_POST['pw'];

    echo "ID : $id<br>";
    echo "Password : $password";
?>

우리는 GET 방식이 아닌 POST 방식으로 데이터를 서버로 보내주었기 때문에, php 문서에서 역시 $_POST[] 로 POST 방식으로 받아주어야 합니다. 역시 복수개의 데이터들을 서버로 보냈기 때문에 배열로 처리해주어야 합니다.


이미지 파일 업로드

이미지 파일을 업로드 하는 방식은 앞서 했던 텍스트를 보내는 방식보다는 까다롭습니다. 일단 html 코드부터 봅시다.

html 작성하기

<!DOCTYPE html>
<html>
    <head>
        <title>HttpRequest</title>
        <meta charset="utf-8">
    </head>
    <body>
        <h2>This is Http Request Test Page</h2>
      
      ... 중략
     
        <fieldset>
            <legend>IMAGE UPLOAD</legend>

            <form action="./uploadFile.php" method="POST" enctype="multipart/form-data">
                <input type="file" accept=".jpg" name="img">
                <br>
                <input type="submit">
            </form>

        </fieldset>
    </body>
</html>

<form> 태그의 속성으로 method 는 GET 방식으로 보낼지 POST 방식으로 보낼지 결정해야합니다. 이미지 파일의 경우 GET 방식 처럼 주소창에 어떠한 데이터값으로 보낼수는 없습니다. 따라서 POST 방식으로 보내줘야 합니다. 또한 중요한 속성인 enctype 속성이 필요합니다. 이미지 파일의 업로드를 위해서는 속성값으로, multipart/form-data 을 지정해주어야 합니다.

또한 <input type="file" accept=".jpg" name="img"> 을 지정해주면, 사용자가 파일을 선택할 수 있게 됩니다. accept 은 파일 선택시 기본 확장자를 지정할 수 있으며, name 속성을 이용하여 파일 데이터에 대한 키값을 지정할 수 있습니다.

php 파일 작성하기

이제 php 파일을 작성해줍니다. header('Content-Type:text/html; charset:utf-8'); 을 적어주는걸 잊지맙시다. 일단 코드부터 봅시다.

<?php
    header('Content-Type:text/html; charset:utf-8');

    $file = $_FILES['img'];

    $srcName =  $file['name']; 
    $type =     $file['type'];
    $size =     $file['size']; 
    $tmpName =  $file['tmp_name'];
    $error =    $file['error'];

    echo "$srcName<br>";
    echo "$type<br>";
    echo "$size<br>";
    echo "$tmpName<br>";
    echo "$error<br>";
?>

사용자가 File 을 보내면, 즉 이미지 파일을 서버로 보낸다고 하면, 실제 이미지 파일의 데이터들은 임시저장소에 저장이 되며, 이 php 파일 문서에는 File 의 정보만이 전달됩니다.

그 정보들은 $_FILES[] 라는 배열에 저장됩니다. 우리가 보낸 이미지 파일의 키값은 img 이므로, 배열의 인덱스 값으로 이미지 파일의 키값인 img 를 넣어주어야 합니다. 그러면 그 파일의 정보들이 $file 에 저장됩니다. 파일의 정보는 하나가 아닌 여러개가 있기 때문에 $file 변수 또한 배열입니다.

$file 변수 안에는 파일 정보가 5개가 있으며, 지정된 갯수 입니다. 파일의 정보는 원본 파일명, 파일 타입, 파일 크기, 임시저장소에 저장된 파일의 주소, 에러 정보 가 있으며, 각각 $file['name'], $file['type'],$file['size'],$file['tmp_name'],$file['error'] 으로 가져올 수 있습니다. (name,type 등은 이미 정해진 키값입니다.)

각각의 파일의 정보를 변수에 담고, echo 를 이용하여 잘 받아졌는지 확인해봅시다.

우리가 보낸 이미지파일의 이름도 정상정으로 잘 왔고, image/jpeg 이라는 MIME 형식의 파일 타입으로 잘 도착했습니다. 사이즈도 잘 왔고, 임시 저장소에 저장된 파일의 주소도 잘 도착했습니다. 임시저장소에 저장된 파일의 주소는 서버가 임의로 정한 이름을 잠시동안 부여합니다. 또한 에러 정보도 잘 왔습니다. 에러 정보가 0이면, 정상적으로 잘 왔다는걸 의미합니다.

이미지 파일 영구적 저장

위 화면을 보니 정보는 잘 확인된것 같습니다. 그렇다면 분명 서버에 이미지 파일이 잘 전송이 되었다는 의미겠죠. 근데, 이 이미지의 파일은 임시저장소에 저장이 되어있기 때문에 시간이 지나면 곧 삭제됩니다. 그래서 온전히 업로드를 하기 위해서는 임시저장소에 있는 파일을, 즉 $tmpName 을 영구히 사라지지 않는 html 에 이동시켜야 합니다.

그러면 테스트를 위해 php 문서가 있는 폴더에 upload 라는 폴더를 만들어 임시저장소에 저장된 이미지 파일을 이 폴더 안으로 이동시킵시다. 단, 이미지 파일의 이름이 중복이 되면 안되기 때문에 날짜를 기반으로 이름을 정해줍시다.

<?php
	... 중략 

    $dstName = "./upload/".date('YmdHis').$srcName;

    $result = move_uploaded_file($tmpName,$dstName);
    if($result){
        echo "Success Upload";
    }else {
        echo "Fail Upload";
    }
?>

이미지 파일을 옮길 주소는 만들었으니, 이제 이미지 파일을 만든 주솟값으로 넣어주어야 합니다. move_uploaded_file() 을 이용하여 옮겨줄 수 있습니다. 또한 앞의 함수는 리턴값이 boolean 값으로 리턴되기 때문에 if 문과 echo 를 활용하여 데이터가 잘 옮겨졌는지를 확인해볼 수 있습니다.


종합 예제

이번에는 POST 방식을 활용하여, 파일과 함께 문자열 데이터도 같이 넘겨주는 테스트를 해봅시다.

<!DOCTYPE html>
<html>
    <head>
        <title>HttpRequest</title>
        <meta charset="utf-8">
    </head>
    <body>
        <h2>This is Http Request Test Page</h2>
      
      ... 중략
      
        <fieldset>
            <legend>POST data with File</legend>
            <form action="./postDataFile.php" method="POST" enctype="multipart/form-data">
                <p>
                    <label for="">name : </label>
                    <input type="text" name="name">
                </p>
                <p>
                    <label for="">message : </label>
                    <input type="text" name="msg">
                </p>
                <p>
                    <label for="">file : </label>
                    <input type="file" name="img" accept="image/*">
                </p>
                <p>
                    <input type="submit" value="작성완료">
                    <input type="reset" value="취소">
                </p>
            </form>
        </fieldset>
    </body>
</html>

파일의 데이터와 문자열 데이터를 넘겨주기 위해 html 문서를 작업했습니다. 그러면 이제, postDataFile.php 파일을 작성해줍시다.

<?php
    header('Content-Type:text/html; charset=utf-8');

    $name = $_POST['name'];
    $msg = $_POST['msg'];
    $file = $_FILES['img'];

    $srcName = $file['name'];
    $tmpName = $file['tmp_name'];

    $dstName = "./upload/".date('YmdHis').$srcName;
    $result = move_uploaded_file($tmpName,$dstName);

    if($result){
        echo "$name<br>";
        echo "$msg<br>";
        echo "Success Upload";
    }else{
        echo "Fail Upload";
    }
?>

앞선 예제와 동일합니다.


Database 에 저장하기

우리의 목적은 사용자가 생성한 데이터를 서버로 보내고, 서버에 보내진 데이터를 데이터베이스에 저장을 해야합니다. 그러기 위해서는 DBMS 를 이용해야 하며, 우리는 MySQL 이라는 DBMS 를 사용합니다. 다행스럽게도, 호스팅 서버에 이미 MySQL 이 설치되어있기 때문에, 그것을 이용해주면 됩니다.

일단 데이터베이스에 테이블 하나를 만들겠습니다. 테이블의 속성으로는 index 값과, 이름, 메시지, 이미지 파일, 등록 시간 을 저장할 예정입니다.

호스팅 사이트에서 적절하게 테이블을 생성해주면 됩니다. 이렇게 생성된 테이블을 기반으로, php 파일을 이용하여 이 데이터베이스에 데이터를 저장해주겠습니다.

<?php
    header('Content-Type:text/html; charset=utf-8');

    $name = $_POST['name'];
    $msg = $_POST['msg'];
    $file = $_FILES['img'];

    $srcName = $file['name'];
    $tmpName = $file['tmp_name'];

    $dstName = "./upload/".date('YmdHis').$srcName;
    $result = move_uploaded_file($tmpName,$dstName);

    if($result){
        echo "$name<br>";
        echo "$msg<br>";
        echo "Success Upload";
    }else{
        echo "Fail Upload";
    }

// ----------------- 여기부터 보자

    $now = date('Y-m-d H:i:s');
   
    $db = mysqli_connect('localhost','tjdrjs0803','dkssud109!','tjdrjs0803'); 
    
    mysqli_query($db,"set names utf8");
    
    $sql = "INSERT INTO board(name,msg,file,date) VALUES('$name','$msg','$dstName','$now')";
    $result = mysqli_query($db,$sql);
    
    if($result) echo "insert Success";
    else echo "insert Fail";

    mysqli_close($db);
?>

우리가 저장할 변수는 $name,$msg,$dstName,$now 입니다. date() 를 이용하여 $now 변수에 현재 시간을 등록해주었습니다. 그리고 우리는 php 파일에서 데이터베이스를 관리해주어야 합니다.

  • $db = mysqli_connect('localhost','tjdrjs0803','dkssud109!','tjdrjs0803');
    그러기 위해서 먼저, mysql 과 연결해주어야 합니다. mysqli_connect() 를 이용하여 데이터베이스와 연결시켜줄 수 있습니다. 첫번째 파라미터는 DB 가 있는 컴퓨터의 IP 주소를 넣어주어야 하며, 두번째는 DB 접속 ID, 세번째는 DB 접속 비밀번호, 마지막은 DB 의 이름을 전달해주어야 합니다. 단, 규모가 크다면 DB 가 있는 컴퓨터의 IP 주소는 php 가 있는 파일과 별도로 있겠지만, 우리는 테스트 용이므로, php 가 있는 파일의 서버와 동일한 주소를 사용합니다. 그렇기 때문에 localhost 를 사용해주었습니다.

  • mysqli_query($db,"set names utf8");
    한글 깨짐 방지를 해주기 위해 쿼리문 하나를 추가합니다.

  • $result = mysqli_query($db,$sql);
    쿼리문을 사용하여, $db 에 쿼리문을 적용시켰습니다. INSERT 문을 활용하여 데이터를 넣은 작업입니다.


Database 에서 로드하기

데이터베이스에 데이터를 집어넣는 작업은 해보았으니, 이제 데이터베이스에서 꺼내오는 작업을 해줄 차례입니다. 먼저 html 문서에 로드 버튼 하나를 만들어줍시다.

<!DOCTYPE html>
<html>
    <head>
        <title>HttpRequest</title>
        <meta charset="utf-8">
    </head>
    <body>
        <h2>This is Http Request Test Page</h2>
      
      ... 중략 
      
        <fieldset>
            <legend>Load Data</legend>
            <form action="./loadDB.php" method="GET">
                <input type="submit" value="load">
            </form>
        </fieldset>
    </body>
</html>

이 버튼을 누르면 데이터베이스에 저장된 데이터들을 불러올 수 있습니다.

그러면 이제, loadDB.php 를 작성해봅시다.

<?php
    header('Content-Type:text/html; charset=utf-8');

    $db = mysqli_connect('localhost','tjdrjs0803','dkssud109!','tjdrjs0803');

    mysqli_query($db,"set names utf8");

    $sql = "SELECT * FROM board";
    $result = mysqli_query($db,$sql); 
    if($result){
        $rowNum = mysqli_num_rows($result);
        for($i=0;$i<$rowNum;$i++){
            $row = mysqli_fetch_array($result,MYSQLI_ASSOC);
            $no = $row['no']; 
            $name = $row['name'];
            $message = $row['msg'];
            $file = $row['file'];
            $date = $row['date'];

            echo "<h2> $no $name</h2>";
            echo "<p> $message </p>";
            echo "<p> $date </p>";

            if($file != null) echo "<img src = '$file' width='50%'>";
        }
    }else{
        echo "Loading Failed";
    }
    mysqli_close($db);
?>

데이터베이스에서 꺼내오는 작업도 넣는 작업과 크게 다르지 않습니다. DB 와 연결해주고, 쿼리문을 활용하여 , 즉 SELECT 문을 활용하여 데이터베이스의 데이터를 가져와주기만 하면 됩니다.

  • $db = mysqli_connect('localhost','tjdrjs0803','dkssud109!','tjdrjs0803');
    DB 를 연결하는 객체하나를 만들어줍시다. $db 를 이용하면 이제 데이터베이스를 관리할 수 있게됩니다.

  • $sql = "SELECT * FROM board";
    board 테이블에서 데이터를 뺴오는 쿼리문을 하나 만들어주었습니다.

  • $result = mysqli_query($db,$sql);
    만들어진 쿼리문을 적용해줍시다. 그러면 반환값으로 쿼리문이 적용된 새로운 가상의 테이블을 줍니다. 즉, $result 에는 쿼리문을 통해 검색된 결과표가 들어있습니다. 단, 아무것도 없으면 false 를 반환합니다.

  • $rowNum = mysqli_num_rows($result);
    mysqli_num_rows() 을 이용하면 파라미터에 들어간 변수(가상의 테이블) 의 줄수를 구할 수 있습니다. 즉, 데이터의 개수를 받아올 수 있습니다. 그러면 이 데이터의 개수를 바탕으로 for 문을 활용해 데이터를 받아옵시다.

  • $row = mysqli_fetch_array($result,MYSQLI_ASSOC);
    mysqli_fetch_array() 을 이용하면 테이블 한 줄의 데이터를 반환합니다. 한 줄의 데이터에는 여러개의 데이터가 들어있을 수 있기 때문에 배열로 처리할 수 있습니다. 즉, $row 에는 배열로 데이터들이 들어있는 형태입니다.

  • $no = $row['no'];
    위 코드와 같이 $row 변수의 인덱스값으로 식별자를 사용할 수 있습니다. 그리고 그 값을 새로운 변수에 입력시켜주었습니다. 단, 식별자를 사용할 때에는 데이터베이스 테이블에 명시되어있는 속성값을 그대로 사용해주어야 합니다.

이렇게 해서 데이터베이스에서 데이터를 꺼내오는 방법까지 알아보았습니다.

profile
Developer

0개의 댓글