9. PHP 홈페이지 만들기 프로그램 글쓰기 2

2014.09.05 15:20
저자 : Kurien


개학으로 인해서 업데이트가 늦어진 점 죄송합니다.

오랜 기간 수정을 못했기 때문에 빠진 점이 있을 수 있는데, 만약 안된다면 댓글에 남겨주시면 바로 수정 해드리겠습니다.


먼저 오늘 할 내용은 글쓰기에서 form을 통해 전송받는 데이터를 데이터베이스에 저장하는 작업을 합니다.

이전에 /write.php에서 전송되는 데이터를 받을 페이지인 writing.php가 필요합니다.

이전에 데이터베이스에 항목을 만들어 놨으므로 그대로 진행하겠습니다.


/writing.php


<?php

require_once "./layout.inc"; // 레이아웃을 include 함

require_once "./db.php";


$base = new Layout; // Layout class 객체를 생성

$base->link='./style.css'; // 임시 스타일 추가


$bn = $_POST['bn'];


if(($bn == 'notice' || $bn == 'programs') && $_SESSION['permit']!=3) // 전에 만들었던 권한 값이 3이 아니라면 접근 불가

{

header("Content-Type: text/html; charset=UTF-8");

echo "<script>alert('접근할 수 없습니다.');location.replace('/');</script>";

exit;

} else if($bn=='notice') // 공지사항 부분

{

$title = $_POST['title'];

$content = $_POST['content'];

$set = $_POST['set'];

if(!(isset($title)&&isset($content)&&isset($set))) // title, content, set 변수가 존재하지 않으면 오류 출력

{

header("Content-Type: text/html; charset=UTF-8");

echo "<script>alert('빈 칸이 존재합니다.');history.back();</script>";

exit;

}


if ($_FILES['userfile']['error']>0) // 파일 업로드에 에러코드(1,2,3,4,6,7)가 0보다 크다면 관련 내용을 출력

{

header("Content-Type: text/html; charset=UTF-8");

switch ($_FILES['userfile']['error'])

{

case 1:

echo "<script>alert('파일의 크기가 최대 업로드 크기를 넘었습니다.');history.back()</script>";

break;

case 2:

echo "<script>alert('파일의 크기가 최대 파일 크기를 넘었습니다.');history.back()</script>";

break;

case 3:

echo "<script>alert('파일이 불완전하게 업로드 되었습니다.');history.back()</script>";

break;

case 4:

echo "<script>alert('파일이 업로드 되지 않았습니다.');history.back()</script>";

break;

case 6:

echo "<script>alert('파일을 업로드 할 수 없습니다.');history.back()</script>";

break;

case 7:

echo "<script>alert('업로드에 실패하였습니다.');history.back()</script>";

break;

}

exit;

}

if ($_FILES['userfile']['type'] !='image/jpeg' && $_FILES['userfile']['type'] !='image/png')

// 이미지 확장자가 jpeg혹은 png가 아니라면 오류 출력

{

header("Content-Type: text/html; charset=UTF-8");

echo "<script>alert('JPG 혹은 PNG 파일만 업로드 가능합니다.');history.back()</script>";

exit;

}


$upfile = './images/'.$_FILES['userfile']['name']; // upfile 변수에 ./images/파일명으로 저장

if (is_uploaded_file($_FILES['userfile']['tmp_name']))

// 임시 저장 공간에 자료가 있다면 임시 공간에서 $upfile의 경로로 자료 이동을 해보고 실패하면 오류 출력

{

if (!move_uploaded_file($_FILES['userfile']['tmp_name'], $upfile))

{

header("Content-Type: text/html; charset=UTF-8");

echo "<script>alert('파일을 업로드 하지 못했습니다.');history.back()</script>";

exit;

}

} else //자료가 없다면 오류 출력

{

header("Content-Type: text/html; charset=UTF-8");

echo "<script>alert('파일 업로드 공격의 가능성이 있습니다. 파일명 : ".$_FILES['userfile']['name']."');history.back()</script>";

exit;

}


$db = new DBC;

$db->DBI();


// query로 세션 값과 id, permit 부분이 멤버 테이블에 존재하는지 확인

$db->query = "select id, pass, permit from member where id='".$_SESSION['id']."' and permit=".$_SESSION['permit'];

$db->DBQ();

$pass = $db->result->fetch_row();

// query로 데이터를 삽입

$db->query = "insert into ".$bn." values (null, '".$_SESSION['id']."', '".$pass[1]."', '".date('Y-m-d')."', '".date('H:i:s')."', '".$title."', '".$content."', ".$set.", '".$upfile."', 0)";


$db->DBQ();

if(!$db->result) // DB에 전송이 실패하면 오류 출력, 성공하면 메시지 출력

{

echo "<script>alert('DB 전송에 실패했습니다.')</script>";

} else

{

echo "<script>alert('글이 정상적으로 업로드 되었습니다.');location.replace('/".$bn."')</script>";

}

$db->DBO();


}


