PHP Superglobals
PHP 슈퍼글로벌(Superglobals): 완벽한 사용법과 예제 가이드
PHP 슈퍼글로벌(Superglobals)이란 무엇인가요?
PHP에서 **슈퍼글로벌(Superglobals)**은 모든 스코프에서 언제나 접근 가능한 특별한 변수들입니다. 이 변수들은 PHP 스크립트 내 어디에서든지 사용할 수 있으며, 주로 폼 데이터, 세션 데이터, 쿠키, 서버 정보 등을 다루는 데 사용됩니다. 슈퍼글로벌을 활용하면 사용자 입력을 처리하고, 서버와의 상호작용을 용이하게 할 수 있습니다. 이 가이드에서는 PHP 슈퍼글로벌의 개념부터 각 슈퍼글로벌의 사용법, 보안 고려사항, 그리고 실용적인 예제까지 상세히 설명하겠습니다.
1. PHP 슈퍼글로벌의 개요
- *슈퍼글로벌(Superglobals)**은 PHP에서 미리 정의된 변수들로, 전역(Global) 스코프에서 자동으로 접근할 수 있습니다. 이들은 특별한 배열 형태로 제공되며, 주로 다음과 같은 용도로 사용됩니다:
- 사용자 입력 처리: 폼 데이터, URL 매개변수 등
- 세션 관리: 사용자 세션 데이터 저장 및 접근
- 쿠키 관리: 사용자 쿠키 데이터 저장 및 접근
- 서버 정보: 서버 환경 및 요청 정보 접근
- 파일 업로드: 사용자로부터 업로드된 파일 정보 접근
슈퍼글로벌은 PHP 스크립트 어디서든지 사용할 수 있으므로, 데이터의 전달과 처리가 매우 편리합니다.
2. 주요 PHP 슈퍼글로벌
PHP에는 여러 종류의 슈퍼글로벌 변수가 있으며, 각각 특정한 목적을 가지고 있습니다. 주요 슈퍼글로벌은 다음과 같습니다:
$_GET
$_POST
$_REQUEST
$_SERVER
$_SESSION
$_COOKIE
$_FILES
$_ENV
$GLOBALS
각 슈퍼글로벌의 역할과 사용법을 자세히 살펴보겠습니다.
3. PHP 슈퍼글로벌 상세 설명과 예제
3.1 $_GET
- *
$_GET
*은 URL을 통해 전달된 데이터를 담고 있는 슈퍼글로벌입니다. 주로 URL의 쿼리 문자열에서 데이터를 수신할 때 사용됩니다.
사용 예제:
<?php
// URL: <http://example.com/page.php?id=10&name=홍길동>
$id = $_GET['id'];
$name = $_GET['name'];
echo "ID: $id<br>"; // 출력: ID: 10
echo "이름: $name<br>"; // 출력: 이름: 홍길동
?>
설명:
- URL의 쿼리 문자열(
?id=10&name=홍길동
)에서id
와name
값을 추출하여 변수에 저장합니다. $_GET
은 데이터가 노출되므로, 민감한 정보를 전달할 때는 주의가 필요합니다.
3.2 $_POST
- *
$_POST
*는 HTTP POST 요청을 통해 전달된 데이터를 담고 있는 슈퍼글로벌입니다. 주로 폼 데이터를 서버로 전송할 때 사용됩니다.
사용 예제:
<?php
// form.html
/*
<form action="process.php" method="post">
이름: <input type="text" name="name">
<input type="submit" value="제출">
</form>
*/
?>
<?php
// process.php
$name = $_POST['name'];
echo "안녕하세요, $name님!";
?>
설명:
- 사용자가
form.html
에서 이름을 입력하고 제출하면,process.php
에서$_POST['name']
을 통해 입력된 이름을 받아 출력합니다. $_POST
는 데이터가 URL에 노출되지 않으므로, 민감한 정보를 전송할 때 더 안전합니다.
3.3 $_REQUEST
- *
$_REQUEST
*는$_GET
,$_POST
,$_COOKIE
등의 데이터를 모두 포함하는 슈퍼글로벌입니다. 다양한 소스에서 데이터를 수신할 때 유용하지만, 보안상 주의가 필요합니다.
사용 예제:
<?php
// URL: <http://example.com/page.php?id=10>
// POST 요청으로 name=홍길동 전송
$id = $_REQUEST['id'];
$name = $_REQUEST['name'];
echo "ID: $id<br>"; // 출력: ID: 10
echo "이름: $name<br>"; // 출력: 이름: 홍길동
?>
설명:
$_REQUEST
는$_GET
,$_POST
,$_COOKIE
의 데이터를 모두 포함하므로, 데이터의 출처를 명확히 구분하기 어려울 수 있습니다.- 보안상 특정 슈퍼글로벌을 명시적으로 사용하는 것이 권장됩니다.
3.4 $_SERVER
- *
$_SERVER
*는 서버 및 실행 환경에 대한 정보를 담고 있는 슈퍼글로벌입니다. HTTP 요청, 서버 정보, 실행 중인 스크립트 경로 등을 포함합니다.
사용 예제:
<?php
echo "현재 스크립트 경로: " . $_SERVER['PHP_SELF'] . "<br>";
echo "서버 이름: " . $_SERVER['SERVER_NAME'] . "<br>";
echo "클라이언트 IP: " . $_SERVER['REMOTE_ADDR'] . "<br>";
?>
설명:
$_SERVER['PHP_SELF']
: 현재 실행 중인 스크립트의 경로를 반환합니다.$_SERVER['SERVER_NAME']
: 서버의 호스트 이름을 반환합니다.$_SERVER['REMOTE_ADDR']
: 클라이언트의 IP 주소를 반환합니다.
3.5 $_SESSION
- *
$_SESSION
*은 사용자 세션 데이터를 저장하고 접근할 수 있는 슈퍼글로벌입니다. 세션은 사용자가 웹사이트를 방문하는 동안 데이터를 유지하는 데 사용됩니다.
사용 예제:
<?php
// session_start()는 세션을 시작하거나 기존 세션을 재개합니다.
session_start();
// 세션 변수 설정
$_SESSION['username'] = "홍길동";
$_SESSION['email'] = "hong@example.com";
// 세션 변수 접근
echo "사용자명: " . $_SESSION['username'] . "<br>";
echo "이메일: " . $_SESSION['email'] . "<br>";
?>
설명:
session_start()
함수를 호출하여 세션을 시작해야$_SESSION
을 사용할 수 있습니다.- 세션 데이터는 서버에 저장되며, 사용자가 브라우저를 닫을 때까지 유지됩니다.
3.6 $_COOKIE
- *
$_COOKIE
*는 클라이언트에 저장된 쿠키 데이터를 담고 있는 슈퍼글로벌입니다. 쿠키는 사용자의 브라우저에 작은 데이터를 저장하여, 다음 방문 시 해당 데이터를 사용할 수 있게 합니다.
사용 예제:
<?php
// 쿠키 설정: 이름, 값, 만료 시간
setcookie("user", "홍길동", time() + (86400 * 30), "/"); // 30일 동안 유효
// 쿠키 접근
if(isset($_COOKIE['user'])) {
echo "환영합니다, " . $_COOKIE['user'] . "님!";
} else {
echo "환영합니다, 게스트님!";
}
?>
설명:
setcookie()
함수를 사용하여 쿠키를 설정합니다. 쿠키는 HTTP 응답 헤더를 통해 클라이언트에 전송됩니다.- 쿠키는 사용자가 브라우저를 닫거나, 쿠키의 만료 시간이 지나면 삭제됩니다.
3.7 $_FILES
- *
$_FILES
*는 사용자로부터 업로드된 파일 정보를 담고 있는 슈퍼글로벌입니다. 파일 업로드를 처리할 때 사용됩니다.
사용 예제:
<?php
// form.html
/*
<form action="upload.php" method="post" enctype="multipart/form-data">
파일 선택: <input type="file" name="uploadedFile">
<input type="submit" value="업로드">
</form>
*/
?>
<?php
// upload.php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_FILES['uploadedFile'])) {
$file = $_FILES['uploadedFile'];
// 파일 정보 출력
echo "파일 이름: " . $file['name'] . "<br>";
echo "파일 유형: " . $file['type'] . "<br>";
echo "파일 크기: " . $file['size'] . " bytes<br>";
echo "파일 임시 위치: " . $file['tmp_name'] . "<br>";
// 파일 이동
$destination = "uploads/" . basename($file['name']);
if (move_uploaded_file($file['tmp_name'], $destination)) {
echo "파일이 성공적으로 업로드되었습니다.";
} else {
echo "파일 업로드에 실패했습니다.";
}
}
}
?>
설명:
- HTML 폼에서
enctype="multipart/form-data"
를 설정하여 파일 업로드를 가능하게 합니다. $_FILES['uploadedFile']
을 통해 업로드된 파일의 정보를 접근하고,move_uploaded_file()
함수를 사용하여 파일을 원하는 위치로 이동시킵니다.
3.8 $_ENV
- *
$_ENV
*는 환경 변수를 담고 있는 슈퍼글로벌입니다. 서버 환경 설정, 시스템 변수 등을 포함합니다.
사용 예제:
<?php
// 환경 변수 접근
echo "홈 디렉토리: " . $_ENV['HOME'] . "<br>";
echo "PATH: " . $_ENV['PATH'] . "<br>";
?>
설명:
$_ENV
는 서버 환경에 따라 포함된 변수들이 다를 수 있으며, PHP 설정에 따라 제한될 수 있습니다.- 환경 변수는 주로 시스템 수준의 정보를 제공하며, 보안상 중요한 정보를 포함할 수 있으므로 신중하게 다뤄야 합니다.
3.9 $GLOBALS
- *
$GLOBALS
*는 모든 글로벌 변수를 포함하는 슈퍼글로벌입니다. 함수나 클래스 내부에서도 글로벌 변수에 접근할 수 있게 합니다.
사용 예제:
<?php
$globalVar = "전역 변수";
function test() {
echo $GLOBALS['globalVar']; // 출력: 전역 변수
}
test();
?>
설명:
$GLOBALS
배열을 통해 모든 글로벌 변수에 접근할 수 있습니다.- 글로벌 변수를 사용하는 것은 코드의 예측 가능성을 떨어뜨릴 수 있으므로, 필요한 경우에만 신중하게 사용해야 합니다.
4. PHP 슈퍼글로벌 보안 고려사항
슈퍼글로벌을 사용할 때는 특히 사용자 입력을 처리할 경우 보안에 유의해야 합니다. 다음은 주요 보안 고려사항입니다:
4.1 입력값 검증 및 필터링
사용자로부터 입력받은 데이터는 신뢰할 수 없으므로, 반드시 검증하고 필터링해야 합니다.
예제:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 필터링 및 검증
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false) {
echo "유효하지 않은 이메일 주소입니다.";
} else {
echo "안녕하세요, $name님! 이메일: $email";
}
}
?>
설명:
filter_input()
함수를 사용하여 입력 데이터를 필터링하고 검증합니다.FILTER_SANITIZE_STRING
과FILTER_VALIDATE_EMAIL
을 사용하여 문자열과 이메일을 각각 처리합니다.
4.2 SQL 인젝션 방지
사용자 입력을 데이터베이스 쿼리에 사용할 때는 **준비된 문장(Prepared Statements)**을 사용하여 SQL 인젝션 공격을 방지해야 합니다.
예제:
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "testdb";
// 데이터베이스 연결
$conn = new mysqli($servername, $username, $password, $dbname);
// 연결 확인
if ($conn->connect_error) {
die("연결 실패: " . $conn->connect_error);
}
// 사용자 입력 받기
$user_input = $_POST['username'];
$pass_input = $_POST['password'];
// 준비된 문장 사용
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $user_input, $pass_input);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
echo "로그인 성공!";
} else {
echo "로그인 실패: 사용자명 또는 비밀번호가 올바르지 않습니다.";
}
$stmt->close();
$conn->close();
?>
설명:
prepare()
와bind_param()
을 사용하여 쿼리를 준비하고, 사용자 입력을 안전하게 바인딩합니다.- 이렇게 하면 SQL 인젝션 공격을 효과적으로 방지할 수 있습니다.
4.3 XSS 방지
사용자 입력을 HTML에 출력할 때는 HTML 이스케이프를 통해 XSS(교차 사이트 스크립팅) 공격을 방지해야 합니다.
예제:
<?php
$comments = [
["user" => "홍길동", "comment" => "<script>alert('XSS');</script>"],
["user" => "김철수", "comment" => "안녕하세요!"]
];
foreach ($comments as $comment) {
$safe_user = htmlspecialchars($comment['user'], ENT_QUOTES, 'UTF-8');
$safe_comment = htmlspecialchars($comment['comment'], ENT_QUOTES, 'UTF-8');
echo "사용자: $safe_user, 댓글: $safe_comment<br>";
}
?>
설명:
htmlspecialchars()
함수를 사용하여 특수 문자를 HTML 엔티티로 변환함으로써 스크립트 실행을 방지합니다.
5. PHP 슈퍼글로벌 Best Practices
PHP 슈퍼글로벌을 효과적으로 사용하기 위한 몇 가지 베스트 프랙티스를 소개합니다.
5.1 특정 슈퍼글로벌 사용
데이터의 출처를 명확히 하기 위해 $_GET
, $_POST
등 특정 슈퍼글로벌을 명시적으로 사용하는 것이 좋습니다. $_REQUEST
는
다양한 소스의 데이터를 포함하므로, 보안상 위험할 수 있습니다.
비권장:
<?php
// 데이터 출처가 불분명
$name = $_REQUEST['name'];
?>
권장:
<?php
// POST 데이터 사용 명시
$name = $_POST['name'];
?>
5.2 입력 데이터 검증 및 필터링
사용자 입력은 항상 검증하고 필터링하여 신뢰할 수 없음을 가정해야 합니다.
예제:
<?php
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT);
if ($age === false) {
echo "유효하지 않은 나이입니다.";
} else {
echo "이름: $name, 나이: $age";
}
?>
5.3 $_SESSION
사용 시 보안 강화
세션 하이재킹 등을 방지하기 위해 세션 관리에 주의해야 합니다.
베스트 프랙티스:
-
세션 시작 전에 세션 쿠키 설정: 보안 설정(
secure
,httponly
)을 강화합니다.<?php session_set_cookie_params([ 'lifetime' => 0, 'path' => '/', 'domain' => 'example.com', 'secure' => true, // HTTPS에서만 전송 'httponly' => true, // JavaScript 접근 금지 'samesite' => 'Strict' // CSRF 방지 ]); session_start(); ?>
-
세션 ID 재생성: 로그인 후 세션 ID를 재생성하여 세션 고정 공격을 방지합니다.
<?php // 로그인 성공 시 session_regenerate_id(true); ?>
5.4 쿠키 보안 강화
쿠키를 설정할 때 보안 옵션을 강화하여 쿠키 탈취를 방지합니다.
예제:
<?php
// 보안 쿠키 설정
setcookie("user", "홍길동", [
'expires' => time() + (86400 * 30), // 30일
'path' => '/',
'domain' => 'example.com',
'secure' => true, // HTTPS에서만 전송
'httponly' => true, // JavaScript 접근 금지
'samesite' => 'Strict' // CSRF 방지
]);
?>
5.5 $_FILES
처리 시 파일 검증
파일 업로드 시 파일 타입, 크기 등을 철저히 검증하여 악성 파일 업로드를 방지합니다.
예제:
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_FILES['uploadedFile'])) {
$file = $_FILES['uploadedFile'];
// 파일 크기 제한 (예: 2MB)
if ($file['size'] > 2 * 1024 * 1024) {
die("파일 크기가 너무 큽니다.");
}
// 파일 유형 검증
$allowed_types = ['image/jpeg', 'image/png', 'image/gif'];
if (!in_array($file['type'], $allowed_types)) {
die("허용되지 않은 파일 유형입니다.");
}
// 파일 이동
$destination = "uploads/" . basename($file['name']);
if (move_uploaded_file($file['tmp_name'], $destination)) {
echo "파일이 성공적으로 업로드되었습니다.";
} else {
echo "파일 업로드에 실패했습니다.";
}
}
}
?>
6. PHP 8.0 이상의 슈퍼글로벌 관련 새로운 기능
PHP 8.0부터 슈퍼글로벌과 관련된 몇 가지 새로운 기능과 개선 사항이 도입되었습니다.
6.1 Named Arguments (명명된 인자)과 슈퍼글로벌
명명된 인자를 사용하면 함수 호출 시 매개변수의 순서를 무시하고 원하는 인자만 전달할 수 있습니다. 이는 슈퍼글로벌과 결합하여 보다 유연한 함수 호출을 가능하게 합니다.
예제:
<?php
function processData($name, $email, $age) {
echo "이름: $name, 이메일: $email, 나이: $age<br>";
}
// 슈퍼글로벌 데이터를 명명된 인자로 전달
processData(
name: $_POST['name'],
email: $_POST['email'],
age: $_POST['age']
);
?>
6.2 Union Types (유니온 타입)과 슈퍼글로벌
함수의 매개변수나 반환값에 여러 타입을 지정할 수 있는 유니온 타입을 활용하여 슈퍼글로벌 데이터를 보다 유연하게 처리할 수 있습니다.
예제:
<?php
function getInput(array|string $input): void {
if (is_array($input)) {
foreach ($input as $item) {
echo "아이템: $item<br>";
}
} else {
echo "아이템: $input<br>";
}
}
// 배열 데이터 전달
getInput($_GET['items'] ?? ['기본값']);
// 단일 문자열 데이터 전달
getInput($_GET['name'] ?? '손님');
?>
6.3 Array Unpacking (배열 펼치기)
PHP 8.0부터 배열 펼치기 연산자(...
)를 사용하여 배열을 다른 배열에 쉽게 병합할 수 있습니다. 이를 통해 슈퍼글로벌 배열을 효율적으로 결합할 수 있습니다.
예제:
<?php
$defaults = [
'host' => 'localhost',
'port' => 3306,
'user' => 'root',
'password' => ''
];
$connectionParams = [
...$defaults,
'password' => 'secret', // 덮어쓰기
'database' => 'testdb'
];
print_r($connectionParams);
/* 출력:
Array
(
[host] => localhost
[port] => 3306
[user] => root
[password] => secret
[database] => testdb
)
*/
?>
7. PHP 슈퍼글로벌 요약
PHP 슈퍼글로벌은 웹 애플리케이션 개발에서 필수적인 도구로, 사용자 입력, 서버 정보, 세션 관리 등 다양한 용도로 사용됩니다. 슈퍼글로벌을 효과적으로 사용하기 위해서는 각 슈퍼글로벌의 특성과 보안 고려사항을 이해하고, 베스트 프랙티스를 준수하는 것이 중요합니다. PHP 8.0 이상의 새로운 기능을 활용하면 슈퍼글로벌을 더욱 유연하고 효율적으로 사용할 수 있습니다.
8. 추가 자료 및 참고 링크
- PHP 공식 문서: 슈퍼글로벌
- PHP 공식 문서: $_GET
- PHP 공식 문서: $_POST
- PHP 공식 문서: $_SESSION
- PHP 공식 문서: $_COOKIE
- PHP 공식 문서: $_FILES
- PHP.net: 보안 관련 슈퍼글로벌 사용
이 가이드를 통해 PHP 슈퍼글로벌의 기본 개념부터 각 슈퍼글로벌의 상세 사용법, 보안 고려사항, 그리고 실용적인 예제까지 종합적으로 이해할 수 있기를 바랍니다. PHP 슈퍼글로벌을 효과적으로 활용하여 더욱 안전하고 강력한 웹 애플리케이션을 개발해보세요.