Menu

PHP $_GET과 $_POST: 쿼리 문자열과 폼 데이터 읽기

$_GET은 URL의 쿼리 문자열을 담고(?page=2는 $_GET['page']를 줍니다) $_POST는 method="post"로 보낸 폼의 필드를 담습니다. 둘을 안전하게 읽는 방법, http_build_query로 링크 만들기, $_SERVER['REQUEST_METHOD'] 확인, GET과 POST 중 고르는 방법을 알아봅니다.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

$_GET은 URL 쿼리 문자열의 배열이므로 article.php?id=42&lang=en은 $_GET['id'] === '42'와 $_GET['lang'] === 'en'을 줍니다. $_POST는 method="post"로 보낸 폼 필드의 배열입니다. 파라미터가 없으면 키도 없으므로 둘 다 기본값과 함께 읽으세요: $_GET['id'] ?? null.

블록을 실행한 다음 링크를 클릭하세요. 클릭할 때마다 링크의 쿼리 문자열로 채워진 $_GET과 함께 스크립트가 다시 실행됩니다.

$_GET['lang']은 출력한 세 링크만이 아니라 URL에 적힌 무엇이든 될 수 있습니다. 누구나 주소창에 ?lang=<script>를 입력할 수 있으며, 그래서 이 블록은 값을 출력하는 대신 $languages에서 찾고, 요청 데이터를 출력하는 유일한 곳은 이스케이프합니다.

쿼리 문자열에서 숫자 읽기

$_GET의 모든 값은 문자열입니다. 페이지 번호라면 filter_var()로 검증과 변환을 한 번에 하고, 값이 없거나 숫자가 아니거나 범위를 벗어나면 기본값으로 돌아가세요. 페이지를 넘겨 본 다음 Page 999와 Page abc 링크를 시도해 보세요.

filter_var()는 "3"에 대해 정수 3을, 그 밖의 문자열에 대해 default 옵션을 반환하므로 $page는 항상 쓸 수 있는 int입니다. 다른 검증기는 filter_var 페이지에 나열되어 있습니다.

$_POST로 폼 데이터 읽기

method="post"인 폼은 필드를 요청 본문으로 보내고, PHP는 각 입력의 name 아래 $_POST에 넣습니다. $_SERVER['REQUEST_METHOD']는 현재 요청이 첫 방문(GET)인지 전송(POST)인지 알려 줍니다. 폼을 채우고 Send를 눌러 둘 다 확인하세요.

빈 텍스트 입력도 ""로 전송되므로, 전송 후에는 방문자가 아무것도 입력하지 않았어도 $_POST['title']이 존재합니다. 서버에서는 REQUEST_METHOD가 항상 설정되어 있고, ?? 'GET'은 명령줄에서 php로 파일을 실행할 때 스크립트를 조용히 유지할 뿐입니다. 폼을 검증하고 다시 표시하는 전체 패턴은 폼 페이지에 있습니다.

method="get"인 검색 폼

결과가 공유 가능한 URL이어야 하는 폼, 예를 들어 검색창에는 GET을 쓰세요. 브라우저가 필드를 쿼리 문자열(?q=sort&level=beginner)로 바꾸고, 스크립트는 링크와 똑같이 $_GET에서 읽습니다. array나 string을 검색해 보세요.

http_build_query로 링크 만들기

"?q=$q&page=2"를 손으로 쓰면 $q에 공백, &, #이 들어가는 순간 깨집니다. http_build_query()는 모든 값을 인코딩해 주며, HTML 안에서 &는 &amp;여야 하므로 결과가 href에 들어갈 때는 htmlspecialchars()를 거칩니다.

두 인수를 받는 parse_str()은 PHP가 쿼리 문자열로 $_GET을 만드는 방법이므로 테스트에 편리합니다. 항상 두 번째 인수를 넘기세요. 변수를 만들던 예전의 인수 하나짜리 형태는 PHP 8에서 제거되었습니다.

$_REQUEST와 피해야 하는 이유

