
1. 서론: 웹 통신의 약속, HTTP와 데이터 전송
웹 개발의 세계에 발을 들이면 가장 먼저 마주하는 약속이 있습니다. 바로 **HTTP(HyperText Protocol)**입니다. 10년 넘게 웹 개발을 해오며 느낀 점은, 화려한 프레임워크보다 이 통신 규약을 정확히 이해하는 것이 훨씬 중요하다는 것입니다.
• HTTP의 정의: 클라이언트(브라우저)가 서버에 자원을 요청(Request)하고, 서버가 이에 응답(Response)하는 구조를 정의한 프로토콜입니다.
• 클라이언트/서버 모델: 사용자가 주소를 입력하면 브라우저는 객체를 요청하고, 서버는 규약에 따라 해당 데이터를 전송합니다.
• Stateless(무상태성): HTTP는 본래 서버가 클라이언트의 이전 상태를 기억하지 않는 성질을 가집니다. 이를 보완하기 위해 쿠키(Cookie) 같은 인위적인 값을 활용해 세션을 유지하게 됩니다.
2. HTTP 요청 메시지의 구조 이해
서버로 무언가를 보낼 때, 우리가 만드는 요청 패킷은 네 가지 핵심 요소로 구성됩니다. 시니어 개발자라면 이 구조를 머릿속에 그려낼 수 있어야 합니다.
1. 요청 라인 (Request Line): 사용자가 선택한 HTTP 메서드(GET, POST 등), 요청 URL, 그리고 HTTP 버전 정보가 담깁니다.
2. 요청 헤더 (Request Header): 요청에 대한 부가 정보(Metadata)를 담습니다.
◦ User-Agent: 접속한 브라우저와 운영체제의 상세 정보입니다.
◦ Accept: 서버로부터 받고자 하는 데이터 타입인 MIME 타입을 명시합니다. 예컨대 */*는 모든 형태의 문서를 수용하겠다는 의미입니다.
◦ Cookie: 앞서 언급한 Stateless 특성을 극복하기 위해 로그인 상태 등을 유지하는 데이터입니다.
◦ Referer: 어떤 페이지를 거쳐 현재 페이지로 왔는지 알려주는 경로 정보입니다.
◦ Host: 요청이 전달될 도메인 이름입니다.
3. 공백 라인 (Blank Line): 헤더와 본문을 구분하는 중요한 경계선입니다. 캐리지 리턴(\r)과 라인 피드(\n)로 구성되는데, 실무적으로는 우리가 키보드에서 'Enter' 키를 치는 것과 동일하게 커서를 맨 앞으로 보내고 줄을 바꾸는 역할을 합니다.
4. 메시지 본문 (Body): 실질적인 데이터인 **페이로드(Payload)**가 담기는 곳입니다. POST 방식에서 핵심적인 역할을 수행합니다.
3. GET 방식: 정보를 조회하는 스마트한 방법
GET 방식은 서버에서 리소스를 **조회(Select/Read)**하기 위해 설계된 메서드입니다.
• 조회(Read) 중심: 서버의 데이터나 상태를 변경하지 않고 정보를 가져오는 '읽기' 전용으로 사용됩니다.
• 쿼리 스트링(Query String) 전송: URL 끝에 ?를 붙이고 key=value 쌍으로 데이터를 전달합니다. (예: ?id=joon&age=25)
• 헤더를 통한 노출: 데이터가 URL에 그대로 포함되어 전송되므로 보안이 필요한 정보 전송에는 적합하지 않습니다.
• 캐싱 및 북마크: 브라우저가 요청을 캐시하여 동일 요청 시 서버 부하를 줄일 수 있으며, 특정 검색 결과 페이지 등을 북마크하거나 링크로 공유하기에 최적입니다.
• 길이 제한의 진실: 과거에는 256자 제한이 있었으나 HTTP 1.1 이후 표준상으로는 무제한입니다. 다만, 브라우저 환경에 따라 최대 길이를 제한하며 이를 초과할 경우 데이터가 절단될 위험이 있으므로 주의해야 합니다.
4. POST 방식: 데이터를 생성하고 변경하는 안전한 통로
POST 방식은 서버의 리소스를 **생성(Insert)**하거나 **수정(Update)**하여 서버의 상태를 실질적으로 변화시킬 때 사용합니다.
데이터를 URL이 아닌 HTTP 메시지의 **Body(본문)**에 담아 전송하므로 URL에 노출되지 않는다는 보안적 이점이 있습니다. 또한 대용량 파일이나 텍스트를 전송할 때 데이터 길이 제한 없이 보낼 수 있습니다. 전송 시에는 Content-Type 헤더를 통해 전송하는 데이터의 타입을 명시해야 합니다.
캐싱이 되지 않고 브라우저 히스토리에도 남지 않아 '뒤로 가기' 시 재전송 경고가 뜨는 특징이 있습니다. 명심할 점은, URL에 보이지 않는다고 해서 무조건 안전한 것은 아니라는 것입니다. Wireshark 같은 패킷 분석 도구로 본문을 들여다볼 수 있으므로 민감한 정보는 반드시 암호화해야 합니다.
5. 핵심 비교: GET vs POST 한눈에 보기
두 방식의 결정적 차이는 **멱등성(Idempotent)**에 있습니다. 수학적으로 멱등성이란 **"연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질"**을 뜻합니다. 즉, 가 성립하는가에 대한 문제입니다.
비교 항목GETPOST
|
처리 방식 (CRUD)
|
조회 (Read)
|
생성/수정/삭제 (Create/Update/Delete)
|
|
데이터 위치
|
Header (URL 쿼리 스트링)
|
Body (본문)
|
|
URL 노출
|
노출됨 (O)
|
노출되지 않음 (X)
|
|
캐싱/북마크
|
가능 (O)
|
불가능 (X)
|
|
데이터 길이
|
제한 있음 (초과 시 절단 위험)
|
제한 없음
|
|
멱등성 여부
|
멱등함 (Idempotent)
|
비멱등함 (Non-idempotent)
|
GET은 수백 번 요청해도 서버의 데이터 상태가 그대로 유지되지만, POST는 요청할 때마다 새로운 게시글이 생성되는 등 서버의 상태를 매번 변화시키므로 비멱등적입니다.
6. PHP에서의 실전 활용: 슈퍼 글로벌 변수와 폼 처리
PHP는 전송된 데이터를 처리하기 위해 배열 형태의 슈퍼 글로벌 변수를 제공합니다. 실무에서는 데이터 존재 여부를 먼저 확인하는 방어적 코딩(Defensive Coding) 습관이 중요합니다.
$_GET 슈퍼 글로벌 변수
if (isset($_GET['id'])) {
$id = $_GET['id']; // URL 쿼리 스트링에서 'id' 값을 가져옴
}
$_POST 슈퍼 글로벌 변수
if (isset($_POST['message'])) {
$message = $_POST['message']; // HTTP Body에서 'message' 값을 가져옴
}
$_REQUEST 슈퍼 글로벌 변수
if (isset($_REQUEST['data'])) {
// GET, POST, COOKIE 데이터를 모두 포함하지만, 출처가 불분명해 보안상 권장되지 않음
$data = $_REQUEST['data'];
}
HTML 폼과 파일 업로드
파일 업로드 시에는 반드시 <form>의 method를 POST로 설정하고, enctype='multipart/form-data' 속성을 추가해야 합니다. 그렇지 않으면 파일 자체가 아닌 파일명만 전송되는 불상사가 발생합니다. 서버측에서는 $_FILES 배열로 정보를 받아 move_uploaded_file() 함수로 파일을 영구 저장합니다.
7. 개발자가 반드시 알아야 할 보안 및 데이터 처리 팁
안전한 서비스를 위해 시니어 개발자가 챙기는 보안 체크리스트입니다.
• 인젝션(Injection) 방어: 사용자 입력값을 쿼리에 바로 넣지 마십시오. addslashes()도 방법이지만, PDO의 Prepared Statement를 사용하는 것이 가장 안전합니다. 특히 $stmt->bindParam(":id", $id, PDO::PARAM_INT);처럼 자료형을 명시하여 엄격하게 검증하십시오.
• XSS(Cross Site Scripting) 방어: 출력 시 htmlspecialchars() 또는 htmlentities()를 사용하여 스크립트 실행을 원천 봉쇄하십시오.
• CSRF 방어: Referer를 통해 도메인 일치 여부를 확인하거나, openssl_random_pseudo_bytes(32)와 bin2hex()를 조합해 생성한 강력한 CSRF 토큰을 세션과 비교하십시오.
• URL 인코딩 차이: urlencode()는 공백을 **+**로 바꾸며 폼 데이터 전송에 적합합니다. 반면 rawurlencode()는 공백을 **%20**으로 바꾸어 URL 경로(파일명 등) 처리에 사용됩니다.
• 민감 데이터: 비밀번호는 반드시 password_hash()로 암호화하고 password_verify()로 검증하는 것이 상식입니다.
8. 결론: 목적에 맞는 적절한 메서드 선택의 중요성
GET과 POST의 선택은 단순히 기술적 선호의 문제가 아니라 설계 원칙의 문제입니다. 실제로 과거 구글이 'Google Accelerator'라는 서비스를 출시했을 때, 웹 페이지의 모든 링크(GET)를 미리 클릭해 캐싱하려다 게시글 삭제 링크까지 GET으로 구현된 사이트들의 데이터를 대량 삭제시킨 사건은 시사하는 바가 큽니다.
조회는 GET, 상태 변경은 POST라는 REST API의 기본을 지키는 것만으로도 수많은 논리적 오류와 보안 사고를 예방할 수 있습니다.
"데이터를 단순히 조회하고 공유해야 한다면 GET을, 서버의 리소스를 생성하거나 변경하며 보안이 요구된다면 POST를 사용하는 것이 웹 설계의 올바른 원칙입니다."
'Backend > Php' 카테고리의 다른 글
| 사용자의 목소리 듣기: PHP로 폼(Form) 데이터 안전하게 수집하고 출력하기 (0) | 2026.02.17 |
|---|---|
| 실무 핵심! 10년 차 시니어 개발자가 엄선한 PHP 내장 함수 베스트 10 (0) | 2026.02.17 |
| 변수가 사는 동네: PHP 전역 변수(global)와 지역 변수(local) 이해하기 (0) | 2026.02.17 |
| 함수(Function) 만들기: 나만의 재사용 가능한 도구 상자 구축하기 (0) | 2026.02.17 |
| PHP의 꽃, foreach: 배열 데이터를 가장 쉽고 빠르게 처리하는 방법 (0) | 2026.02.17 |