else if($bn=='programs') // 프로그램 부분

{


// 프로그램 부분에 필요한 각각의 변수를 만들어줍니다.

$category = $_POST['category'];

$os = $_POST['os1']." ".$_POST['os2']." ".$_POST['os3']." ".$_POST['os4']." ".$_POST['os5']." ".$_POST['os6']." ".$_POST['os7'];

$kr = $_POST['kr'];

$link = $_POST['link'];

$title = $_POST['title'];

$content = $_POST['content'];

$licence = $_POST['licence'];


if(!(isset($category) && isset($os) && isset($kr) && isset($link) && isset($title) && isset($content) && isset($licence) && isset($_FILES['userfile']['name']))) // 비어있는 변수가 있다면 오류를 출력

{

header("Content-Type: text/html; charset=UTF-8");

echo "<script>alert('빈 칸이 존재합니다.');history.back();</script>";

exit;

}


if ($_FILES['userfile']['error']>0) // 파일 업로드에 에러코드(1,2,3,4,6,7)가 0보다 크다면 관련 내용을 출력

{

header("Content-Type: text/html; charset=UTF-8");

switch ($_FILES['userfile']['error'])

{

case 1:

echo "<script>alert('파일의 크기가 최대 업로드 크기를 넘었습니다.');history.back()</script>";

break;

case 2:

echo "<script>alert('파일의 크기가 최대 파일 크기를 넘었습니다.');history.back()</script>";

break;

case 3:

echo "<script>alert('파일이 불완전하게 업로드 되었습니다.');history.back()</script>";

break;

case 4:

echo "<script>alert('파일이 업로드 되지 않았습니다.');history.back()</script>";

break;

case 6:

echo "<script>alert('파일을 업로드 할 수 없습니다.');history.back()</script>";

break;

case 7:

echo "<script>alert('업로드에 실패하였습니다.');history.back()</script>";

break;

}

exit;

}

if ($_FILES['userfile']['type'] !='image/jpeg' && $_FILES['userfile']['type'] !='image/png')

// 이미지 확장자가 jpeg혹은 png가 아니라면 오류 출력

{

header("Content-Type: text/html; charset=UTF-8");

echo "<script>alert('JPG 혹은 PNG 파일만 업로드 가능합니다.');history.back()</script>";

exit;

}


$upfile = './images/'.$_FILES['userfile']['name']; // upfile 변수에 ./images/파일명으로 저장

if (is_uploaded_file($_FILES['userfile']['tmp_name']))

{

if (!move_uploaded_file($_FILES['userfile']['tmp_name'], $upfile))

// 임시 저장 공간에 자료가 있다면 임시 공간에서 $upfile의 경로로 자료 이동을 해보고 실패하면 오류 출력

{

header("Content-Type: text/html; charset=UTF-8");

echo "<script>alert('파일을 업로드 하지 못했습니다.');history.back()</script>";

exit;

}

} else //자료가 없다면 오류 출력

{

header("Content-Type: text/html; charset=UTF-8");

echo "<script>alert('파일 업로드 공격의 가능성이 있습니다. 파일명 : ".$_FILES['userfile']['name']."');history.back()</script>";

exit;

}


$db = new DBC;

$db->DBI();

// query로 세션 값과 id, permit 부분이 멤버 테이블에 존재하는지 확인

$db->query = "select id, pass, permit from member where id='".$_SESSION['id']."' and permit=".$_SESSION['permit'];

$db->DBQ();

$pass = $db->result->fetch_row();

// query로 데이터를 삽입

$db->query = "insert into ".$bn." values(null, '".$_SESSION['id']."', '".$pass[1]."', '".date('Y-m-d')."', '".date('H:i:s')."', '".$category."', '".$title."', '".$content."', '".$link."', '".$os."', '".$kr."', '".$upfile."', ".$licence.")";

$db->DBQ();

if(!$db->result) // DB에 전송이 실패하면 오류 출력, 성공하면 메시지 출력

{

echo "<script>alert('DB 전송에 실패했습니다.')</script>";

} else

{

echo "<script>alert('글이 정상적으로 업로드 되었습니다.');location.replace('/".$bn."')</script>";

}

$db->DBO();

}


