PHP (Hypertext Preprocessor)는 1995년 라스무스 러도프(Rasmus Lerdorf)가 자신의 웹 이력서 방문자를 추적하기 위해 만든 C 언어 기반의 간단한 스크립트 모음(Personal Home Page Tools)에서 출발했습니다.
초기의 단순한 형태를 넘어, 전 세계 웹 서버의 70% 이상을 구동하는 가장 대표적인 오픈 소스 백엔드 언어로 성장했습니다.
PHP는 서버 측(Server-side) 스크립트 언어이므로, 내 컴퓨터를 서버처럼 동작하게 만들어주는 도구가 필요합니다.
설치 후 htdocs 폴더에 .php 파일을 만들고 브라우저에서 localhost/파일명.php로 접속하면 실행됩니다.
PHP 코드는 항상 <?php로 시작해서 ?>로 끝납니다. 이 태그 밖의 내용은 일반 HTML로 취급됩니다.
화면에 무언가를 출력할 때는 주로 echo 또는 print를 사용합니다.
데이터를 저장하는 핵심 요소인 변수(Variable)와 절대 변하지 않는 상수(Constant)의 개념을 다룹니다. 또한 스칼라, 복합형 등 PHP의 다양한 데이터 타입 체계와 동적 타이핑(Dynamic Typing) 특성을 깊이 있게 이해합니다.
PHP에서 변수는 항상 달러 기호($)로 시작합니다. 자바스크립트나 C언어와 달리 변수 선언 시 데이터 타입을 명시하지 않는 동적 타입(Dynamic Type) 언어입니다.
PHP는 실행 시점에 타입이 결정되므로, 숫자로 구성된 문자열("10")과 정수(10)가 연산될 때 자동으로 타입이 변환될 수 있습니다. 의도치 않은 버그를 막기 위해 엄격한 비교 연산자(===) 사용을 권장합니다.
| 카테고리 | 타입명 | 설명 및 예시 |
|---|---|---|
| 스칼라 (Scalar) 단일 값 저장 |
String |
문자열 데이터. 따옴표나 쌍따옴표 사용 (예: "Hello") |
Integer |
소수점이 없는 정수 (예: 25, -100) | |
Float / Double |
소수점이 있는 실수 (예: 3.14) | |
Boolean |
참(true) 또는 거짓(false) |
상수는 한 번 값을 할당하면 스크립트 실행 중에 절대로 변경할 수 없는 식별자입니다. define() 함수 또는 const 키워드를 사용하여 선언하며, 주로 DB 접속 정보나 전역 설정값을 저장할 때 사용합니다.
데이터를 계산하고 조작하는 산술·대입·증감 연산자부터, 제어문(if, while)의 핵심이 되는 비교 연산자와 논리 연산자까지 PHP의 다양한 연산자를 종합적으로 학습합니다. 특히 조건 평가 시 리소스를 아낄 수 있는 단축 평가(Short-circuit)의 원리를 이해합니다.
수학적인 계산과 변수의 값을 조작할 때 사용되는 가장 기본적인 연산자 그룹입니다.
| 종류 | 기호 (Operator) | 설명 및 예시 |
|---|---|---|
| 산술 연산자 | +, -, *, /, % |
사칙연산 및 나머지 연산. (예: 10 % 3 결과는 1) |
| 대입 연산자 | =, +=, -=, *= |
오른쪽의 값을 왼쪽 변수에 할당. (예: $a += 5) |
| 증감 연산자 | ++, -- |
값을 1씩 증가시키거나 감소. (예: $a++) |
데이터를 비교하여 참(true) 또는 거짓(false)을 판별합니다. 제어문의 핵심 논리 구조를 구성합니다.
| 종류 | 기호 (Operator) | 설명 및 예시 |
|---|---|---|
| 비교 연산자 | ==, ===, !=, !==, >, <= |
두 값의 크기나 동일성 비교. ===는 데이터 타입까지 일치하는지 엄격하게 검사합니다. |
| 논리 연산자 | && (AND), || (OR), ! (NOT) |
여러 개의 조건을 결합하거나 반전시킵니다. |
조건 분기문은 프로그램의 흐름을 결정짓는 핵심 요소입니다. 조건에 따라 실행할 코드를 다르게 분기하여 동적인 로직을 구성합니다. if-else 구문을 활용한 순차적 검사와 switch 구문을 통한 값 기반의 명확한 점프(Jump) 방식을 학습하고, 각각의 적절한 사용 상황을 이해합니다.
| 명령어 | 역할 및 특징 | 주요 사용처 |
|---|---|---|
if |
주어진 조건이 true일 경우에만 내부 블록을 실행 |
단일 조건 판단 |
elseif |
이전 if 조건이 거짓일 때 새로운 조건을 검사 |
여러 범위나 조건을 순차적으로 판단 |
else |
앞선 모든 조건이 만족하지 않을 경우 기본으로 실행 | 예외 처리 및 기본 동작 수행 |
switch |
변수의 값에 따라 일치하는 case로 바로 점프하여 실행 |
정확한 값(문자열, 숫자) 매칭 판단 |
특정 조건이 true일 때만 코드를 실행하고 싶다면 if를 사용합니다. 조건이 여러 개일 경우 elseif로 연결하며, 모든 조건이 맞지 않을 때는 else를 사용합니다.
변수의 값이 정확히 특정 값(문자열, 숫자 등)과 일치할 때 실행할 코드를 정의합니다. if-elseif가 길어질 때 사용하면 가독성이 좋습니다.
반복문은 동일한 코드나 로직을 지정된 조건이나 횟수만큼 반복해서 실행할 때 사용됩니다. PHP에서는 while, for를 통해 전통적인 순회 제어를 수행할 뿐만 아니라, foreach를 제공하여 배열(Array) 데이터를 처리하는 데 매우 직관적이고 강력한 도구를 제공합니다.
| 명령어 | 역할 및 작동 방식 | 주요 사용처 |
|---|---|---|
while |
조건이 참(true)인 동안 계속해서 반복 실행 | 무한 루프, 조건 기반 종료 |
do-while |
코드를 최소 한 번은 실행한 후, 조건을 검사하여 반복 | 선 실행 후 조건 판단이 필요할 때 |
for |
초기식, 조건식, 증감식을 한 줄에 정의하여 정해진 횟수만큼 반복 | 횟수가 명확한 반복 순회 |
foreach |
배열의 시작부터 끝까지 자동으로 순회 (인덱스 계산 불필요) | 배열 및 객체 데이터 처리 |
조건이 참(true)인 동안 코드를 계속 반복 실행합니다. do-while은 조건을 나중에 검사하므로 최소 1번은 무조건 실행되는 차이가 있습니다.
for (초기식; 조건식; 증감식) 구조로 작성하며, 반복 횟수가 명확할 때 가장 많이 쓰이는 반복문입니다.
배열의 처음부터 끝까지 자동으로 순회하면서 값을 하나씩 꺼내줍니다. PHP에서 가장 사랑받는 배열 전용 반복문입니다.
배열(Array)은 연관된 여러 개의 데이터를 하나의 변수 이름으로 묶어서 관리하는 매우 중요한 자료구조입니다. PHP는 순서대로 저장되는 인덱스 배열(Indexed Array)과, Key-Value 쌍으로 데이터를 저장하는 연관 배열(Associative Array)을 유연하게 지원하며, 이들을 조합한 다차원 배열도 매우 자주 사용됩니다.
| 배열 종류 | 선언 및 접근 방식 | 특징 및 활용 상황 |
|---|---|---|
| 인덱스 배열 Indexed Array |
$arr = ["A", "B"]; |
0부터 시작하는 숫자 인덱스가 자동으로 부여됩니다. 단순 나열형 데이터, 순서가 중요한 목록을 처리할 때 사용됩니다. |
| 연관 배열 Associative Array |
$arr = ["key" => "Val"]; |
숫자 대신 명시적인 문자열 Key를 부여합니다. 데이터의 의미를 명확히 해야 할 때(ex: JSON, DB 레코드) 필수적입니다. |
| 다차원 배열 Multidimensional |
$arr[0]["key"] |
배열 안에 또 다른 배열이 중첩된 형태입니다. 복잡한 표(Matrix) 구조나 트리 구조 데이터를 다룰 때 사용됩니다. |
PHP의 배열은 크게 두 가지로 나뉩니다.
하나의 배열 안에 또 다른 배열을 넣어서 복잡한 표(테이블) 구조의 데이터를 표현할 수 있습니다. 2차원 배열이 가장 흔히 쓰입니다.
함수(Function)는 코드를 논리적인 작업 단위로 묶어 재사용성을 극대화하는 핵심 도구입니다. 매개변수(Parameter)를 통해 외부의 값을 전달받고, 연산 결과를 반환(Return)합니다. 또한, 변수가 선언된 위치에 따라 접근 가능 범위가 결정되는 스코프(Scope)의 개념을 이해하는 것은 안정적인 프로그램 작성에 필수적입니다.
| 스코프 타입 | 선언 위치 및 수명 | 특징 및 접근 방법 |
|---|---|---|
| 지역 스코프 Local Scope |
함수 내부에서 선언. 함수 종료 시 메모리 해제 | 해당 함수 내부에서만 사용 가능합니다. 외부에서는 접근할 수 없습니다. |
| 전역 스코프 Global Scope |
함수 외부에서 선언. 스크립트 종료 시 메모리 해제 | 함수 외부 어디서든 접근 가능하지만, 함수 내부에서 접근하려면 global 키워드가 필요합니다. |
| 정적 스코프 Static Scope |
함수 내부에서 static으로 선언 |
지역 변수처럼 해당 함수 내에서만 접근 가능하지만, 함수가 종료되어도 값이 초기화되지 않고 계속 유지됩니다. |
자주 사용하는 코드를 블록으로 묶어 이름을 붙여둔 것입니다. 원할 때마다 이름을 불러(호출) 실행할 수 있습니다.
재료를 넣어주면(매개변수 Parameter), 결과물을 내뱉습니다(반환값 Return).
변수는 선언된 위치에 따라 접근할 수 있는 범위(Scope)가 다릅니다.
global 키워드 필요!PHP는 엄청나게 많은 기본 내장 함수를 제공합니다. 이를 잘 활용하면 수십 줄의 코드를 한 줄로 줄일 수 있습니다.
웹 개발의 핵심은 사용자가 HTML <form>에 입력한 데이터를 서버(PHP)가 받아서 처리하는 것입니다.
?id=1&name=kim)로 데이터를 달아서 보냅니다. (검색, 공유용)
HTTP 프로토콜은 상태를 기억하지 않는 무상태성(Stateless)을 가집니다. 따라서 로그인 상태 유지나 장바구니 기능 등을 구현하기 위해서는 웹 애플리케이션 차원의 상태 관리가 필수적입니다. 데이터를 클라이언트(브라우저)에 저장하는 Cookie(쿠키)와 서버 메모리에 안전하게 저장하는 Session(세션)의 차이점과 활용법을 알아봅니다.
| 구분 | 세션 (Session) | 쿠키 (Cookie) |
|---|---|---|
| 저장 위치 | 웹 서버의 메모리 또는 파일 | 사용자의 클라이언트 (웹 브라우저) |
| 보안성 | 높음 (서버에 저장되므로 탈취/위조가 어려움) | 낮음 (사용자 PC에 노출되므로 조작 가능) |
| 데이터 형태 | 서버 내 다양한 형태의 객체/배열 | 단순한 문자열 (텍스트 조각) |
| 주요 용도 | 로그인 인증, 민감한 개인 정보 유지 | '오늘 하루 보지 않기', 다크모드 설정, 장바구니 등 |
웹 서버는 사용자가 누군지 기억하지 못합니다(Stateless). 세션은 서버 메모리에 사용자의 정보를 저장하여 로그인 상태 등을 유지하는 기술입니다.
모든 세션 사용 전에는 반드시 session_start()가 호출되어야 합니다.
세션이 '서버'에 저장된다면, 쿠키는 사용자의 웹 브라우저(로컬)에 저장되는 작은 텍스트 조각입니다. (예: "7일간 보지 않기", 장바구니)
데이터베이스를 사용하지 않고도 텍스트 파일 단위로 데이터를 읽고 쓰는 파일 I/O(Input/Output) 기능은 프로그래밍의 기본입니다. 특히 시스템 활동 내역을 기록하는 로그(Log) 파일 작성, 간단한 설정 파일(Config)을 저장하거나 읽어올 때 필수적으로 사용됩니다. 파일을 열고(Open), 조작(Read/Write)하고, 닫는(Close) 일련의 스트림 생명주기를 완벽히 이해해 봅니다.
| 모드 (Mode) | 기능 및 동작 | 파일이 없을 경우 |
|---|---|---|
| r (Read) | 읽기 전용. 파일 포인터는 파일의 맨 처음을 가리킵니다. | 에러 발생 (실패) |
| w (Write) | 쓰기 전용. 기존 내용이 완전히 삭제되고 새로 덮어씁니다. | 새 파일을 생성함 |
| a (Append) | 이어 쓰기 전용. 파일 내용의 맨 끝(마지막)에 내용을 추가합니다. | 새 파일을 생성함 |
| x (Exclusive) | 생성 후 쓰기 전용. 파일이 이미 존재하면 무조건 실패합니다 (안전한 파일 생성). | 새 파일을 생성함 |
텍스트 파일을 읽어오거나 텍스트를 파일에 저장할 수 있습니다. 로그(Log)를 남길 때 주로 사용됩니다.
수백 페이지에 달하는 웹사이트를 만들 때 모든 페이지마다 헤더나 푸터 코드를 복사해서 붙여넣는 것은 유지보수 측면에서 최악입니다. PHP에서는 공통으로 사용되는 UI나 DB 접속 설정 등을 별도의 모듈(조각 파일)로 분리하고, 메인 파일에서 이를 조립(Include/Require)하는 방식으로 개발 효율성을 극대화합니다.
| 명령어 | 파일이 없을 때의 동작 (에러 처리) | 주요 사용처 |
|---|---|---|
include |
Warning(경고) 발생 후 스크립트 계속 실행 | 헤더, 푸터, 배너 등 UI 요소 (없어도 치명적이지 않은 곳) |
require |
Fatal Error(치명적 오류) 발생 후 스크립트 즉시 중단 | DB 접속 파일, 핵심 비즈니스 로직, 보안 모듈 |
include_oncerequire_once |
기본 동작은 위와 동일하되, 이미 불러온 파일이면 다시 불러오지 않음 | 함수나 클래스가 중복 선언되어 충돌하는 것을 방지할 때 |
헤더, 푸터, DB 접속 코드처럼 모든 페이지에 공통으로 들어가는 코드를 별도의 파일로 빼서 불러옵니다.
include: 파일을 못 찾아도 경고만 띄우고 계속 실행합니다.require: 파일을 못 찾으면 치명적 오류를 내고 즉시 중단합니다. (DB 접속 등에 사용)
실제 웹 서비스를 운영하기 위해서는 날짜와 시간을 다루는 date(), 페이지 이동을 제어하는 header(), 그리고 개발 중 발생하는 버그를 잡는 디버깅 기법이 필수적입니다. 이 장에서는 PHP의 강력한 내장 유틸리티 함수들의 사용법과 서버와 브라우저 간의 HTTP 통신 원리에 기반한 리다이렉션 기법을 익힙니다.
| 기호 (Format) | 의미 | 예시 출력 |
|---|---|---|
Y / y |
연도 (Year) | 2026 / 26 |
m / n |
월 (Month) | 05 (0포함) / 5 (0제외) |
d / j |
일 (Day) | 09 / 9 |
H : i : s |
시간 : 분 : 초 (24시간제) | 14:30:00 |
게시글 작성 시간, 로그 기록 등을 남길 때 date() 함수를 사용하여 타임스탬프를 읽기 쉬운 문자열로 변환합니다.
로그인을 성공했거나, 권한이 없는 페이지에 접근했을 때 브라우저의 URL을 강제로 변경하여 이동시킵니다.
⚠️ 주의: header() 함수 이전에 HTML이나 공백이 단 1글자라도 출력되면(echo) 에러가 발생합니다.
PHP는 기본적으로 실서버 환경에서 보안을 위해 에러 메시지를 숨깁니다. 하지만 개발 중에는 에러를 화면에 띄워야 문제를 고칠 수 있습니다.
현대적인 PHP 개발은 Composer와 PSR 표준 없이는 설명할 수 없습니다. 이 모듈에서는 외부 라이브러리를 안전하게 다운로드하고, include/require 지옥에서 벗어나 자동으로 클래스를 로드(Autoloading)하는 생태계의 핵심 원리를 학습합니다.
과거의 PHP는 외부 라이브러리를 사용하기 위해 파일을 직접 다운로드하고 복사해야 했습니다. 하지만 Composer의 등장으로 현대 PHP는 완전히 달라졌습니다.
마치 Node.js의 npm이나 Python의 pip처럼, 필요한 라이브러리를 선언만 하면 자동으로 다운로드하고 의존성을 관리해줍니다. Packagist라는 방대한 패키지 저장소를 통해 수많은 오픈소스 도구를 손쉽게 내 프로젝트에 통합할 수 있습니다.
PHP Framework Interop Group(PHP-FIG)에서 제정한 PSR(PHP Standard Recommendation)은 다양한 프레임워크 간의 상호운용성을 위한 표준입니다.
코딩 스타일(PSR-12), 로깅 인터페이스(PSR-3), HTTP 메시지(PSR-7) 등 공통의 규격을 따름으로써, Laravel, Symfony 등 어떤 환경에서도 호환되는 코드를 작성할 수 있게 해줍니다.
| 표준 번호 | 주제 (Topic) | 설명 및 목적 |
|---|---|---|
| PSR-4 | 오토로딩 (Autoloading) | 파일 경로와 네임스페이스를 1:1로 매핑하여 클래스 파일을 자동으로 불러옵니다. |
| PSR-12 | 코딩 스타일 (Coding Style) | 들여쓰기, 괄호 위치, 네이밍 규칙 등 통일된 PHP 코딩 컨벤션을 정의합니다. |
| PSR-3 | 로거 인터페이스 (Logger Interface) | 모든 로깅 라이브러리가 공통으로 사용해야 하는 에러/경고 기록 규격을 제공합니다. |
| PSR-7 | HTTP 메시지 (HTTP Message) | HTTP 요청(Request) 및 응답(Response)을 객체 지향적으로 처리하는 표준 인터페이스입니다. |
기존에는 클래스 파일을 사용하기 위해 수많은 require_once를 작성해야 했습니다. PSR-4는 네임스페이스와 폴더 구조를 매핑하여, 클래스를 사용할 때 해당 파일을 자동으로 로드하는 표준 프로토콜입니다.
Composer와 함께 사용되며, 코드를 훨씬 깔끔하게 만들고 파일 관리의 부담을 덜어줍니다. 이제 네임스페이스 규칙만 잘 지키면 파일 로드는 Composer가 알아서 처리합니다.
모든 진입점 파일(주로 index.php)의 가장 첫 부분에는 반드시 require_once __DIR__ . '/vendor/autoload.php'; 코드가 선언되어야만 Composer의 Autoloading 기능이 작동합니다.
실제 코드를 작성하기 전에, composer.json 파일을 통해 프로젝트 의존성을 설정하고 터미널에서 패키지를 설치하는 과정이 선행되어야 합니다.
설치가 완료되면 PHP 코드를 작성하여 클래스가 자동으로 로딩되는 것을 확인합니다. 이제 클래스 생성 시 require를 일일이 적지 않아도 됩니다!
과거의 PHP는 느슨한 타입 검사(Weak Typing)로 인해 예상치 못한 암묵적 형변환 버그가 자주 발생했습니다. 최신 PHP는 strict_types 선언과 복합 타입(Union, Intersection)을 도입하여, 유연함과 엔터프라이즈급 런타임 안정성을 동시에 제공하는 강력한 언어로 진화했습니다.
PHP는 기본적으로 느슨한 타입 언어(동적 타입)이지만, declare(strict_types=1);를 선언하면 엄격한 타입 체크를 강제할 수 있습니다.
이는 의도치 않은 타입 변환(예: 문자열 "1"이 정수 1로 변환되는 현상)을 막아주며, 예상치 못한 버그를 예방하고 코드의 예측 가능성을 크게 높여줍니다.
현대 PHP는 매우 강력한 타입 시스템을 갖추고 있습니다. Union Types(여러 타입 중 하나), Intersection Types(여러 인터페이스를 모두 만족) 등을 지원합니다.
여기에 어떤 값이든 될 수 있는 mixed나, 절대 반환하지 않는(예: 에러를 던지거나 종료) 함수를 위한 never 타입까지 추가되어, 더욱 견고한 코드를 작성할 수 있습니다.
최신 PHP는 객체 지향 프로그래밍(OOP)을 더 간결하고 안전하게 작성할 수 있는 기능들을 대거 추가했습니다. 보일러플레이트 코드를 줄여주는 Constructor Property Promotion, 객체의 불변성을 보장하는 Readonly Classes, 그리고 상태 값 관리를 혁신적으로 바꿔줄 Native Enums까지 주요 기능들을 살펴봅니다.
생성자 속성 프로모션은 클래스를 정의할 때 발생하는 반복적인 코드를 획기적으로 줄여주는 기능입니다.
생성자 매개변수에 가시성(public, private, protected)을 지정하기만 하면, 속성 선언과 할당이 한 번에 자동으로 처리됩니다. 이로 인해 클래스가 훨씬 짧고 읽기 쉬워집니다.
Readonly는 한 번 초기화되면 값을 변경할 수 없도록 강제하는 기능입니다. DTO(Data Transfer Object)나 Value Object를 만들 때 매우 유용합니다.
PHP 8.2부터는 클래스 전체를 readonly로 선언할 수 있어, 클래스 내의 모든 속성이 자동으로 불변(immutable) 상태가 되며 예상치 못한 부작용(Side Effect)을 차단합니다.
오랫동안 PHP에 없었던 열거형(Enum)이 네이티브로 지원됩니다. 단순한 상수(const) 배열을 넘어, 메서드를 가질 수 있고 인터페이스를 구현할 수 있는 일급 객체입니다.
상태 값, 카테고리 등 고정된 데이터 세트를 타입 안전하게 관리할 수 있어 도메인 로직의 안정성이 크게 향상됩니다.
PHP 8.x부터는 코드의 가독성과 안전성을 비약적으로 높여주는 새로운 문법들이 추가되었습니다. 엄격한 타입 비교와 값을 반환하는 Match 표현식, 널 포인터 예외를 우아하게 피하는 Nullsafe 연산자, 그리고 프레임워크 메타데이터의 표준이 된 Attributes 문법을 익혀보세요.
match 표현식은 기존의 switch 문을 개선한 기능입니다. 값을 반환할 수 있고(표현식), 일치 여부를 확인할 때 엄격한 비교(===)를 사용합니다.
또한 break를 생략해도 다음 케이스로 넘어가지 않으며(No type coercion, No fallthrough), 코드가 훨씬 간결하고 가독성이 뛰어납니다.
Nullsafe 연산자(?->)는 객체의 메서드나 속성에 연쇄적으로 접근할 때 유용합니다. 중간에 어느 하나라도 null이면 에러를 발생시키지 않고 전체 평가를 멈춘 뒤 null을 반환합니다.
이 기능 덕분에 불필요한 null 체크 조건문(if 문)을 대폭 줄일 수 있습니다.
Attributes(어트리뷰트)는 기존에 주석(DocBlock)으로 처리하던 메타데이터를 언어 차원의 공식 문법으로 대체한 것입니다.
주석을 파싱하는 대신 Reflection API를 통해 구조적이고 타입 안전하게 클래스, 메서드, 속성에 추가 정보를 부여할 수 있어 프레임워크 설계 시 핵심적으로 사용됩니다.
실제 코드에서 Match 표현식과 Nullsafe 연산자가 어떻게 동작하는지 브라우저 결과를 확인해보세요.
현대적인 PHP 프레임워크(Laravel, Symfony 등)의 핵심 기반 기술인 의존성 주입(Dependency Injection)에 대해 학습합니다. 내부에서 객체를 직접 생성하는 강결합(Tightly Coupled) 구조를 탈피하여, 외부 컨테이너로부터 주입받음으로써 단위 테스트(Mocking)가 쉬워지고 코드의 재사용성이 극대화되는 원리를 알아봅니다.
현대 PHP 개발의 핵심 패턴 중 하나는 의존성 주입(DI)입니다. 객체가 필요로 하는 의존성을 내부에서 직접 생성하지 않고 외부에서 주입받는 방식입니다.
이를 통해 모듈 간의 결합도를 낮추고 단위 테스트(Mocking)를 쉽게 만들 수 있습니다. 최신 프레임워크들은 강력한 DI Container를 내장하여 객체의 생성과 주입을 자동화합니다.
<?php
// NO_PREVIEW
// 의존성 주입 (DI) 패턴 적용
class UserService {
// 내부에서 new UserRepository()를 호출하지 않고 외부에서 주입받습니다.
public function __construct(
private UserRepository $repository
) {}
}
/**
* 프레임워크의 DI 컨테이너 역할
* (실제 프레임워크에서는 이 과정을 개발자가 직접 작성하지 않고 자동화해 줍니다)
*/
// $container = new Container();
// $userService = $container->get(UserService::class);
단순한 스크립트 언어를 넘어선 최신 PHP 생태계에서는 엄격한 코드 품질 관리가 필수입니다. 코드를 실행하지 않고도 타입 에러와 버그를 짚어내는 정적 분석(PHPStan, Psalm) 도구와, 직관적이고 아름다운 테스트 코드를 작성할 수 있게 해주는 Pest 프레임워크를 통해 견고한 애플리케이션을 구축하는 방법을 알아봅니다.
PHP는 인터프리터 언어이지만, PHPStan이나 Psalm 같은 정적 분석(Static Analysis) 도구를 통해 컴파일 언어 수준의 타입 안정성을 확보할 수 있습니다.
코드를 실행하지 않고도 타입 불일치, 정의되지 않은 메서드 호출, 논리적 오류 등을 사전에 탐지하여 프로젝트의 품질을 비약적으로 높여줍니다.
기존의 PHPUnit이 클래스 기반의 다소 무거운 구조였다면, Pest는 현대적이고 서술적인(fluent) 함수형 인터페이스를 제공하는 테스팅 프레임워크입니다.
마치 JavaScript의 Jest처럼 직관적으로 코드를 작성할 수 있어, 개발자들이 테스트 작성에 느끼는 진입 장벽을 크게 낮춰줍니다.