ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SISS/웹 스터디] 2학기 7주차 스터디 - MySQL + PHP
    24-2 SISS/웹 2024. 11. 9. 21:00

    2학기 7주차 스터디 - MySQL + PHP

    : 7주차 11/04 ~ 11/10 [PHP & MYSQL] 08 ~ 12

     

    8.1. SELECT 사용법 1


    •  SELECT
      • 데이터 읽기
      • LIMIT
        • 불러오는 개수 제한
    • select.php
      • 기본 테이블
      • mysqli_query()
        • 실패 시
          • false 반환
        • 성공 시(읽기)
          • mysqli_result 객체를 반환 → var_nump($result→num_rows);와 같이 이용 가능
            • current_field
            • field_count
            • lengths
            • num_rows
    // select.php
    
    <?php
    $conn = mysqli_connect(
        "localhost",
        "root",
        "20242024",
        "opentutorials");
    $sql = "SELECT * FROM topic";
    $result = mysqli_query($conn, $sql);
    

    8.1. SELECT 사용법 1

     

    8.2. SELECT 사용법 2


    •  mysqli_fetch_~ → mysqli를 통해 가져온 데이터 타입을 php에 맞게 변경
      • mysqli_fetch_array(mysqli_result) → 한 행씩 배열과 연관 배열의 형태로 불러옴(없을 경우 NULL 반환)
    // select.php
    
    <?php
    $conn = mysqli_connect(
        "localhost",
        "root",
        "20242024",
        "opentutorials");
    $sql = "SELECT * FROM topic WHERE id = 6";
    $result = mysqli_query($conn, $sql);
    $row = mysqli_fetch_array($result);
    echo '<h1>'.$row['title'].'</h1>';
    echo $row['description'];
    

    8.2. SELECT 사용법 2

     

    8.3. SELECT 사용법 3


    • while
      • php의 NULL은 false와 같다는 것을 이용하여 조건식 작성
    // select.php
    
    <?php
    $conn = mysqli_connect(
        "localhost",
        "root",
        "20242024",
        "opentutorials");
    
    // 한 개의 row
    echo "<h1>한 개의 행</h1>";
    $sql = "SELECT * FROM topic WHERE id = 6";
    $result = mysqli_query($conn, $sql);
    $row = mysqli_fetch_array($result);
    echo '<h2>'.$row['title'].'</h2>';
    echo $row['description'];
    
    // 모든 row
    echo "<h1>여러 개의 행</h1>";
    $sql = "SELECT * FROM topic";
    $result = mysqli_query($conn, $sql);
    
    while($row = mysqli_fetch_array($result)) {
        echo '<h2>'.$row['title'].'</h2>';
        echo $row['description'];
    }
    

    8.3. SELECT 사용법 3

     

    9.1. 활용 - 글 읽기 1


    •  index.php
      • 참고
        • <?= … ?> → echo와 같은 역할
        • . → 문자열 결합
    // index.php
    
    <?php
        $conn = mysqli_connect(
            "localhost",
            "root",
            "20242024",
            "opentutorials");
    
        $sql = "SELECT * FROM topic";
        $result = mysqli_query($conn, $sql);
        $list = '';
    
        while ($row = mysqli_fetch_array($result)) {
            $list = $list."<li><a
                href=\\"index.php?id={$row['id']}\\">{$row['title']}</a></li>";
        }
    ?>
    
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>웹</title>
        </head>
        <body>
            <h1>웹</h1>
            <ol>
                <?=$list?>
            </ol>
            <a href="create.php">create</a>
            <h2>환영합니다</h2>
            Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatem animi facilis quos, nostrum dolore doloremque? Quod iusto fugit delectus pariatur dolorum esse dolor sunt! Consectetur, eius! Earum nostrum necessitatibus in!
        </body>
    </html>
    

    9.1. 활용 - 글 읽기 1

     

    9.2. 활용 - 글 읽기 2


    • 연관 배열 → 문자열을 인덱스로 한 배열(article) 생성
    // index.php
    
    <?php
        $conn = mysqli_connect(
            "localhost",
            "root",
            "20242024",
            "opentutorials");
    
        $sql = "SELECT * FROM topic";
        $result = mysqli_query($conn, $sql);
        $list = '';
    
        while ($row = mysqli_fetch_array($result)) {
            $list = $list."<li><a
                href=\\"index.php?id={$row['id']}\\">{$row['title']}</a></li>";
        }
    
        $article = array(
            'title'=>'환영합니다',
            'description'=>'안녕, 웹'
        );
    
        if(isset($_GET['id'])) {
            $sql = "SELECT * FROM topic WHERE id={$_GET['id']}";
            $result = mysqli_query($conn, $sql);
            $row = mysqli_fetch_array($result);
            $article['title'] = $row['title'];
            $article['description'] = $row['description'];
        }   
    ?>
    
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>웹</title>
        </head>
        <body>
            <h1><a href="index.php">웹</a></h1>
            <ol>
                <?=$list?>
            </ol>
            <a href="create.php">create</a>
            <h2><?=$article['title']?></h2>
            <?=$article['description']?>
        </body>
    </html>
    
    // create.php
    
    <?php
        $conn = mysqli_connect(
            "localhost",
            "root",
            "20242024",
            "opentutorials");
    
        $sql = "SELECT * FROM topic";
        $result = mysqli_query($conn, $sql);
        $list = '';
    
        while ($row = mysqli_fetch_array($result)) {
            $list = $list."<li><a
                href=\\"index.php?id={$row['id']}\\">{$row['title']}</a></li>";
        }
    
        $article = array(
            'title'=>'환영합니다',
            'description'=>'안녕, 웹'
        );
    
        if(isset($_GET['id'])) {
            $sql = "SELECT * FROM topic WHERE id={$_GET['id']}";
            $result = mysqli_query($conn, $sql);
            $row = mysqli_fetch_array($result);
            $article['title'] = $row['title'];
            $article['description'] = $row['description'];
        }   
    ?>
    
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>웹</title>
        </head>
        <body>
            <h1><a href="index.php">웹</a></h1>
            <ol>
                <?=$list?>
            </ol>
            <form action="process_create.php" method="POST">
                <p><input type="text" name="title" placeholder="title"></p>
                <p><textarea name="description" placeholder="description"></textarea></p>
                <p><input type="submit"></p>
            </form>
        </body>
    </html>
    

    9.2. 활용 - 글 읽기 2

     

    10.1. 보안 - filtering


    • 보안 → 사용자의 입력에서 문제점 발생
      • 유형
        1. 문제가 발생하는 정보가 입력 → filtering
        2. 문제가 있는 정보가 사용자에게 출력(노출) → escaping

     

    • mysqli_real_escape_string() → SQL 삽입 관련 문자를 안전하게 변경
      // index.php, create.php
      
      if(isset($_GET['id'])) {
          $filtered_id = mysqli_real_escape_string($conn, $_GET['id']);
          $sql = "SELECT * FROM topic WHERE id={$filtered_id}";
          $result = mysqli_query($conn, $sql);
          $row = mysqli_fetch_array($result);
          $article['title'] = $row['title'];
          $article['description'] = $row['description'];
      }  
      
      // process_create.php
      
      $filtered = array (
          'title'=>mysqli_real_escape_string($conn, $_POST['title']),
          'description'=>mysqli_real_escape_string($conn, $_POST['description'])
      );
      
      $sql = "
          INSERT INTO topic
          (title, description, created)
          VALUES(
              '{$filtered['title']}',
              '{$filtered['description']}',
              NOW()
          )
      ";
      

    10.1. 보안 - filtering

     

    10.2. 보안 sql injection의 원리


    • SQL Injection 발생 예시 (process_create.php) → NOW()를 다른 시각으로 변경
      • description 입력 → haha’, ‘2018-1-1 00:00:00’);--
        • mysqli_real_escape_string을 사용하지 않을 경우→ -- 이후는 주석처리되어 현재 시각이 아닌 입력한 시각으로 정보가 저장됨 → VALUES(’Hehe’, ‘haha’, ‘2018-1-1 00:00:00’);-- ‘, NOW()) 이 됨
        • 사용할 경우→ \가 추가되어 작은 따옴표가 문자열의 시작과 끝을 나타내는 기호의 역할이 아닌 문자 그대로의 역할을 하게 됨 → VALUES(’Hehe’, ‘haha\’, \‘2018-1-1 00:00:00\’);-- ‘, NOW()) 이 됨
      • 비밀번호 변경, 데이터 삭제, 운영체제 조작 등에 이용 가능

    10.2. 보안 sql injection의 원리

     

    • 참고
      • SQL문
        • 주석(--) → 뒤에 있는 문장은 해석하지 않음
        • mysqli_multi_query() → 복수의 SQL문을 실행, 보안 위험이 있으므로 mysqli_query() 사용 추천
      • die(인자); → 인자로 들어온 값을 출력하며 프로그램을 멈춤

     

    10.3. 보안 - escaping


    • XXS 발생 예시
      • 사용자가 악의적인 목적으로 자바스크립트 코드를 삽입할 경우(script 태그) → <script>location.href”https://opentutorials.org”</script> 입력
      • 외부로 정보 유출이 일어날 수 있음

     

    • XSS 예방
      • htmlspecialchars() → 태그로 인식하지 못하도록 <script>를 <script> 로 변환
    // index.php
    
    ...
    
    while ($row = mysqli_fetch_array($result)) {
        $escaped_title = htmlspecialchars($row['title']);
        $list = $list."<li><a
            href=\\"index.php?id={$row['id']}\\">{$escaped_title}</a></li>";
    }
    
    ...
    
    if(isset($_GET['id'])) {
        $filtered_id = mysqli_real_escape_string($conn, $_GET['id']);
        $sql = "SELECT * FROM topic WHERE id={$filtered_id}";
        $result = mysqli_query($conn, $sql);
        $row = mysqli_fetch_array($result);
        $article['title'] = htmlspecialchars($row['title']);
        $article['description'] = $row['description'];
    }  
    

     

    11.1. 활용 - 글 쓰기 1


    • index.php
      • update.php로 이동하는 링크 추가
      // index.php
      
      <body>
      	...
        <a href="create.php">create</a>
        <?=$update_link?>
        ...
      </body>
      

     

    •  update.php
      • $_GET['id']가 가능할 경우 update 링크를 생성하도록 하는 코드 추가
      • create.php 복제
      • 입력 창에 기존 내용을 불러오는 코드 추가
      // update.php
      
      ...
      
      $update_link = '';
      if(isset($_GET['id'])) {
      		...
          $update_link = '<a
              href="update.php?id='.$_GET['id'].'">update</a>';
      }
      
      ...
      
      <form action="process_create.php" method="POST">
          <p><input type="text" name="title" placeholder="title"
              value="<?=$article['title']?>"></p>
          <p><textarea name="description"
              placeholder="description"><?=$article['description']?></textarea></p>
          <p><input type="submit"></p>
      </form>
      

    11.1. 활용 - 글 쓰기 1

     

    11.2. 활용 - 글 쓰기 2


    •  update.php
      • input 태그 추가
      // update.php
      
      ...
      
      <form action="process_create.php" method="POST">
          <input type="hidden" name="id" value="<?=$_GET['id']?>">
          ...
      </form>
      

     

    •  process_update.php
      • process_create.php 복제
      • settype()
        • 변수의 자료형 설정
      // process_update.php
      
      ...
      
      settype($_POST['id'], 'integer');
      $filtered = array (
          'id'=>mysqli_real_escape_string($conn, $_POST['id']),
          'title'=>mysqli_real_escape_string($conn, $_POST['title']),
          'description'=>mysqli_real_escape_string($conn, $_POST['description'])
      );
      
      $sql = "
          UPDATE topic
              SET
                  title = '{$filtered['title']}',
                  description = '{$filtered['description']}'
              WHERE
                  id = '{$filtered['id']}'
          )
      ";
      
      ...
      

    11.2. 활용 - 글 쓰기 2

     

    12. 활용 - 글 삭제


    • index.php
      • 삭제 링크 추가(form 태그 이용)
      // index.php
      
      ...
      
      if(isset($_GET['id'])) {
      		...
          $update_link = '<a
              href="update.php?id='.$_GET['id'].'">update</a>';
          $delete_link = '
              <form action="process_delete.php" method="post">
                  <input type="hidden" name="id" value="'.$_GET['id'].'">
                  <input type="submit" value="delete">
              </form>
          ';
      } 
      
      ...
      
      <body>
          ...
          <?=$update_link?>
          <?=$delete_link?>
          <h2><?=$article['title']?></h2>
          <?=$article['description']?>
      </body>
      

     

    •  process_delete.php
      • process_update.php 복사
      • 데이터 삭제를 위한 SQL문 작성
      // process_delete.php
      
      ...
      
      settype($_POST['id'], 'integer');
      $filtered = array (
          'id'=>mysqli_real_escape_string($conn, $_POST['id'])
      );
      
      $sql = "
          DELETE
              FROM topic
              WHERE id = {$filtered['id']}
      ";
      
      ...
      

    12. 활용 - 글 삭제

     

    •  참고
      • GET → 정보를 가져올 때 URL 파라미터를 이용
      • POST → (정보의 수정, 삭제 등) URL을 사용하지 않음
Designed by Tistory.