본문 바로가기

개발과제

[노말틱 모의 해킹 취업반 추가 개발과제 ] 주소 검색 기능 만들기

안녕하세요! 제가 저번에 주소 검색 기능을 API로 만든 기억이 있습니다.

저는 그 API를 없애고 우체국 사이트에 데이터베이스를 다운로드하고 난 뒤에 직접 코딩을 짜보겠습니다.

 

일단 DB을 다운로드하여보겠습니다.

 

우체국 사이트에 들어가 셔서

 

 

우체국은 많이 가봤는데 사이트는 처음이네요

 

우편번호 DB파일 바로가기 누른 다음 지역별 주소 DB을 다운로드하시면 됩니다!

 

 

그리고 압축 해제하셔서 보시면 되는데

 

저는 칼리 리눅스라 그런지 한글명이 깨지더라고요

 

뭐라는겨

 

그래서 저는 윈도에서 다운로드하고 옮겼습니다.

 

 

이게 가장 쉬워요

 

만약 칼리 리눅스 내에서 해결을 하고 싶으면 iconv을 이용하면 되는데 더욱 까다로워집니다..

윈도에 다운로드하시거나 핸드폰에 다운로드하고 압축 풀어서 네이버나 USB 통해 옮기시면 됩니다

 

안에 내용 보시면

 

강원도.txt입니다.

 

이렇게 되어있을 텐데 저희는 이 것을 저희가 테이블을 만들고 이에 맞춰서 컴럼을 만들어야 합니다.

그리고 다행히 이 txt파일은 파이프(|) 라인으로 구별되어서 있어서

구분자를 | 로 하여서 자동으로 데이터를 넣게 할 수 있습니다!

 

시작하죠 일단 테이블을 만들어야 합니다.

 

DB!

 

그리고 테이블을 우편번호로 하고..

 

셀러 보니 칼럼이 26개 있네요!

 

그다음에 이 코드로 sql문을 삽입하겠습니다.

 

CREATE TABLE 우편번호 (
  우편번호 INT(5) NOT NULL,
  시도 VARCHAR(20) NOT NULL,
  시도영문 VARCHAR(20),
  시군구 VARCHAR(20) NOT NULL,
  시군구영문 VARCHAR(20),
  읍면 VARCHAR(20),
  읍면영문 VARCHAR(20),
  도로명코드 INT(10),
  도로명 VARCHAR(20),
  도로명영문 VARCHAR(20),
  지하여부 VARCHAR(10),
  건물번호본번 VARCHAR(10),
  건물번호부번 VARCHAR(10),
  건물관리번호 VARCHAR(20),
  다량배달처명 VARCHAR(100),
  시군구용건물명 VARCHAR(100),
  법정동코드 VARCHAR(20),
  법정동명 VARCHAR(20) NOT NULL,
  리명 VARCHAR(10),
  행정동명 VARCHAR(20),
  산여부 VARCHAR(10),
  지번본번 INT(5),
  읍면동일련번호 INT(10),
  지번부번 INT(5),
  구우편번호 INT(5),
  우편번호일련번호 INT(10),
  PRIMARY KEY (우편번호)
);

 

 

데이터를 한꺼번에 넣을땐 이게 좋네요

 

그리고 ctrl+enter 눌러서 실행합니다.

 

콘솔은 밑에 있어요

 

 

아랫쪽에 있어요

 

이제 테이블이 있으니 데이터를 넣기만 하면 되겠죠?

 

일일이 삽입하기엔 너무 오래 걸리니 저희는 LOAD DATA을 이용하겠습니다!

LOAD DATA는 말 그대로 데이터를 넣는 겁니다. 파일 내에 구분자로 나누어서 각각 데이터가 알아서 들어가게 하는

방대한 데이터를 넣을 땐 매우 매우 좋은 기능입니다.

 

LOAD DATA LOCAL INFILE '/path/zipcode_DB/강원도.txt'
INTO TABLE 우편번호
FIELDS TERMINATED BY '|'
ENCLOSED BY ''
LINES TERMINATED BY '\r\n'
IGNORE 1 ROWS;

