
PHP ๊ฐ์
>PHP - ์ค๊ธ
๐ PHP ์ค๊ธ - 4์ฃผ์ฐจ: ํ์ผ ์ ๋ก๋ ๋ฐ ์ด๋ฏธ์ง ์ฒ๋ฆฌ - 01 HTML ํผ์ ์ด์ฉํ ํ์ผ ์ ๋ก๋
![]() |
ํ์ | 10.0 | ๋ผ์ด์ผ์ค | free |
---|---|---|---|---|
์ฌ์ฉ์ํ์ | 10.0 | ์ด์์ฒด์ | ||
๋ค์ด๋ก๋ | 1 | ํ์ผํฌ๊ธฐ | 0 | |
์ ์์ฌ | LUZENSOFT | ๋ฑ๋ก์ผ | 2025-07-24 15:13:35 | |
์กฐํ์ | 9 |
๐ PHP ์ค๊ธ - 4์ฃผ์ฐจ: ํ์ผ ์ ๋ก๋ ๋ฐ ์ด๋ฏธ์ง ์ฒ๋ฆฌ - 01 HTML ํผ์ ์ด์ฉํ ํ์ผ ์ ๋ก๋
์๋ ํ์ธ์! #PHP ์ค๊ธ ๊ณผ์ 4์ฃผ์ฐจ์ ๋๋ค. ์ค๋์ #์น_์ ํ๋ฆฌ์ผ์ด์ ์์ ๊ฐ์ฅ ํํ๊ฒ ์ ํ๋ ๊ธฐ๋ฅ ์ค ํ๋์ธ #ํ์ผ_์ ๋ก๋(File Upload)์ ๋ํด ์์ธํ ์์๋ณด๊ฒ ์ต๋๋ค. ํนํ ์ฌ์ฉ์๊ฐ #HTML #ํผ(Form)์ ํตํด ํ์ผ์ ์๋ฒ๋ก ์ ์กํ๋ ๊ธฐ๋ณธ์ ์ธ ๊ณผ์ ์ ๋ค๋ฃฐ ๊ฑฐ์์. #๊ฒ์ํ์ #์ด๋ฏธ์ง๋ฅผ ์ฒจ๋ถํ๊ฑฐ๋ #ํ๋กํ_์ฌ์ง์ ๋ณ๊ฒฝํ๋ ๋ฑ ๋ค์ํ ๊ณณ์ ํ์ฉ๋ ์ ์๋ ์ค์ํ ๊ธฐ๋ฅ์ด๋ ํจ๊ป ์ดํด๋ณผ๊น์?
1. ํ์ผ ์ ๋ก๋์ ๊ฐ์ ๋ฐ ๋ณด์ ๊ณ ๋ ค์ฌํญ
#ํ์ผ_์ ๋ก๋๋ ์ฌ์ฉ์์ ๋ก์ปฌ #PC์ ์๋ #ํ์ผ์ #์น_์๋ฒ๋ก ์ ์กํ๋ ๊ณผ์ ์ ๋๋ค. ์ด ๊ณผ์ ์ ๋จ์ํ ํ์ผ์ ์ฎ๊ธฐ๋ ๊ฒ์ ๋์ด, #๋ณด์(Security)์ ๋ํ ๊น์ ์ดํด๋ฅผ ์๊ตฌํฉ๋๋ค. ์ ์์ ์ธ ์ฌ์ฉ์๊ฐ #์น_์ ธ(Web Shell)์ด๋ #๋ฐ์ด๋ฌ์ค(Virus)๋ฅผ ํฌํจํ #์ ์ฑ_ํ์ผ์ ์ ๋ก๋ํ์ฌ #์๋ฒ๋ฅผ_๊ณต๊ฒฉํ ์ ์๊ธฐ ๋๋ฌธ์ด์ฃ .
๋ฐ๋ผ์ #ํ์ผ_์ ๋ก๋ ๊ธฐ๋ฅ์ ๊ตฌํํ ๋๋ ๋ค์๊ณผ ๊ฐ์ #๋ณด์_๊ณ ๋ ค์ฌํญ์ ๋ฐ๋์ ์ง์ผ์ผ ํฉ๋๋ค.
#ํ์ฅ์_๊ฒ์ฌ: ์ ๋ก๋ ๊ฐ๋ฅํ #ํ์ผ_ํ์์ ์๊ฒฉํ๊ฒ ์ ํํด์ผ ํฉ๋๋ค. (์:
.jpg
,.png
,.gif
๋ง ํ์ฉ)#MIME_ํ์ _๊ฒ์ฌ: #HTTP_ํค๋์ ํฌํจ๋ #MIME_ํ์ ์ ๋ณด๋ ํ์ธํ์ฌ #ํ์ฅ์_์๋ณ์กฐ๋ฅผ ๋ง์์ผ ํฉ๋๋ค.
#ํ์ผ_ํฌ๊ธฐ_์ ํ: ๋๋ฌด ํฐ ํ์ผ ์ ๋ก๋๋ฅผ ๋ง์ #์๋ฒ_๊ณผ๋ถํ(Server Overload)๋ #์๋น์ค_๊ฑฐ๋ถ_๊ณต๊ฒฉ(DoS Attack)์ ๋ฐฉ์งํฉ๋๋ค.
#ํ์ผ_์ด๋ฆ_๋ณ๊ฒฝ: ์ ๋ก๋๋ ํ์ผ ์ด๋ฆ์ ๋ฌด์์ ๋ฌธ์์ด๋ก ๋ณ๊ฒฝํ์ฌ #๊ฒฝ๋ก_ํ์_๊ณต๊ฒฉ(Path Traversal Attack)์ด๋ #ํ์ผ_๋ฎ์ด์ฐ๊ธฐ๋ฅผ ๋ฐฉ์งํฉ๋๋ค.
#์ ๋ก๋_๋๋ ํฐ๋ฆฌ_๋ถ๋ฆฌ: ์น์์ ์ง์ ์ ๊ทผํ ์ ์๋ ๋ณ๋์ #๋๋ ํฐ๋ฆฌ์ ์ ์ฅํ๊ณ , ํ์์ #์คํฌ๋ฆฝํธ๋ฅผ ํตํด ์ ๊ทผํ๊ฒ ํฉ๋๋ค.
#์น_์๋ฒ_์ค์ _๊ฐํ: #PHP ์ค์ (
php.ini
)์์ #ํ์ผ_์ ๋ก๋ ๊ด๋ จ ์ ํ(upload_max_filesize
,post_max_size
๋ฑ)์ ์ ์ ํ ์ค์ ํฉ๋๋ค.
2. HTML ํผ(Form) ์ค์
#ํ์ผ_์ ๋ก๋๋ฅผ ์ํ #HTML #ํผ์ ์ผ๋ฐ์ ์ธ ํผ๊ณผ ๋ช ๊ฐ์ง ์ค์ํ ์ฐจ์ด์ ์ด ์์ต๋๋ค.
2-1. enctype="multipart/form-data"
#ํ์ผ_์
๋ก๋ ํผ์์ ๊ฐ์ฅ ์ค์ํ ์์ฑ์
๋๋ค. ์ด ์์ฑ์ด ์์ผ๋ฉด ํ์ผ ๋ฐ์ดํฐ๊ฐ ์๋ฒ๋ก ์ ๋๋ก ์ ์ก๋์ง ์์ต๋๋ค. #multipart/form-data
๋ ํผ ๋ฐ์ดํฐ์ ํ์ผ ๋ฐ์ดํฐ๋ฅผ ํจ๊ป ์ ์กํ ์ ์๋๋ก ์ธ์ฝ๋ฉํ๋ ๋ฐฉ์์
๋๋ค.
2-2. method="POST"
#ํ์ผ_๋ฐ์ดํฐ๋ #URL์ ํฌํจ๋ ์ ์์ผ๋ฏ๋ก, ๋ฐ๋์ #POST_๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
2-3. <input type="file" name="file_upload">
#ํ์ผ_์ ํ_ํ๋๋ฅผ ์์ฑํฉ๋๋ค. name
์์ฑ์ PHP์์ ํ์ผ์ ๋ฐ์ ๋ ์ฌ์ฉ๋ #๋ณ์_์ด๋ฆ์ด ๋ฉ๋๋ค. ์ฌ๋ฌ ํ์ผ์ ํ ๋ฒ์ ์
๋ก๋ํ๋ ค๋ฉด multiple
์์ฑ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
upload_form.html
์์:
HTML
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ํ์ผ ์
๋ก๋ ํผ</title>
<style>
body { font-family: Arial, sans-serif; margin: 50px; }
form { background-color: #f9f9f9; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); width: 400px; margin: auto; }
h2 { text-align: center; color: #333; }
label { display: block; margin-bottom: 8px; font-weight: bold; }
input[type="file"] { margin-bottom: 15px; border: 1px solid #ddd; padding: 8px; border-radius: 4px; background-color: #fff; width: calc(100% - 18px); }
input[type="submit"] { background-color: #007bff; color: white; padding: 10px 15px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; width: 100%; }
input[type="submit"]:hover { background-color: #0056b3; }
</style>
</head>
<body>
<h2>ํ์ผ ์
๋ก๋</h2>
<form action="upload_process.php" method="POST" enctype="multipart/form-data">
<label for="my_file">์
๋ก๋ํ ํ์ผ ์ ํ:</label>
<input type="file" name="my_file" id="my_file" required>
<input type="submit" value="ํ์ผ ์
๋ก๋">
</form>
</body>
</html>
3. PHP์์ ํ์ผ ์ ๋ก๋ ์ฒ๋ฆฌ
#PHP๋ ์
๋ก๋๋ #ํ์ผ_๋ฐ์ดํฐ๋ฅผ ์ ์ญ ๋ณ์์ธ #$_FILES
๋ฅผ ํตํด ์ ๊ทผํ ์ ์๊ฒ ํฉ๋๋ค. ์ด #$_FILES
๋ฐฐ์ด์ ์
๋ก๋๋ ๊ฐ ํ์ผ์ ๋ํ ์ ๋ณด๋ฅผ ๋ด๊ณ ์์ต๋๋ค.
$_FILES
๋ฐฐ์ด์ ๊ตฌ์กฐ
$_FILES['input_name']
์ ๋ค์๊ณผ ๊ฐ์ ์ ๋ณด๋ฅผ ํฌํจํฉ๋๋ค. (์ฌ๊ธฐ์ input_name
์ HTML input type="file"
์ name
์์ฑ ๊ฐ์
๋๋ค.)
name
: ํด๋ผ์ด์ธํธ #PC์ ์๋ #์๋ณธ_ํ์ผ_์ด๋ฆtype
: ํ์ผ์ #MIME_ํ์ (์:image/jpeg
,text/plain
)tmp_name
: #์๋ฒ์_์์๋ก_์ ์ฅ๋_ํ์ผ์_๊ฒฝ๋ก์_์ด๋ฆerror
: #ํ์ผ_์ ๋ก๋_์_๋ฐ์ํ_์ค๋ฅ_์ฝ๋ (#UPLOAD_ERR_OK
๋ ์ค๋ฅ ์์์ ์๋ฏธ)size
: ์ ๋ก๋๋ #ํ์ผ์_ํฌ๊ธฐ(๋ฐ์ดํธ ๋จ์)
ํ์ผ ์ ๋ก๋ ์ฒ๋ฆฌ ๋ก์ง (PHP)
upload_process.php
ํ์ผ์์ ์ค์ ํ์ผ ์
๋ก๋ ์ฒ๋ฆฌ ๋ฐ #๋ณด์_๊ฒ์ฌ๋ฅผ ์ํํฉ๋๋ค.
PHP
<?php
// upload_process.php
// 1. ์
๋ก๋ ๋๋ ํ ๋ฆฌ ์ค์ (๋ฐ๋์ ์น ์ ๊ทผ ๋ถ๊ฐ๋ฅํ ์์ ๊ฒฝ๋ก์ ๋๋ ๊ฒ์ด ๋ณด์์ ์ข์)
$upload_dir = './uploads/'; // ํ์ฌ ์คํฌ๋ฆฝํธ๊ฐ ์๋ ํด๋ ํ์์ 'uploads' ํด๋
// 'uploads' ํด๋๊ฐ ์์ผ๋ฉด ์์ฑ (๊ถํ 0755)
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0755, true);
}
// 2. ํ์ผ ์
๋ก๋ ์ค๋ฅ ํ์ธ
// UPLOAD_ERR_OK: ํ์ผ ์
๋ก๋ ์ฑ๊ณต
if (!isset($_FILES['my_file']) || $_FILES['my_file']['error'] !== UPLOAD_ERR_OK) {
switch ($_FILES['my_file']['error']) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
echo "์
๋ก๋ ํ์ผ ํฌ๊ธฐ๊ฐ PHP ์ค์ ๋๋ ํผ์์ ํ์ฉ๋ ์ต๋ ํฌ๊ธฐ๋ฅผ ์ด๊ณผํ์ต๋๋ค.";
break;
case UPLOAD_ERR_NO_FILE:
echo "ํ์ผ์ด ์
๋ก๋๋์ง ์์์ต๋๋ค.";
break;
default:
echo "ํ์ผ ์
๋ก๋ ์ค ์ ์ ์๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. ์ค๋ฅ ์ฝ๋: " . $_FILES['my_file']['error'];
break;
}
exit;
}
// 3. ์
๋ก๋๋ ํ์ผ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
$file_name = $_FILES['my_file']['name']; // ์๋ณธ ํ์ผ ์ด๋ฆ
$file_type = $_FILES['my_file']['type']; // MIME ํ์
$file_tmp_name = $_FILES['my_file']['tmp_name']; // ์์ ํ์ผ ๊ฒฝ๋ก
$file_size = $_FILES['my_file']['size']; // ํ์ผ ํฌ๊ธฐ
// 4. ๋ณด์ ๊ฒ์ฌ (๋งค์ฐ ์ค์!)
// 4-1. ํ์ผ ํฌ๊ธฐ ์ ํ (์: 5MB)
$max_file_size = 5 * 1024 * 1024; // 5MB
if ($file_size > $max_file_size) {
echo "ํ์ผ ํฌ๊ธฐ๊ฐ ๋๋ฌด ํฝ๋๋ค. (์ต๋ 5MB)";
exit;
}
// 4-2. ํ์ฉ๋ ํ์ผ ํ์ฅ์ ๋ฐ MIME ํ์
์ค์
$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf'];
$allowed_mime_types = ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'];
// ํ์ผ ํ์ฅ์ ์ถ์ถ ๋ฐ ์๋ฌธ์๋ก ๋ณํ
$file_ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
// MIME ํ์
๊ฒ์ฌ ($_FILES['type']์ ํด๋ผ์ด์ธํธ์์ ์ ๊ณตํ๋ฏ๋ก ์์กฐ ๊ฐ๋ฅ์ฑ ์์)
// ์ค์ ํ์ผ์ MIME ํ์
์ ๊ฒ์ฌํ๋ ๋ฐฉ๋ฒ์ด ๋ ์์ ํ๋, ์ฌ๊ธฐ์๋ ๊ธฐ๋ณธ์ ์ธ ๊ฒ์ฌ๋ง ํฌํจ
if (!in_array($file_ext, $allowed_extensions) || !in_array($file_type, $allowed_mime_types)) {
echo "ํ์ฉ๋์ง ์๋ ํ์ผ ํ์์
๋๋ค. (ํ์ฉ: JPG, JPEG, PNG, GIF, PDF)";
exit;
}
// 5. ํ์ผ ์ด๋ฆ ๋ณ๊ฒฝ (๋ณด์์ ์ํด ํ์)
// ์ ๋ํฌํ ํ์ผ ์ด๋ฆ ์์ฑ (์: ํ์ฌ ์๊ฐ์ ๊ธฐ๋ฐ + ์๋ณธ ํ์ฅ์)
$new_file_name = uniqid() . '.' . $file_ext;
$destination = $upload_dir . $new_file_name; // ์ ์ฅ๋ ์ต์ข
๊ฒฝ๋ก
// 6. ์์ ํ์ผ์ ์ต์ข
๋ชฉ์ ์ง๋ก ์ด๋
// move_uploaded_file() ํจ์๋ ์
๋ก๋๋ ์์ ํ์ผ์ ์์ ํ๊ฒ ์ด๋์ํต๋๋ค.
if (move_uploaded_file($file_tmp_name, $destination)) {
echo "ํ์ผ์ด ์ฑ๊ณต์ ์ผ๋ก ์
๋ก๋๋์์ต๋๋ค.<br>";
echo "์ ์ฅ๋ ํ์ผ๋ช
: " . htmlspecialchars($new_file_name) . "<br>";
echo "ํ์ผ ๊ฒฝ๋ก: " . htmlspecialchars($destination) . "<br>";
echo "<img src='" . htmlspecialchars($destination) . "' alt='์
๋ก๋๋ ์ด๋ฏธ์ง' style='max-width:300px;'>";
} else {
echo "ํ์ผ ์
๋ก๋์ ์คํจํ์ต๋๋ค.";
}
?>
4. PHP ์ค์ (php.ini
) ํ์ธ
#PHP์ #php.ini
์ค์ ํ์ผ์๋ #ํ์ผ_์
๋ก๋์ ๊ด๋ จ๋ ์ค์ํ ์ง์์ด๋ค์ด ์์ต๋๋ค.
file_uploads = On
: ํ์ผ ์ ๋ก๋ ๊ธฐ๋ฅ์ ํ์ฑํํฉ๋๋ค. (๊ธฐ๋ณธ๊ฐ On)upload_max_filesize = 2M
: ๊ฐ๋ณ ํ์ผ ์ ๋ก๋์ ์ต๋ ํฌ๊ธฐ๋ฅผ ์ค์ ํฉ๋๋ค. (์:2M
์ 2๋ฉ๊ฐ๋ฐ์ดํธ)post_max_size = 8M
: #POST_์์ฒญ์ผ๋ก ์ ์ก๋ ์ ์๋ ์ ์ฒด ๋ฐ์ดํฐ์ ์ต๋ ํฌ๊ธฐ๋ฅผ ์ค์ ํฉ๋๋ค. (upload_max_filesize
๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์์ผ ํฉ๋๋ค.)upload_tmp_dir =
: ์ ๋ก๋๋ ํ์ผ์ด ์์๋ก ์ ์ฅ๋ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ง์ ํฉ๋๋ค. (์ค์ ํ์ง ์์ผ๋ฉด ์์คํ ๊ธฐ๋ณธ ์์ ๋๋ ํฐ๋ฆฌ ์ฌ์ฉ)max_file_uploads = 20
: ํ ๋ฒ์ ์์ฒญ์ผ๋ก ์ ๋ก๋ํ ์ ์๋ ์ต๋ ํ์ผ ๊ฐ์์ ๋๋ค.
์ด ๊ฐ๋ค์ ์น ์๋ฒ์ ์๊ตฌ์ฌํญ๊ณผ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์์ ๋ง๊ฒ ์กฐ์ ํด์ผ ํฉ๋๋ค. ๋ณ๊ฒฝ ํ์๋ #์น_์๋ฒ(Apache, Nginx ๋ฑ)๋ฅผ #์ฌ์์ํด์ผ ์ ์ฉ๋ฉ๋๋ค.
์ค๋์ #HTML #ํผ์ ์ด์ฉํ #ํ์ผ_์ ๋ก๋์ ๊ธฐ๋ณธ์ ์ธ ๊ตฌํ ๋ฐฉ๋ฒ๊ณผ #๋ณด์_๊ณ ๋ ค์ฌํญ์ ๋ํด ์์๋ณด์์ต๋๋ค.