-
(기능추가4-3) 작성자 테이블 구축, 양식초기화, select 태그프로젝트/프로젝트_사진첩 2023. 9. 9. 20:21
전체소스코드
index.php
<?php$conn=mysqli_connect("localhost:81","root","mysql","project_memories");
$sql = "SELECT * FROM who";$result = mysqli_query($conn, $sql);$select_form = '<select id="select" name="creater"><option disabled selected>누구야?</option>';//option기본값을 disabled된(false값) 값으로 selected(기본값으로 설정) 함으로써 사용자가 이미지만 업로드하여 제출되는 일이 없도록 만듬while($row = mysqli_fetch_array($result)){$select_form .= '<option value="'.$row['id'].'">'.$row['creater'].'</option>';}$select_form .= '</select>'; //select 태그를 추가하여 이미지 업로드시 작성자를 표시함?>
<!DOCTYPE html><html lang="ko"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Memories</title><link href="https://fonts.googleapis.com/css2?family=Dancing+Script:wght@700&family=Nanum+Gothic&display=swap" rel="stylesheet">//구글 웹폰트로 나눔고딕 추가<link href="style_index.css" rel="stylesheet"><script>function autoSubmit() {var form = document.getElementById('uploadForm');form.submit();}</script></head>
<body><div class="layout"><div class="titleBox"><div class="titleName">Memories</div><form id="uploadForm" action="" method="POST" enctype="multipart/form-data"><input type="hidden" name="upload" value="1"><label class="uploadBotton" for="uploadInput">+</label><input type="file" id="uploadInput" style="display:none" name="image" onchange="autoSubmit()"><?=$select_form?></form></div>
<?phpsession_start(); //session에 대한 설명은 아랫쪽에서 참고.
if(isset($_POST['upload'])) {$file = addslashes(file_get_contents($_FILES["image"]["tmp_name"]));$filtered_id = mysqli_real_escape_string($conn, $_POST['creater']);$sql = "insert into image (image,created,who_id) values('$file',NOW(),'$filtered_id')";//image테이블에 who_id칼럼을 추가하여 누가 작성하였는지 알수잇도록 함if(mysqli_query($conn, $sql)){$_SESSION['message'] = "헤헤 고맙따!";header("Location: ".$_SERVER['PHP_SELF']);exit(); //작성후 리다이렉트함으로써 POST로 제출된 값이 초기화되도록 함.}else{$_SESSION['message'] = "밍..실패했어오!";header("Location: ".$_SERVER['PHP_SELF']);exit();}}
if(isset($_SESSION['message'])) {echo '<script type="text/javascript"> alert("' . $_SESSION['message'] . '"); </script>';unset($_SESSION['message']);}
$sql = "select * from image order by id desc limit 18";$result = mysqli_query($conn, $sql);?>
<div id="photoLayout" class="photoLayout"><?phpwhile($row = mysqli_fetch_array($result)){echo '<div class="photo"><a href="image_display230906.php?id='.$row['id'].'"><img class="img" src="data:image;base64,'.base64_encode($row['image']).'" alt="Image"></a></div>';}?></div><!-- <script>window.onscroll = function() {if((window.innerHeight + Math.ceil(window.scrollY))>= document.body.offsetHeight) {let Newphoto = document.createElement('div');Newphoto.classList.add('photo');document.getElementById('photoLayout').appendChild(Newphoto);}}</script> --></body>
</html>session에 관한 AI의 답변(session 사용 이유 : 이미지 업로드폼 제출전 echo를 사용하니 alert창이 출력되지않았음)
-리다이렉션을 수행하면서 동시에 메시지를 보여주려면, 세션(session)을 이용하는 방법이 있습니다. 세션은 서버 측에서 사용자의 상태 정보를 저장하는 기술로, 웹 브라우저가 종료되기 전까지는 정보가 유지됩니다.
- session_start();: PHP에서 세션을 사용하기 위해서는 반드시 session_start(); 함수를 호출해야 합니다. 이 함수는 현재 세션 ID를 초기화하거나 복원합니다. 이 함수가 호출되면, PHP는 현재 세션 ID와 연관된 서버에 저장된 세션 데이터를 불러옵니다.
- $_SESSION['message'] = "헤헤 고맙따!";: $_SESSION은 PHP의 슈퍼글로벌 변수 중 하나로, 웹 페이지 간에 정보를 공유하는 데 사용됩니다. 여기서 'message'라는 키에 메시지 문자열을 저장하고 있습니다.
- header("Location: ".$_SERVER['PHP_SELF']);: 이 코드는 현재 페이지로 리다이렉트합니다. 이 때, 서버에 저장된 세션 데이터도 유지됩니다.
- exit();: 리다이렉트 후에 추가적인 코드 실행을 막기 위해 스크립트를 종료합니다.
- if(isset($_SESSION['message'])) {...}: 새로운 페이지가 로드되면, 우리가 설정한 'message'라는 키의 값이 있는지 확인합니다.
- 'alert("' . $_SESSION['message'] . '");': JavaScript alert 창으로 메시지를 출력합니다.
7.unset($_SESSION['message']);: 한 번 메시지가 출력되면 그 값을 삭제하여 다음 새로고침에서 같은 메시지가 또 출력되지 않게 합니다.
8.세션이란 클라이언트(웹 브라우저)와 서버 간의 연결 상태를 유지하는 기술입니다. HTTP 프로토콜은 상태 정보(stateless)를 기억하지 않으므로, 사용자나 클라이언트의 상태 정보를 알아야 하는 경우 (로그인 정보 등), 그 정보들을 일정 시간 동안 유지할 필요가 있습니다. 세션이 활용되면서 웹 사이트에서 사용자 인증 및 개인화 등 다양한 기능을 제공할 수 있게 되었습니다.
양식제출을 초기화하기 위한 코드에 대한 설명
웹 페이지에서 form 제출 후 새로고침을 하면 이전에 제출했던 양식이 다시 제출되는 문제를 해결하려면, 일반적으로 'Post/Redirect/Get' (PRG) 패턴을 사용합니다.
PHP에서는 header() 함수를 사용하여 리다이렉션을 수행할 수 있습니다. 이를 통해, form 데이터가 서버로 전송된 후에 페이지를 다른 위치로 리다이렉트하여 새로고침 시 데이터가 중복으로 전송되는 것을 방지할 수 있습니다.
여기서 주의해야 할 점은 header() 함수는 HTTP 헤더 정보를 수정하기 때문에, 이 함수 호출 전에 어떠한 출력도 발생하면 안된다는 것입니다. 즉, echo, print 등의 출력문 또는 HTML 코드 등이 미리 실행되어서는 안됩니다.(session을 사용한 이유)
아래 코드에서 확인할 수 있듯이 form 제출 성공 후에 페이지를 자신 자신($_SERVER['PHP_SELF'])으로 리다이렉트합니다:
display_image.php
<?php$conn=mysqli_connect("localhost:81","root","password","project_memories");$image_display='';$formatted_date='';if (isset($_GET['id'])){$filtered_id = mysqli_real_escape_string($conn, $_GET['id']);$sql = "SELECT * FROM image LEFT JOIN who ON image.who_id=who.id WHERE image.id={$filtered_id}";//who 테이블을 새로 만들어서 left join을 통해 정규화를 시킴$result = mysqli_query($conn, $sql);$row = mysqli_fetch_array($result);$article = array('created' => htmlspecialchars($row['created']),'image' => $row['image'],'creater' => htmlspecialchars($row['creater']) //'who'의 자리에 누가만들엇는지 넣기 위해 추가);$image_display ='<img src="data:image;base64,'.base64_encode($article['image']).'"alt="Image" style="width: 100%; height: 100%;">';$formatted_date = date("y년 m월 d일", strtotime($article['created']));} else {header("Location: index230906.php"); //id 파라미터가 없는 경우, 보여줄 사진이 없기때문에 홈페이지로 리다이렉트}?><!DOCTYPE html><html lang="ko"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Memories</title><link href="https://fonts.googleapis.com/css2?family=Dancing+Script:wght@700&family=Nanum+Gothic&display=swap" rel="stylesheet"><link href="style_display.css" rel="stylesheet"></head><body><div class="layout"><div class="topLayout"><div class="titleContents" id="who"><?=$article['creater']?></div> //작성자를 DB에서 불러와 표시<div class="titleContents" id="when"><?=$formatted_date?></div><div class="titleContents" id="close"><a href="index230906.php">X</a></div></div><div class="photo"><div class="photoLayout" id="leftLayout"><?=$image_display?></div><div class="photoLayout" id="rightLayout"><div class="chatLayout"></div><div class="chatInputLayout"><!-- <form action="" method="post"><input type="text"><input type="submit"> --></div></div><div></div></body></html>css 추가(select 태그 꾸미기)
#select {color : rgb(156, 156, 156);border : 1px solid rgb(255, 188, 188);padding: 2px 3px;border-radius: 4px;margin-top: 25px;margin-right: 8px;font-family: 'Nanum Gothic', sans-serif;}
#select option {font-family: 'Nanum Gothic', sans-serif;background: rgb(255, 188, 188);color: #fff;padding: 3px 0;}참고) header()를 사용하기전 출력이 발생해서는 안되는 이유 (아직은 이해를 못하겠음)
-header() 함수는 HTTP 헤더를 수정하거나 추가하는 데 사용됩니다. HTTP 헤더는 클라이언트(웹 브라우저)와 서버 간의 요청과 응답에서 메타데이터를 전송하는 데 사용되는 정보입니다.
예를 들어, header("Location: http://www.example.com"); 코드는 웹 브라우저에게 "http://www.example.com" URL로 리다이렉션하라는 지시를 내리며, 이 지시는 HTTP 헤더를 통해 전달됩니다.
HTTP 응답은 크게 두 부분으로 구성됩니다: 헤더(header)와 바디(body).
- 헤더: 응답의 메타데이터(상태 코드, 콘텐츠 유형 등)를 포함합니다.
- 바디: 실제 컨텐츠(HTML 문서, 이미지 파일 등)을 포함합니다.
PHP 스크립트에서 echo, print, 혹은 HTML 출력 등을 수행하면 이들은 HTTP 응답의 바디 부분으로 간주되며, 웹 서버가 클라이언트에게 전송할 준비가 되었다고 판단하여 HTTP 헤더들을 보내기 시작합니다. 따라서 한번 출력이 시작되면 (즉, PHP가 어떠한 내용을 출력하기 시작하면), 그 시점 이후에는 HTTP 헤더 정보를 변경할 수 없습니다. 그래서 header() 함수 호출 전에 어떠한 출력도 발생하지 않아야 하는 것입니다.
세션을 사용하는 것과 직접적인 연관성은 없지만, 세션 ID 같은 정보도 쿠키 형태로 클라이언트에게 보내질 때 HTTP 헤더를 이용하기 때문에 세션을 초기화(session_start()) 할 때도 역시 아무런 출력도 발생하지 않아야 합니다.
느낀점)
-session과 form제출후 초기화하는 방법을 배움. 유용한것을 배운것같아 뿌듯.
-DB가 큰것은 아니지만 테이블을 분리시켜 정규화시켜서 관리하기가 쉬울듯
-select태그에 대해 공부해보면서 실제로 활용할 수 있게 됨.
-검색과 AI를 이용해서 나도 코딩을 할 수 있다는 자신감이 점점 붙기 시작하는 것 같아 좋음.
-점점 만들어가면서 추가하고싶은 기능들이 많아짐.(무한스크롤, 댓글기능, 로그인 기능등을 구현하고싶음)
'프로젝트 > 프로젝트_사진첩' 카테고리의 다른 글
(기능추가4-5) 댓글삭제기능 구현(프론트) (0) 2023.09.13 (기능추가4-4) 댓글기능 구현 (1) 2023.09.12 (기능추가4-2) 상세페이지 내용 DB에서 불러오기 (0) 2023.09.09 (기능추가4-1)상세팝업 레이아웃 구현하기 (0) 2023.09.06 (기능추가5-1) 업로드, 로드기능 구현하기 (0) 2023.09.05