PHP는 서버에서 실행됩니다. 페이지를 만들고, 완성된 HTML을 보낸 뒤 멈춥니다. JavaScript는 방문자의 브라우저에서 실행되며, 클릭에 반응하고 페이지가 로드된 뒤 내용을 바꿉니다. Node.js를 쓰면 서버에서도 실행됩니다. 그래서 둘은 경쟁자라기보다 파트너입니다. 일반적인 사이트는 서버에 PHP(또는 Node.js)를, 브라우저에 JavaScript를 씁니다.
이 PHP 코드는 서버에서 실행됩니다. 브라우저는 출력된 것만 받고, Page 탭이 그 결과를 보여 줍니다.
Output 탭을 보세요. PHP는 하나도 남아 있지 않고 HTML만 있습니다. 브라우저에서 JavaScript로 같은 목록을 만들면 이렇게 됩니다.
const products = [
{ name: "Keyboard", price: 49 },
{ name: "Mouse", price: 19 },
{ name: "Monitor", price: 189 },
];
const ul = document.querySelector("#cart"); // an empty <ul id="cart"> in the HTML
for (const p of products) {
const li = document.createElement("li");
li.textContent = `${p.name}: $${p.price}`;
ul.append(li);
}
PHP 버전은 완성된 페이지를 보내므로 검색 엔진과 느린 휴대폰이 바로 읽을 수 있습니다. JavaScript 버전은 나중에 새로 고침 없이 목록을 갱신할 수 있습니다. 예를 들어 방문자가 항목을 지울 때입니다.
각 언어가 실행되는 곳
| PHP | JavaScript | |
|---|---|---|
| 실행 위치 | 웹 서버(또는 터미널) | 브라우저, 그리고 Node.js, Deno, Bun을 쓰는 서버 |
| 접근 대상 | 파일, 데이터베이스, 환경, 비밀 정보 | 페이지(DOM), 클릭, 브라우저 저장소 |
| 수명 | 요청마다 한 번 실행 | 페이지가 열려 있는 동안(브라우저), 또는 하나의 장기 프로세스(Node.js) |
| 주 용도 | 페이지 생성, 폼 처리, API, 데이터베이스 연동 | 상호작용, 실시간 갱신, 싱글 페이지 앱, Node.js 서버 |
| 방문자가 코드를 볼 수 있음 | 아니요 | 예, 브라우저에서 |
마지막 행은 보안에 중요합니다. 브라우저 JavaScript에 있는 것은 모두 방문자에게 보이므로, 비밀번호, API 키, 가격 검증은 서버에 두어야 합니다.
문법 나란히 보기
두 언어는 C에서 빌려 온 부분이 많아 비슷해 보입니다: 중괄호, if, for, while, function, return. 차이는 세부에 있습니다.
| 작업 | PHP | JavaScript |
|---|---|---|
| 변수 | $name = "Ada"; | let name = "Ada"; |
| 상수 | const MAX = 10; | const MAX = 10; |
| 문자열 연결 | "Hi " . $name | "Hi " + name |
| 템플릿 문자열 | "Hi $name" | `Hi ${name}` |
| 리스트 | ["a", "b"] | ["a", "b"] |
| 키/값 | ["id" => 1] | { id: 1 } |
| 길이 | count($list), strlen($s) | list.length, s.length |
| 반복 | foreach ($list as $item) | for (const item of list) |
| 화살표 함수 | fn($x) => $x * 2 | (x) => x * 2 |
| 출력 | echo "Hi"; | console.log("Hi"); |
다음은 PHP에서 콜백을 쓰는 함수입니다.
JavaScript에서는 map과 filter가 배열의 메서드입니다.
const prices = [12.5, 8, 30, 4.25];
const withTax = prices.map((p) => Math.round(p * 1.2 * 100) / 100);
const cheap = withTax.filter((p) => p < 15);
console.log(withTax.join(", "));
console.log("Under 15: " + cheap.join(", "));
+ 연산자: 대표적인 함정
JavaScript에서 +는 숫자 덧셈과 문자열 연결을 모두 하므로, 어딘가에 문자열이 있으면 덧셈이 연결로 바뀝니다. PHP는 둘을 구분합니다. +는 항상 더하고 .는 항상 연결합니다.
console.log("10" + 5); // "105"
console.log("10" - 5); // 5
console.log("3" * "4"); // 12
console.log(0.1 + 0.2 === 0.3); // false
두 언어 모두 느슨한 ==와 엄격한 ===가 있습니다. 조언도 같습니다. 타입을 넘나들며 비교할 생각이 아니라면 ===를 쓰세요.
PHP에서 JavaScript로 데이터 전달
PHP가 먼저 실행되므로, 브라우저의 JavaScript가 쓸 데이터를 페이지에 바로 써 넣을 수 있습니다. json_encode는 PHP 배열을 유효한 JavaScript로 바꿉니다.
Output 탭에서 데이터가 이미 채워진 생성된 스크립트를 볼 수 있습니다. JSON_HEX_TAG 플래그는 <와 >를 이스케이프하므로, </script>가 들어 있는 값이 스크립트를 일찍 끝낼 수 없습니다. 옵션은 json_encode에서 자세히 다룹니다.
반대 방향은 HTTP로 동작합니다. 브라우저 JavaScript가 fetch("/api/cart.php")를 호출하면 PHP 스크립트가 실행되어 JSON으로 응답합니다.
<?php
// api/cart.php
header('Content-Type: application/json');
echo json_encode(['items' => 3, 'total' => 257]);
const res = await fetch("/api/cart.php");
const cart = await res.json();
console.log(cart.total); // 257
서버에서 PHP vs Node.js
JavaScript가 Node.js로 서버에서 실행되면, 이 비교는 실제 선택의 문제가 됩니다.
| PHP | Node.js | |
|---|---|---|
| 모델 | 요청마다 새로 실행, 공유하는 것 없음 | 이벤트 루프를 가진 하나의 장기 실행 프로세스 |
| I/O 대기 | 그 요청을 블로킹(다른 요청은 다른 워커에서 실행) | 논블로킹, async/await |
| 잘하는 일 | 서버 렌더링 사이트, CMS, 전형적인 CRUD 앱 | 실시간 앱, 웹소켓, 대기 중인 연결이 많은 경우 |
| 호스팅 | 모든 공유 호스팅, PHP-FPM | Node 프로세스 매니저 또는 Vercel 같은 플랫폼 |
| 대표 프레임워크 | Laravel, Symfony, WordPress | Express, NestJS, Next.js |
| 프론트와 백엔드를 한 언어로 | 아니요 | 예 |
PHP의 모델은 관대합니다. 버그나 메모리 누수가 요청 하나에만 영향을 주고, 요청마다 깨끗하게 시작합니다. Node의 모델은 상태와 연결을 열어 둘 수 있어 채팅과 실시간 대시보드에 맞지만, 충돌이나 블로킹 루프가 그 프로세스의 모든 사용자에게 영향을 줍니다.
무엇을 배울까
상호작용이 있는 웹 페이지에는 어차피 JavaScript가 필요합니다. 브라우저가 실행하는 유일한 언어이기 때문입니다. 질문은 서버에서 무엇을 실행하느냐입니다.
- 다음으로 PHP를 배우세요. WordPress, Laravel, 수많은 기존 PHP 사이트로 일하고 싶거나, 저렴한 호스팅에 동적 사이트를 올리는 가장 간단한 방법을 원한다면요. PHP란부터 시작하세요.
- JavaScript(Node.js)를 계속 쓰세요. 스택 전체에 언어 하나를 쓰고 싶거나 실시간 기능을 만든다면요.
흔한 경로는 HTML과 CSS, 그다음 브라우저의 JavaScript, 그다음 서버 언어 하나입니다. 어떤 서버 언어를 고르든 폼, 세션, 데이터베이스, JSON API는 같은 HTTP 개념 위에서 동작하므로 지식이 그대로 옮겨 갑니다.
자주 묻는 질문
JavaScript가 PHP를 대체할 수 있나요?
서버에서는 가능합니다. Node.js(Express, Next.js 등)는 PHP와 같은 일을 합니다. 브라우저에서는 PHP가 JavaScript를 전혀 대체할 수 없습니다. 브라우저는 JavaScript만 실행하기 때문입니다. 그래서 많은 사이트가 서버에는 PHP나 Node를, 브라우저에는 JavaScript를 씁니다.
PHP 변수를 JavaScript로 넘기려면 어떻게 하나요?
페이지에 JSON으로 출력하세요: <script>const user = <?= json_encode($user, JSON_HEX_TAG) ?>;</script>. json_encode는 문자열, 숫자, 배열, 객체에 대해 유효한 JavaScript를 만들고, JSON_HEX_TAG는 데이터 안의 </script>가 태그를 닫지 못하게 합니다.
JavaScript에서 PHP 함수를 호출할 수 있나요?
직접은 안 됩니다. PHP는 서버에서, JavaScript는 브라우저에서 실행되기 때문입니다. JavaScript가 fetch('/api.php?id=3')로 HTTP 요청을 보내면 PHP 스크립트가 실행되어 응답(보통 JSON)을 출력하고, JavaScript가 그것을 읽습니다.
PHP가 Node.js보다 빠른가요?
작업 유형에 따라 다릅니다. Node.js는 이벤트 루프 덕분에 동시에 열린 느린 연결이 많을 때(채팅, 웹소켓) 잘 처리합니다. OPcache를 쓰는 PHP 8은 일반적인 요청과 응답 페이지에서 빠릅니다. 대부분의 사이트에서 병목은 언어가 아니라 데이터베이스입니다.