$base->LayoutMain(); //위의 변수들이 입력된 객체를 출력

?>


무지하게 기네요.

이 부분을 만들 때 공지사항 부분도 만들어버려서 이렇게 길게 되었습니다...

아마 코드를 더 짧게 할 수도 있긴 할텐데 아직은 제작단계이므로 이대로 하겠습니다.


먼저 빨간색으로 칠해진 부분은 공지사항, 파란색으로 칠해진 부분은 프로그램 메뉴구요.

사이사이에 주석으로 설명을 해뒀으니 크게 어려우시진 않을거라고 생각합니다.


writing.php의 역할은 write.php에서 넘어온 데이터를 데이터베이스로 저장하는 것 입니다.

프로그램 부분만 필요하므로 공통 부분과 프로그램 부분만 설명하자면, 먼저 맨 위의 검은색으로 적혀있는 부분은 공통입니다.


레이아웃을 만들고, $bn이라는 변수에 게시판의 이름을 저장합니다.

프로그램 메뉴는 programs가 되겠죠?


그 다음 $bn의 값에 따라서 notice 혹은 programs로 넘어가게 됩니다.

여기서 지금 볼 부분은 programs입니다.

사실 위나 아래나 크게 다른 부분은 없습니다.

몇 가지 입력이 더 있을 뿐이죠.


먼저 category, os, kr, link, title, content, licence라는 변수를 만들고, write에서 넘어온 자료를 넣어줍니다.

그 다음 if문을 이용해서 위의 변수에 자료가 없는 것이 있다면 오류를 발생시킵니다.


아래 있는 $_FILE이라는 것은 <input type='file' name='userfile' id='userfile'/>를 통해서 넘어온 데이터를 말하는데,

여기서는 name이 userfile이므로 $_FILE['userfile']으로 자료가 넘어옵니다.


$_FILE['userfile']['error']는 만약 파일이 넘어오는 것이 실패했을 때 0보다 큰 값이 넘어오게 되고, 

1, 2, 3, 4, 6, 7 에 맞는 결과 값이 오류로 출력됩니다.

만약 오류가 나지 않으면 다음으로 넘어가는거죠.


다음은 $_FILES['userfile']['type']인데, 이건 $_FILES['userfile']의 확장자를 말합니다.

위에 있는 코드에서는 image/jpeg 혹은 image/png가 아닌 다른 확장자를 사용하는 파일을 업로드 하게 되면,

오류를 출력하고 이전페이지로 되돌아갑니다.


$upfile = './images/'.$_FILES['userfile']['name']; 이 부분은 단순히 $upfile이라는 변수에 경로/파일이름.확장자를 넣어주는 것입니다.

아래 있는 코드에서 사용하려고 하는건데, is_uploaded_file()는 업로드 된 파일을 검사하고, 

그 하위에 있는 if문에 존재하는 move_uploaded_file()은 업로드 된 파일을 임시 폴더에서 $upfile의 경로로 옮겨줍니다.


지금 까지 한건 자료를 검사하고 오류를 출력하는 것 이였다면, 이번에는 검사를 마친 자료를 데이터 베이스로 이동해야합니다.


query를 사용해서 member 테이블에 존재하는 현재 로그인이 된 아이디의 세션을 가지고 id, pass, permit을 찾습니다.

그리고 나온 결과 값을 $pass에 저장하구요.

$pass[1]에는 pass 값이 들어있으니 데이터를 가지고 insert를 해줍니다.


insert를 끝냈는데 데이터베이스에 정상적으로 등록이 되면 메시지를 출력하고, 등록 되지 않았을 경우 오류를 출력합니다.





여기까지 프로그램 메뉴에 글을 쓰는 부분을 알아봤는데요,

글쓰기 1과 2의 사이에 공백기간이 길었던 것과, 이미 웹에서는 구현을 해놨기 때문에 어느 부분을 수정했는지 정확히 알 수가 없습니다 ㅠ


혹시라도 사용하시던 도중 정상적으로 작동하지 않게 되면 꼭! 댓글에 남겨 알려주세요!

그래야 글도 수정이 가능합니다!


사이트에서 직접 보고싶으신 분은 http://kurien.speeds.kr 로 접속하시면 보실 수 있습니다.