$_REQUEST는 $_GET과 $_POST를 한 배열로 합친 것입니다. PHP가 제공하는 php.ini 파일은 request_order = "GP"를 설정하므로 둘에 같은 키가 있으면 POST가 이깁니다. 그 설정이 없으면 쿠키도 합쳐집니다.

<?php
// POST /save.php?id=1 with a form field id=2
echo $_GET['id'];      // "1"
echo $_POST['id'];     // "2"
echo $_REQUEST['id'];  // "2"

편리해 보이지만 값이 어디서 왔는지 숨깁니다. $_REQUEST['id']로 레코드를 지우는 핸들러는 평범한 링크로도 실행될 수 있으며, 이는 POST 전용 동작이 막으려는 바로 그것입니다. 대신 $_GET이나 $_POST를 이름으로 읽으세요.

GET과 POST: 무엇을 쓸까

GETPOST
데이터가 이동하는 곳URL 안: ?q=php&page=2요청 본문 안
읽는 방법$_GET$_POST
북마크, 공유, 뒤로 가기가능불가(브라우저가 재전송을 묻습니다)
길이URL에 의해 제한(수천 자는 안전)post_max_size에 의해 제한(기본 8M)
파일 업로드불가가능, enctype="multipart/form-data"와 함께($_FILES를 읽음)
용도검색, 필터, 정렬, 페이지 나누기로그인, 가입, 저장, 삭제, 결제

중요한 규칙: GET 요청은 아무것도 바꾸면 안 됩니다. 브라우저는 링크를 미리 불러오고, 크롤러는 링크를 따라가며, 사람들은 링크를 공유하므로 ?delete=5 링크는 결국 지울 의도가 없던 무언가에 의해 열리게 됩니다. 두 방식 모두 그 자체로 암호화되지는 않습니다. HTTPS가 둘 다 보호하며, POST는 데이터를 URL, 브라우저 기록, 서버 로그에 남기지 않을 뿐입니다.

자주 묻는 질문

PHP에서 URL의 파라미터를 가져오려면 어떻게 하나요?

기본값과 함께 $_GET에서 읽으세요. page.php?id=42라면 $id = $_GET['id'] ?? null;이 문자열 "42"를 줍니다. 모든 값은 문자열(또는 id[]=의 경우 배열)이므로, 예를 들어 filter_var($id, FILTER_VALIDATE_INT)로 변환하고 검증하세요.

$_GET과 $_POST의 차이는 무엇인가요?

$_GET은 URL의 쿼리 문자열에서 오므로 보이고, 북마크할 수 있고, 길이가 제한됩니다. 검색, 필터, 페이지에 쓰세요. $_POST는 method="post"로 보낸 폼의 요청 본문에서 옵니다. 저장, 구매, 로그인처럼 데이터를 바꾸는 모든 것에 쓰세요.

PHP에서 GET 파라미터가 있는지 확인하려면 어떻게 하나요?

isset($_GET['q'])를 쓰세요. 키가 없거나 null이면 거짓입니다. 빈 값(?q=)도 없는 것으로 치려면 trim한 값을 비교하세요: trim($_GET['q'] ?? '') !== ''.

PHP에서 $_REQUEST를 써야 하나요?

대개는 아닙니다. $_REQUEST는 $_GET과 $_POST(그리고 request_order에 따라 쿠키)를 합치므로 값이 어디서 왔는지 알 수 없고, 폼에서 기대한 값을 링크가 공급할 수 있습니다. $_GET이나 $_POST를 명시적으로 읽으세요.

PHP에서 요청이 GET인지 POST인지 확인하려면 어떻게 하나요?

$_SERVER['REQUEST_METHOD']를 비교하세요: if ($_SERVER['REQUEST_METHOD'] === 'POST') { ... }. 버튼에 name이 없거나 JavaScript나 다른 스크립트가 그 필드 없이 폼을 보낼 때 실패하는 isset($_POST['submit'])보다 더 믿을 만합니다.

Coddy 프로그래밍 언어 일러스트

Coddy로 코딩 배우기

시작하기