C-log

⚡PHP select_id : JS&PHP&MySQL 본문

Server/⚡ver0

⚡PHP select_id : JS&PHP&MySQL

4:Bee 2023. 10. 23. 08:28
728x90

앞전에 우리가 작성한 코드에 많은 부족함이 있었다. 우선 전되는 데이터 값을 js에 있는 변수를 통해 동적으로 값이 변하길 원했으나 구현에 있어서 매우 미흡했다. 이를 실험하기 위해서 아주 작게 하나의 스크립트를 작성해 보려고 한다.

우리가 설계할 ERD는 아래와 같다. (ERD가 ERD답지 않다. 스케치 정도로만 봐두자)

Button.php파일을 생성해보자.

Button.php

<?php
echo "CONTACT!";
mysqli_report(MYSQLI_REPORT_OFF);
$conn = mysqli_connect(
  'localhost',
  'root',
  '*****',
  'test'
);
?>

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>send_DATA_button</title>
</head>

<body>
  <h1>Click BUTTON</h1>
  <form action="process_data.php" method="POST">
    <input type="hidden" name="hidden_text" class="hidden_text" placeholder="input text">
    <input type="button" class="newbtn" value="new value">
    <input type="submit" class="btn" value="Click!">
  </form>

  <script src="./data.js"></script>
</body>

</html>

HTML코드에서 body를 보면 input 태그가 세개가 있다. 첫 번째는 숨겨져 있는 input이다. 여기에는 js를 통해서 원하는 값을 변경하고 이를 form 태그의 POST방식으로 값을 process_data.phh로 옮겨지고 process_data.php에선 데이터를 sql로 넘겨지는 과정을 거치게 할 것이다. 여기서 우리가 고려해야하는 것은 js에서 hidden_text의 value값을 변경하는 코드를 단순하게 작성해서 값이 전달 되지 않는다 그 이유는 btn을 클릭함과 동시에 form태그와 함께 동기화가 되면서 데이터가 처리된다. 결국에는 hidden_text의 value값이 저장되지 않고 데이터가 처리가 되기 때문에 ajax와 같은 비동기 처리 과정이 필요하다. 우선 js를 통해서 hidden_text를 잘 찾아내고 있는지 확인하기 위한 스크립트는 아래와 같다.

data.js

let button = document.querySelector(".btn");
let hidden_text = document.querySelector(".hidden_text");//hidden_text는 현재 type이 숨겨져 있기 때문에 보이지 않는다.
let new_Btn = document.querySelector(".newbtn"); //btn클릭시 hidden_text의 value 값이 변동

new_Btn.addEventListener("click", () => {
  console.log("Before : " + hidden_text.value);
  hidden_text.value = "test"
  console.log("After : " + hidden_text.value);
})

구조는 정말 간단하고 가장 기본적인 구성으로 만들었다. 클릭을 했을 때 웹브라우저에서 log값이 찍히면 잘 찾았다는 것이다. ajax를 사용하기 전에 간다하게 ajax를 살펴보자.

더보기

ajax는 비동기 방식을 사용할 수 있는 API이다. 아래 코드를 통해서 하나 하나 설명 하겠다.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <article>

  </article>
  <input type="button" value="fetch" onclick="

    fetch('css').then(function(response){
      response.text().then(function(text){
        // alert(text);
        document.querySelector('article').innerHTML = text;
      })
    })
 ">
</body>