이것이 기본 틀입니다. 저기 path/zipcode_DB는 자신이 저장한 DB파일의 경로를 적으시면 됩니다!

 

먼저 강원도 하겠습니다.

 

마지막 줄에 IGNORE 1 ROWS는

 

맨 처음 한 줄이 우편번호|시도|... 이렇게 적혀 있어서 이 줄을 무시하기 위해 적은 겁니다.

 

그리고 실행하면?

 

앗!

 

그렇죠 맞죠 저희가 LOAD 하는 권한을 준 적이 없습니다.

 

그럼 잠깐 주면 되겠네요

 

php.ini 파일을 열겠습니다.

 

#sudo vi /etc/php/8.2/apache2/php.ini

 

그리고 보시면 

 

저기 주석처리 된거 보이시나요

 

저기 mysqli.allow_local_infile = On 이 주석 처리 된 게 보이시죠? 이게 권한을 안 준겁니다!

 

잠깐 On으로 켜두죠

 

 

On!

 

그리고 또 설정할 게 있습니다. 원래 이렇게만 해도 돼야 되긴 하는데 근데 mysql에서 설정을 하는 것이 더 좋다고 합니다.

 

그러니 저는 둘 다 하겠습니다.

 

#sudo vi /etc/mysql/my.cnf

 

 

맨아래에

 

만약 mysqld 섹션이 있으면 저 한 줄 추가하시면 되고요 없으시면 저렇게 추가하시면 됩니다.

 

 

저장 후 나가시고 이제 apache랑 mysql을 재시작합니다

 

그리고 다시 해보겠습니다.

 

 

화나네요!

 

음.. 그냥 콘솔로 하겠습니다.

편리한 대신 오류가 많네요

 

LOAD DATA LOCAL INFILE '/path/zipcode_DB/강원도.txt'
INTO TABLE 우편번호 CHARACTER SET 'utf8' FIELDS TERMINATED BY '|' IGNORE 1 LINES;

 

mysql -u [mysql ID] -p 들어가셔서

 

use 우체국_DB 하시고 저 코드를 입력하시면 됩니다!

 

 

경고는 무시하죠

 

이제 쭉쭉하겠습니다.

 

만약 나중에 문제가 생기면 이렇게 다시 하면 되겠죠! 그땐 테이블에 아예 NULL을 허용하게 추가하겠습니다

 

 

꽤나.. 고된 작업이네요..

 

이제 권한을 다시 빼겠습니다.

 

 

 

 

다 지웠습니다

 

그리고 phpmyadmin 통해 보시면 들어가진 걸 볼 수 있습니다!

 

많네요 확실히;

 

이제 코딩을 시작하겠습니다.

.

.

.

.

.

.

.

.

.

.

env파일에 데이터베이스 명을 추가하겠습니다.

#sudo vi /etc/apache2/envvars

 

 

 

한 줄 추가했습니다.

 

그리고 DB_INFO.php에도 추가하겠습니다.

 

join.php에 있는 API 관련 코딩을 전부 지우겠습니다.

그리고 주소 찾기 버튼을 추가했습니다.

 

<!DOCTYPE html>
<html>
<head>
    <title>회원가입</title>
</head>
<body>
    <h1>회원가입</h1>
    <form action="process_join.php" method="POST">
        <label>ID:</label>
        <input type="text" name="id" placeholder="특수기호 작성시 로그인 안되요" required><br><br>
        <label>비밀번호:</label>
        <input type="password" name="pw" required><br><br>
        <input type="text" name="address" id="address" value="<?php echo $_GET['address']; ?>" readonly> <!-- 검색된 주소를 표시할 입력란 -->
        <input type="button" value="주소 찾기" onclick="search_address()"><br><br> <!-- 주소 찾기 버튼 -->
        <input type="submit" value="회원가입">
    </form>
    <script>
        function search_address() {
            window.open("search_address.php", "주소 찾기"); // 새로운 창에서 search_address.php 호출
            window.close();
        }
    </script>

    <form action="login.php" method="POST">
        <p><input type="submit" value="로그인하러 가기"></p>
    </form>
    <p>
        <?php session_start();
                if (isset($_SESSION['join_error'])) {
                    echo $_SESSION['join_error'];
                    unset($_SESSION['join_error']);
                }
        ?>
    </p>