</html>

 fetch('css').then(function(response)

fetch의 매개변수에 따라서 가져오는 데이터가 다르다 참고로 현재 fetch는 우리가 method 속성을 변경하지 않았기 때문에 기본적으로 GET 타입인 것이다. 즉, css라는 데이터를 가져오겠다는 의미이다.

 response.text().then(function(text)

그렇게 css의 데이터파일을 resonse로 받아오고 .text 함수로 해당 작성된 글로 진입하고 그걸 text로 다음 then에서 받는다.

 alert(text);& document.querySelector('article').innerHTML = text;

text 변수에는 css의 response의 text의 text를 alert로 호출 하는 것이다. 이 방식을 이용해서 article에 text를 삽입하는 방법으로 구성 해본 것이다.

여기까지 우리는 다른 데이터의, 페이지의 데이터를 가지고 와서 이것들을 spa와 같은 동적 페이지로 구성하고 있다. 이것은 서버와는 어떠한 연결이 되어 있는지 구체적으로 배워볼 필요가 있다.

위의 방식을 이용해서 쉽게 이해하기 위해서 좀 더 직관적인 비동기 방식의 코드를 작성해 보았다.

function callbackme(){console.log('response')} 
    fetch('html').then(callbackme); 
    console.log(1);
    console.log(2);

 fetch가 html에 접속, 응답을 받고 그때(then) callbackme함수를 실행 시켜주라는 뜻 결과적으로 1,2의 값이 먼저 출력되고 그것들이 끝나고 난다음에 해당 callbackme 함수가 콜백된다. 위의 fetch가 실행되는 것을 확인 하는 방법은 개발자 창을 통해서 확인 할 수 있다. 개발자도구에서 NetWork에 들어가서 fetch버튼을 눌렀을 때 html을 200이라는 status로 정상접속이 되었다는 것을 알 수 있다.

ajax를 살펴 보았으니 ajax로 데이터 정보를 php로 전달 해보자. 이전 html코드를 좀 더 간단하게 버튼하나만 존재 할 수 있게 바꿀 것이다 거기에 더해서 random한 숫자만 나오는 것이 아니라 배열로 정해둔 특정 단어가 random함수를 통해 반환되는 값으로 배열 index의 값도 함께 동적으로 저장될 수 있게 변경할 것이다. 변경이 필요한 body태그만 살펴 보자.

<body>
  <h1>Click BUTTON</h1>
  <form action="process_data.php" method="POST">
    <!-- js에서 해당 언어를 찾고 값을 정의하고 process_data.php 로 값을 전달한다.-->
    <!-- hidden type의 value는 값이 없다. 여기서 우리는 먼저 값을 부여한 뒤에 클릭이 이루어져야 한다. -->
    <input type="hidden" name="hidden_text" class="hidden_text">
    <input type="hidden" name="hidden_num" class="hidden_num">
    <input type="submit" class="btn" value="Click!">
  </form>

  <script src="./data.js"></script>
</body>

이제 여기에 맞는 data.js 코드를 작성할 것이다. 해당 js코드는 아래와 같다.

let hidden_text = document.querySelector(".hidden_text");//hidden_text는 현재 type이 숨겨져 있기 때문에 보이지 않는다.
let hidden_num = document.querySelector(".hidden_num");
let btn = document.querySelector(".btn");

let random = Math.floor(Math.random() * 10);
let random_text = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
let addBtn = () => btn.addEventListener("click", () => {
  hidden_text.value = random_text[random];
  hidden_num.value = random;
  console.log("After : " + hidden_text.value);
})
// fetch가 없으면 실행이 안된다.
fetch('button.php').then(()=>addBtn());

우리가 새로 추가한 hidden_text와 hidden_num을 document로 찾아서 버튼을 눌렀을 때 이벤트가 발생할 수 있게 화살표기 함수(arrow funtion)로 value프로퍼티 값을 변경해 준다. 이때 우리는 비동기를 통해서 서버에 값을 전달하는 데이터의 값을 변환해야한다. 

다시 말해서 document.querySelector()를 통해서 가져온 값은 HTML을 js 파일을 통해서 조작(control)하는 것 일뿐 서버로 전달되는 데이터 값을 변경하는 것이 아니다. fetch를 통해서 button.php를 서버로부터 응답 요청을 처리하는 것이다. 다시말해서 서버로부터 feth(button.php)요청이 완료된 후에 then에서 addBtn()함수를 실행함으로 form을 수정하는 것이다. 이후 form에서 데이터를 POST방식으로 데이터를 process_data.php로 제출 되는 것이다. 

여기까지 들으면 굉장히 혼란 스럽고 혼동이 될 것이다. 조금 더 직관적으로 묘사해서 설명하자면 js에서 사용된 document.query-등과 같은 방식의 변수들로 값을 변경하는 것들은(js를 통한 클라이언트와 상호작용 하는 모든 코드를 말하는 것이다.)클라이언트와의 소통을 위한 코드일 뿐이다. 즉, c언어와 같이 순차적인 프로세스에 익숙한 나머지 fetch 또한 클라인트와의 소통을 위한 코드라 생각하여 Event처리 함수가 끝나고 fetch가 수행이 된다고 착각을 하는 것이다. 아니면 fetch가 없이 Event를 처리하는 코드가 있기 때문에 form태 내부에서 알아서 value와 같은 값들이 알아서 처리해줄 것이라고 생각하고 착각하는 것이다.(한 번 다시 생각해보라. HTML이야 말로 순차적인 작업을 하는데 script가 가장 아래에 존재한다. 당연히 코드가 script를 찍고 다시 거슬로 올라가 form태그 내부에서 값이 자동으로 처리될리가 없다.) 결론적으로 우리는 addBtn()함수는 단순히 데이터 처리를 하기 이전의 부속품과도 같다. (이렇게 표현하는 것이 맞는진 잘 모르겠다.) 그래서 Promise가 있는 것이고 그래서 then이라는 뜻이 '그때'인 것이다. 그렇게 우리는 객체라는 것에 한걸음 더 다가가 이 코드를 새로운 시선으로 바라 보아야 하는 것이다. 아래 코드는 위 글에 걸맞게 코드를 어떻게 나눠 봐야하는지 주석으로 처리한 것이다.

//================ 서버와 데이터 처리를 위한 소스/부품 ===================================
let hidden_text = document.querySelector(".hidden_text");
let hidden_num = document.querySelector(".hidden_num");
let btn = document.querySelector(".btn");

let random = Math.floor(Math.random() * 10);
let random_text = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
let addBtn = () => btn.addEventListener("click", () => {
  hidden_text.value = random_text[random];
  hidden_num.value = random;
  console.log("After : " + hidden_text.value);
})

// ===================실제 서버와 데이터 처리=========================================================
fetch('button.php').then(() => addBtn());

빠르게 MySQL 작성을 보고 porcess_data.php코드를 살펴보자

데이터를 저장할 sql 스키마의 table은 아래 코드와 같다.

MariaDB [test]> CREATE TABLE btndata(id INT(11) NOT NULL AUTO_INCREMENT,num INT(11) NOT NULL,text VARCHAR(100) NULL,시간 DATETIME NOT NULL,PRIMARY KEY(id));
Query OK, 0 rows affected (0.188 sec)

MariaDB [test]> DESC  btndata;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| num   | int(11)      | NO   |     | NULL    |                |
| text  | varchar(100) | YES  |     | NULL    |                |
| 시간  | datetime     | NO   |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
4 rows in set (0.025 sec)

이렇게 준비가 되어 있는 table을 process_data.js에서 INSERT 하는 처리과정 코드를 살펴보자. 아래 코드를 참고하자.

process_data.php

<?php
echo "CONTACT!";
mysqli_report(MYSQLI_REPORT_OFF);
$conn = mysqli_connect(
  'localhost',
  'root',
  '******',
  'test'
);

$filtered = array(
  'num' => mysqli_real_escape_string($conn, $_POST['hidden_num']),
  'text' => mysqli_real_escape_string($conn, $_POST['hidden_text'])
);

$sql = "
INSERT INTO btndata(num,text,시간)
VALUES(
  '{$filtered['num']}',
  '{$filtered['text']}',
  NOW()
)
";
$result = mysqli_query($conn, $sql);

if ($result === false) {
  echo '저장하는 과정에서 문제가 생겼습니다. 관리자에게 문의해주세요.';
  echo mysqli_error($conn);
  error_log(mysqli_error($conn));
} else {
  echo '성공했습니다.<a href="button.php">돌아가기</a>';
}

해당 코드에서 우리가 주의 깊게 작성해야하는 것은 filtered이다. 해당 POST된 값을 데이터 서버어서 가져오는 것이 아니라 POST로 보내기 위해서 $_POST인 것이다. 즉, sql에서 데이터 서버에 POST방식으로 데이터를 전송하겠다는 것이다.

이전에 우리가 수업 때 클리이언트와 브라우저 그리고 데이터 서버와의 관계를 주의깊고 유심히 봐야한다는 이유를 여기서 다시 느끼게 되었다.

728x90

'Server > ⚡ver0' 카테고리의 다른 글

⚡PHP API : 날짜 그리고 나의 위치  (0) 2023.10.30
⚡PHP select_id : DATABASE  (0) 2023.10.22
⚡PHP change_id : Ajax  (0) 2023.10.21
⚡PHP change_id  (0) 2023.10.21
⚡PHP로 URL의 id값 가져오기 : GET/POST  (0) 2023.10.18
Comments