</body>
</html>

 

자바 스크립 트을 이용 하여 버튼 클릭 시 주소 찾기 코드문이 나오게 했습니다!

 

그리고 search_address.php을 만들겠습니다.

 

<!DOCTYPE html>
<html>
<head>
    <title>주소찾기</title>
</head>
<body>
    <h1>주소찾기</h1>
    <form action="search_address.php" method="POST">
        <label>주소입력: </label>
        <p><input type="text" name="id" placeholder="주소 입력" required></p>
        <input type="submit" value="검색">
    </form>
    <?php
        
    
    
    
    ?>


    <p>
        <?php session_start();
                if (isset($_SESSION['join_error'])) {
                    echo $_SESSION['join_error'];
                    unset($_SESSION['join_error']);
                }
        ?>
    </p>
</body>
</html>

 

이 php에 데이터베이스 넣고 주소 찾는 sql문까지 작성하겠습니다.

 

<!DOCTYPE html>
<html>
<head>
    <title>주소찾기</title>
</head>
<body>
    <h1>주소찾기</h1>
    <form action="search_address.php" method="GET">
        <label>주소입력: </label>
        <p><input type="text" name="search" placeholder="주소 입력" required></p>
        <input type="submit" value="검색">
    </form>
    <?php
        include 'DB_INFO.php';

        //데이터베이스 연결
        $conn = mysqli_connect($host,$username,$password,$db_address);

        //데이터베이스 오류시 종료
        if(mysqli_connect_errno()) {
            die("데이터 베이스 오류: ". mysqli_connect_error());
        }
        
        //검색이 입력된 경우
        if(isset($_GET['search'])) {
            $search = mysqli_real_escape_string($conn, filter_var(strip_tags($_GET['search']),FILTER_SANITIZE_SPECIAL_CHARS));

            // 검색어에 해당하는 주소 정보 검색
            $sql = "SELECT *
            FROM 우편번호
            WHERE CONCAT(우편번호,' ',시도,' ',시군구,' ',읍면,' ',도로명) LIKE '%$search%'";


        } else {
            //검색이 입력되지 않은 경우
            $search = '';
            $sql = "SELECT * FROM 우편번호"; //전체 게시물 검색
        }        
        
        //쿼리문 실행
        $result = mysqli_query($conn, $sql);

        if(mysqli_num_rows($result) > 0) {
            //주소 출력
            while($row = mysqli_fetch_assoc($result)) {

                $address = $row['우편번호'].' '.$row['시도'].' '.$row['시군구'].' '.$row['읍면'].' '.$row['도로명'];

                echo '<p><a href="join.php?address='.$address.'">'.$address.'</a></p>';
            }
        } else {
            echo "주소가 없습니다!";
        }
    ?>
</body>
</html>

 

주소를 입력할 때 페이지가 있을 필요가 딱히 느끼지 않기에 페이지 수 세는 기능을 빼겠습니다.

 

다들 우편번호 찾는 용이니깐요!

 

 

그리고 process_join.php에 $address을 받을 대 보안 함수를 추가했습니다!!

$adr = trim(mysqli_real_escape_string($conn,filter_var(strip_tags($_POST['address']),FILTER_SANITIZE_SPECIAL_CHARS)));

 

실행해 보겠습니다

 

잘되네요

 

 

그리고 아무거나 검색을 해보겠습니다.

 

 

 

만약 검색창에 남게 하고 싶으시면 value에 php문 적고 GET방식으로 받으시면 됩니다!

 

그리고 클릭하겠습니다.

 

성공!

 

이렇게 주소 API 제거하고 제가 직접 코딩을 해봤습니다.

 

다음에 할 것은 이제 제가 쓴 보안 함수은 escape보단 Prepared가 훨씬 좋다고 합니다.

 

그래서 다음에는 Prepared을 전부 적용할 겁니다!

 

긴 글 읽어주셔서 감사합니다.