minstudio

모던 PHP 표준 생태계

👉 1. Composer: 현대 PHP의 심장

Composer와 Packagist 생태계

과거의 PHP는 외부 라이브러리를 사용하기 위해 파일을 직접 다운로드하고 복사해야 했습니다. 하지만 Composer의 등장으로 현대 PHP는 완전히 달라졌습니다.

마치 Node.js의 npm이나 Python의 pip처럼, 필요한 라이브러리를 선언만 하면 자동으로 다운로드하고 의존성을 관리해줍니다. Packagist라는 방대한 패키지 저장소를 통해 수많은 오픈소스 도구를 손쉽게 내 프로젝트에 통합할 수 있습니다.


👉 2. PSR-4 Autoloading

파일을 자동으로 불러오는 마법

기존에는 클래스 파일을 사용하기 위해 수많은 require_once를 작성해야 했습니다. PSR-4는 네임스페이스와 폴더 구조를 매핑하여, 클래스를 사용할 때 해당 파일을 자동으로 로드하는 표준 프로토콜입니다.

Composer와 함께 사용되며, 코드를 훨씬 깔끔하게 만들고 파일 관리의 부담을 덜어줍니다. 이제 네임스페이스 규칙만 잘 지키면 파일 로드는 Composer가 알아서 처리합니다.


👉 3. PHP Standard Recommendation (PSR)

PHP 생태계의 공통 표준

PHP Framework Interop Group(PHP-FIG)에서 제정한 PSR(PHP Standard Recommendation)은 다양한 프레임워크 간의 상호운용성을 위한 표준입니다.

코딩 스타일(PSR-12), 로깅 인터페이스(PSR-3), HTTP 메시지(PSR-7) 등 공통의 규격을 따름으로써, Laravel, Symfony 등 어떤 환경에서도 호환되는 코드를 작성할 수 있게 해줍니다.

PSR-4 Autoloading 매핑 원리

코드상의 네임스페이스 App\Controllers\UserController new App\Controllers\UserController(); Composer 물리적 파일 경로 src/Controllers/UserController.php include_once(...) 자동 실행
bash
// composer.json
{
    "require": {
        "monolog/monolog": "^3.0"
    }
}

// 터미널 실행
// composer install
타입 시스템의 원리와 이해

👉 4. Strict Typing (엄격한 타입)

런타임 안정성의 핵심

PHP는 기본적으로 느슨한 타입 언어(동적 타입)이지만, declare(strict_types=1);를 선언하면 엄격한 타입 체크를 강제할 수 있습니다.

이는 의도치 않은 타입 변환(예: 문자열 "1"이 정수 1로 변환되는 현상)을 막아주며, 예상치 못한 버그를 예방하고 코드의 예측 가능성을 크게 높여줍니다.


👉 5. Scalar & Complex Types

고도화된 타입 시스템

현대 PHP는 매우 강력한 타입 시스템을 갖추고 있습니다. Union Types(여러 타입 중 하나), Intersection Types(여러 인터페이스를 모두 만족) 등을 지원합니다.

여기에 어떤 값이든 될 수 있는 mixed나, 절대 반환하지 않는(예: 에러를 던지거나 종료) 함수를 위한 never 타입까지 추가되어, 더욱 견고한 코드를 작성할 수 있습니다.

Weak Typing vs Strict Typing

기본 모드 (Weak Typing) 암묵적 형변환 발생 (버그 원인) function add(int $a, int $b) add(1, "2") 결과: 3 "2"가 자동으로 int(2)로 변환됨 엄격한 모드 (Strict Typing) declare(strict_types=1); function add(int $a, int $b) add(1, "2") Fatal Error 타입이 정확히 일치하지 않으면 에러 발생
<?php
declare(strict_types=1);

function addNumbers(int $a, int $b): int {
    return $a + $b;
}

// addNumbers("1", "2"); // 타입 에러 발생!
객체 지향 문법 업데이트

👉 6. Constructor Property Promotion

보일러플레이트 코드 제거

생성자 속성 프로모션은 클래스를 정의할 때 발생하는 반복적인 코드를 획기적으로 줄여주는 기능입니다.

생성자 매개변수에 가시성(public, private, protected)을 지정하기만 하면, 속성 선언과 할당이 한 번에 자동으로 처리됩니다. 이로 인해 클래스가 훨씬 짧고 읽기 쉬워집니다.


👉 9. Readonly Properties & Classes

데이터 불변성 보장

Readonly는 한 번 초기화되면 값을 변경할 수 없도록 강제하는 기능입니다. DTO(Data Transfer Object)나 Value Object를 만들 때 매우 유용합니다.

PHP 8.2부터는 클래스 전체를 readonly로 선언할 수 있어, 클래스 내의 모든 속성이 자동으로 불변(immutable) 상태가 되며 예상치 못한 부작용(Side Effect)을 차단합니다.


👉 10. Native Enums

강력한 상태 값 관리

오랫동안 PHP에 없었던 열거형(Enum)이 네이티브로 지원됩니다. 단순한 상수(const) 배열을 넘어, 메서드를 가질 수 있고 인터페이스를 구현할 수 있는 일급 객체입니다.

상태 값, 카테고리 등 고정된 데이터 세트를 타입 안전하게 관리할 수 있어 도메인 로직의 안정성이 크게 향상됩니다.

// 이전 방식
class User {
    private string $name;
    public function __construct(string $name) {
        $this->name = $name;
    }
}

// PHP 8.0 프로모션 적용
class User {
    public function __construct(
        private string $name
    ) {}
}
새로운 표현식과 편의 기능

👉 7. Match Expression

더 안전하고 강력한 조건문

match 표현식은 기존의 switch 문을 개선한 기능입니다. 값을 반환할 수 있고(표현식), 일치 여부를 확인할 때 엄격한 비교(===)를 사용합니다.

또한 break를 생략해도 다음 케이스로 넘어가지 않으며(No type coercion, No fallthrough), 코드가 훨씬 간결하고 가독성이 뛰어납니다.


👉 8. Nullsafe Operator

안전한 체이닝 (Optional Chaining)

Nullsafe 연산자(?->)는 객체의 메서드나 속성에 연쇄적으로 접근할 때 유용합니다. 중간에 어느 하나라도 null이면 에러를 발생시키지 않고 전체 평가를 멈춘 뒤 null을 반환합니다.

이 기능 덕분에 불필요한 null 체크 조건문(if 문)을 대폭 줄일 수 있습니다.


👉 11. Attributes

코드 내장 메타데이터

Attributes(어트리뷰트)는 기존에 주석(DocBlock)으로 처리하던 메타데이터를 언어 차원의 공식 문법으로 대체한 것입니다.

주석을 파싱하는 대신 Reflection API를 통해 구조적이고 타입 안전하게 클래스, 메서드, 속성에 추가 정보를 부여할 수 있어 프레임워크 설계 시 핵심적으로 사용됩니다.

Match 표현식 (PHP 8.0+)

과거: switch 문 switch ($status) { case 1: $msg = '대기'; break; case 2: $msg = '진행'; break; default: $msg = '완료'; } 현재: match 표현식 $msg = match ($status) { 1 => '대기', 2 => '진행', default => '완료', }; Break 필요 없음 / 값을 즉시 반환 엄격한 타입 비교 (===) 수행
// switch 문 대체
$status = 200;

$message = match($status) {
    200, 201 => 'Success',
    400 => 'Bad Request',
    404 => 'Not Found',
    500 => 'Server Error',
    default => 'Unknown Status',
};
의존성 주입

유연하고 테스트 가능한 설계

현대 PHP 개발의 핵심 패턴 중 하나는 의존성 주입(DI)입니다. 객체가 필요로 하는 의존성을 내부에서 직접 생성하지 않고 외부에서 주입받는 방식입니다.

이를 통해 모듈 간의 결합도를 낮추고 단위 테스트(Mocking)를 쉽게 만들 수 있습니다. 최신 프레임워크들은 강력한 DI Container를 내장하여 객체의 생성과 주입을 자동화합니다.

의존성 주입 (Dependency Injection)

강결합 (내부에서 생성) UserController new Database(); new Logger(); new Mailer(); 테스트 불가 / 교체 어려움 의존성 주입 (외부에서 주입) UserController __construct( Database $db, Logger $log ) DI Container (미리 만들어진 객체 창고) 주입(Inject)
// 의존성 주입 (DI)
class UserService {
    public function __construct(
        private UserRepository $repository
    ) {}
}

// DI 컨테이너가 의존성을 자동으로 해결
$userService = $container->get(UserService::class);
코드 품질 및 테스트

👉 13. Static Analysis

실행 전 버그 찾기

PHP는 인터프리터 언어이지만, PHPStan이나 Psalm 같은 정적 분석(Static Analysis) 도구를 통해 컴파일 언어 수준의 타입 안정성을 확보할 수 있습니다.

코드를 실행하지 않고도 타입 불일치, 정의되지 않은 메서드 호출, 논리적 오류 등을 사전에 탐지하여 프로젝트의 품질을 비약적으로 높여줍니다.


👉 14. Pest Testing Framework

아름답고 직관적인 테스팅

기존의 PHPUnit이 클래스 기반의 다소 무거운 구조였다면, Pest는 현대적이고 서술적인(fluent) 함수형 인터페이스를 제공하는 테스팅 프레임워크입니다.

마치 JavaScript의 Jest처럼 직관적으로 코드를 작성할 수 있어, 개발자들이 테스트 작성에 느끼는 진입 장벽을 크게 낮춰줍니다.

정적 분석 (Static Analysis - PHPStan)

PHP Source (타입 힌트 포함) PHPStan 코드 실행 없이 문맥/타입 오류 검출 Pass (성공) Fail (오류 리포트) 운영 서버 배포 전 치명적 버그를 사전 차단
bash
// 터미널에서 정적 분석 실행
// vendor/bin/phpstan analyse src

/** @var User $user */
// PHPStan이나 Psalm은 이러한 타입 정보와 코드를 
// 분석하여 실행 전에 잠재적 오류를 찾아냅니다.
Laravel 프레임워크 생태계

👉 15. Laravel Ecosystem

압도적인 생산성의 프레임워크

Laravel은 현대 PHP의 부흥을 이끈 가장 인기 있는 프레임워크입니다. 아름다운 문법과 강력한 ORM(Eloquent), 직관적인 템플릿 엔진(Blade)을 제공합니다.

또한 인증, 큐(Queue), 캐시, 브로드캐스팅 등 웹 개발에 필요한 모든 도구가 생태계 내에 완벽하게 통합되어 있어, 개발 생산성을 극대화합니다.


👉 16. Inertia.js & Livewire

모던 SPA의 새로운 접근법

전통적으로 SPA(Single Page Application)를 만들려면 백엔드 API를 구축하고 프론트엔드와 별도로 통신해야 했습니다.

Inertia.js는 API 구축 없이 React/Vue를 뷰 레이어로 사용하게 해주며, Livewire는 JavaScript 작성 거의 없이 PHP 코드만으로 리액티브한 동적 인터페이스를 만들 수 있게 해주는 혁신적인 도구입니다.

Laravel MVC 처리 흐름

Client Router Controller (C) 핵심 로직 Model DB (Eloquent) View (Blade) HTML 렌더링 후 반환
// Eloquent ORM 예시
$users = User::where('active', 1)
             ->orderBy('created_at', 'desc')
             ->get();

return view('users.index', ['users' => $users]);
고성능 런타임 및 배포

👉 17. Swoole / RoadRunner / FrankenPHP

PHP-FPM을 넘어서는 비동기 아키텍처

기존 PHP는 매 요청마다 스크립트를 새로 로드하는 'Share-Nothing' 아키텍처(PHP-FPM)를 사용했습니다.

하지만 Swoole, RoadRunner, FrankenPHP 같은 서버를 사용하면, Node.js나 Go처럼 애플리케이션을 메모리에 상주(Persistent)시키고 비동기 처리를 지원하여, 웹소켓 등 실시간 통신과 압도적인 처리 속도를 구현할 수 있습니다.


👉 18. JIT (Just-In-Time) Compilation

극한의 성능 최적화

PHP 8부터 도입된 JIT(Just-In-Time) 컴파일러는, 코드를 실행할 때 머신 코드로 컴파일하여 캐싱하는 기술입니다.

웹 애플리케이션보다는 CPU 집약적인 복잡한 연산, 이미지 처리, 머신러닝 등 특정 작업에서 C 언어에 버금가는 획기적인 성능 향상을 가져다줍니다.


👉 19. Dockerized Environment

일관된 개발 및 배포 환경

현대의 PHP 프로젝트는 내 PC에 직접 PHP를 설치하지 않고, Docker를 활용한 컨테이너 환경에서 개발합니다.

Laravel Sail 같은 도구를 사용하면, 운영체제에 상관없이 팀원 모두가 완벽하게 동일한 버전의 PHP, DB, Redis 환경을 클릭 한 번(또는 명령어 한 줄)으로 구성할 수 있습니다.

PHP-FPM vs Swoole/FrankenPHP

전통적 PHP-FPM Request 1 Boot -> Run -> Die Request 2 Boot -> Run -> Die 요청마다 프레임워크 부팅 (오버헤드 큼) Swoole / FrankenPHP 1번 부팅 Request 1 Run Request 2 Run 메모리에 상주하여 처리 (Node.js/Go 방식)
// FrankenPHP (Caddy 기반 PHP 앱 서버)
// 메모리에 상주하며 요청을 처리 (비동기, 고성능)

// 터미널 실행 예시
// ./frankenphp php-server
PHP 시작과 환경 구축

👉 PHP의 역사와 탄생

1995년
PHP 1.0 (FI) 라스무스 러도프가 개인 홈페이지 관리용 도구로 최초 공개.
1997년
PHP 3.0 파서를 재작성하여 진정한 언어의 기틀 마련. 명칭을 'PHP: Hypertext Preprocessor'로 변경.
2000년
PHP 4.0 Zend Engine 도입으로 성능 및 안정성 대폭 향상.
2004년
PHP 5.0 강력한 객체 지향 프로그래밍(OOP) 패러다임 전면 지원.
2015년
PHP 7.0 이전 버전 대비 성능 2배 향상 및 메모리 사용량 대폭 감소.
2020년 ~ 현재
PHP 8.0 🚀 JIT 컴파일러 도입, 타입 시스템 강화 및 성능 최적화!

PHP (Hypertext Preprocessor)는 1995년 라스무스 러도프(Rasmus Lerdorf)가 자신의 웹 이력서 방문자를 추적하기 위해 만든 C 언어 기반의 간단한 스크립트 모음(Personal Home Page Tools)에서 출발했습니다.

초기의 단순한 형태를 넘어, 전 세계 웹 서버의 70% 이상을 구동하는 가장 대표적인 오픈 소스 백엔드 언어로 성장했습니다.

💡 PHP의 철학

"PHP는 무엇보다도 실용적(Practical)이어야 한다. 개발자가 웹 애플리케이션을 최대한 빠르고 쉽게 만들 수 있도록 돕는 가장 큰 목표다."

👉 PHP 개발 환경 구축 (XAMPP/MAMP 설치)

PHP 첫걸음: 서버 환경 만들기 🛠️

PHP는 서버 측(Server-side) 스크립트 언어이므로, 내 컴퓨터를 서버처럼 동작하게 만들어주는 도구가 필요합니다.

  • XAMPP (Windows): Apache(웹 서버), MariaDB(데이터베이스), PHP를 한 번에 설치해 주는 통합 패키지입니다.
  • MAMP (Mac): Mac 환경에서 가장 널리 쓰이는 로컬 서버 환경 구축 도구입니다.

설치 후 htdocs 폴더에 .php 파일을 만들고 브라우저에서 localhost/파일명.php로 접속하면 실행됩니다.


👉 PHP 구문 기초와 Hello World 출력

PHP의 심장부: <?php ... ?> 🏁

PHP 코드는 항상 <?php로 시작해서 ?>로 끝납니다. 이 태그 밖의 내용은 일반 HTML로 취급됩니다.

화면에 무언가를 출력할 때는 주로 echo 또는 print를 사용합니다.

PHP 웹 서버 동작 원리

Client (Browser) HTTP Request Web Server (Apache/Nginx) PHP Interpreter index.php 실행 SQL Query MySQL HTML Response
<!-- htdocs/index.php 파일에 아래 코드를 작성합니다 -->
<h1>로컬 서버 구동 성공!</h1>
<?php
  // 서버 정보 출력하기
  phpinfo();
?>
변수와 데이터 타입

👉 변수 선언과 데이터 타입

데이터를 담는 그릇: 변수(Variable) 📦

PHP에서 변수는 달러 기호($)로 시작합니다. 자바스크립트나 C와 달리 자료형을 미리 선언할 필요가 없습니다. (동적 타입 언어)

  • String: 문자열 (따옴표 사용)
  • Integer: 정수 (소수점 없는 숫자)
  • Float/Double: 실수 (소수점 있는 숫자)
  • Boolean: 참(true) 또는 거짓(false)

👉 상수(Constant) 정의와 사용법

절대 변하지 않는 값: 상수 💎

상수는 한 번 값을 정하면 스크립트 실행 중에 절대로 변경할 수 없는 식별자입니다. 주로 사이트 이름이나 DB 접속 정보 등을 저장합니다.

define() 함수 또는 const 키워드를 사용합니다.

PHP 데이터 타입 체계도

Data Types Scalar (단일) int float string bool Compound (복합) array object callable Special (특수) null resource
<?php
    $name = "Minstudio"; // 문자열 (String)
    $age = 25;           // 정수 (Integer)
    $height = 175.5;     // 실수 (Float)
    $isDeveloper = true; // 불리언 (Boolean)

    echo "이름: " . $name . "<br>"; // 점(.)으로 문자열 연결
    echo "나이: $age 세";          // 큰따옴표 안에서는 변수 직접 파싱 가능
?>
연산자 종합

👉 산술, 대입, 증감 연산자

수학 시간으로 돌아가기: 연산자 ➕

데이터를 계산하고 가공할 때 사용하는 필수 기호들입니다.

  • 산술 연산자: +, -, *, /, % (나머지)
  • 대입 연산자: =, +=, -=, *= (값을 할당)
  • 증감 연산자: ++, -- (값을 1씩 올리거나 내림)

👉 비교 연산자와 논리 연산자

참과 거짓 판별하기 ⚖️

두 값을 비교하거나, 여러 조건을 결합할 때 사용합니다. 조건문(if)에서 핵심적인 역할을 합니다.

  • 비교: == (같다), === (타입까지 같다), != (다르다), >, <, >=, <=
  • 논리: && 또는 and (둘 다 참), || 또는 or (둘 중 하나라도 참), ! (반대)

논리 연산자 단축 평가 (Short-circuit)

false && heavy_function() 실행 안 됨 (생략) AND(&&)는 앞이 false면 뒤는 볼 필요 없이 무조건 false true || crash_system() 안전함 (생략) OR(||)는 앞이 true면 뒤는 볼 필요 없이 무조건 true
<?php
    $a = 10;
    $b = 3;

    echo "더하기: " . ($a + $b) . "<br>";
    echo "나머지: " . ($a % $b) . "<br>";

    $a += 5; // $a = $a + 5 와 동일 (15가 됨)
    echo "대입 후: $a <br>";

    $a++; // 1 증가
    echo "증가 후: $a";
?>
조건 분기문

👉 if, else, elseif 조건문

프로그램의 갈림길: 조건문 🛣️

특정 조건이 true일 때만 코드를 실행하고 싶다면 if를 사용합니다.

조건이 여러 개일 경우 elseif로 연결하며, 모든 조건이 맞지 않을 때는 else를 사용합니다.

<?php
    $score = 85;

    if ($score >= 90) {
        echo "A 등급입니다. 🌟";
    } elseif ($score >= 80) {
        echo "B 등급입니다. 👍";
    } elseif ($score >= 70) {
        echo "C 등급입니다. 😐";
    } else {
        echo "노력이 필요합니다. 📚";
    }
?>
localhost:8000/preview.php
B 등급입니다. 👍

👉 switch case 분기문

명확한 값 매칭: switch 🎛️

변수의 값이 정확히 특정 값(문자열, 숫자 등)과 일치할 때 실행할 코드를 정의합니다. if-elseif가 길어질 때 사용하면 가독성이 좋습니다.

<?php
    $grade = 'B';

    switch ($grade) {
        case 'A':
            echo "최우수 성적입니다.";
            break;
        case 'B':
            echo "우수한 성적입니다.";
            break;
        case 'C':
            echo "보통 성적입니다.";
            break;
        default:
            echo "재수강이 필요합니다.";
    }
?>
localhost:8000/preview.php
우수한 성적입니다.

if-elseif vs switch 흐름 비교

if / elseif (순차적 검사) if (x == 1) elseif (x == 2) elseif (x == 3) 최악의 경우밑바닥까지모두 검사함 switch (값에 따른 점프) switch (x) case 1: case 2: case 3: 한 번의 평가로 해당 case로 바로 점프 (해시)
반복문 제어

👉 while 및 do-while 반복문

무한 루프 조심! while 🔄

조건이 참(true)인 동안 코드를 계속 반복 실행합니다. do-while은 조건을 나중에 검사하므로 최소 1번은 무조건 실행되는 차이가 있습니다.


👉 for 반복문 기초

횟수가 정해진 반복: for 🎯

for (초기식; 조건식; 증감식) 구조로 작성하며, 반복 횟수가 명확할 때 가장 많이 쓰이는 반복문입니다.


👉 foreach와 배열 데이터 처리

배열의 단짝 친구: foreach 👯‍♀️

배열의 처음부터 끝까지 자동으로 순회하면서 값을 하나씩 꺼내줍니다. PHP에서 가장 사랑받는 배열 전용 반복문입니다.

for vs foreach 순회 구조

for (전통적 인덱스 방식) for ($i=0; $i<3; $i++) Array [ 0 => "A", 1 => "B", 2 => "C" ] $i 인덱스($i)를 하나씩 증가시키며 접근 foreach (배열 포인터 순회) foreach ($arr as $key => $val) "name" => "John" "age" => 30 "city" => "Seoul" 배열 내부 포인터가 다음 요소로 자동 전진 (문자열 Key인 연관 배열에 필수적)
<?php
    // 1부터 5까지 출력
    for ($i = 1; $i <= 5; $i++) {
        echo "반복 횟수: " . $i . "<br>";
    }

    echo "<br>";

    // 10부터 2씩 감소
    for ($k = 10; $k > 0; $k -= 2) {
        echo "카운트다운: $k<br>";
    }
?>
배열 완벽 가이드

👉 인덱스 배열과 연관 배열

숫자 방번호 vs 이름 방번호 🗄️

PHP의 배열은 크게 두 가지로 나뉩니다.

  • 인덱스 배열(Indexed Array): 0, 1, 2... 순서대로 숫자가 매겨지는 일반적인 배열입니다.
  • 연관 배열(Associative Array): 숫자 대신 '문자열(Key)'을 방 이름으로 사용하는 배열입니다. (JSON 객체와 유사함)

👉 다차원 배열의 이해와 활용

배열 안의 배열: 다차원 배열 🏢

하나의 배열 안에 또 다른 배열을 넣어서 복잡한 표(테이블) 구조의 데이터를 표현할 수 있습니다. 2차원 배열이 가장 흔히 쓰입니다.

배열의 종류: 인덱스 배열 vs 연관 배열

인덱스 배열 (Indexed Array) ['Apple', 'Banana', 'Cherry'] 0 "Apple" 1 "Banana" 2 "Cherry" 자동으로 0부터 시작하는 숫자 키 할당 연관 배열 (Associative Array) ['name' => 'John', 'age' => 25] "name" "John" "age" 25 "role" "Admin" 문자열 등 사용자가 지정한 키(Key) 사용
<?php
    // 1. 인덱스 배열
    $colors = array("Red", "Green", "Blue");
    echo "첫 번째 색상: " . $colors[0] . "<br>";

    // 2. 연관 배열 (=> 화살표 사용)
    $user = [
        "name" => "Kim",
        "age" => 30,
        "job" => "Developer"
    ];
    echo "사용자 이름: " . $user["name"]; // Key로 접근
?>
함수와 변수 스코프

👉 함수 정의와 매개변수, 반환값

코드 재사용의 꽃: 함수(Function) 🛠️

자주 사용하는 코드를 블록으로 묶어 이름을 붙여둔 것입니다. 원할 때마다 이름을 불러(호출) 실행할 수 있습니다.

재료를 넣어주면(매개변수 Parameter), 결과물을 내뱉습니다(반환값 Return).


👉 변수의 범위 (Local, Global, Static)

변수의 생명 주기와 활동 영역 🌐

변수는 선언된 위치에 따라 접근할 수 있는 범위(Scope)가 다릅니다.

  • Local(지역): 함수 안에서 선언. 밖에서는 못 씀!
  • Global(전역): 함수 밖에서 선언. 함수 안에서 쓰려면 global 키워드 필요!
  • Static(정적): 함수가 끝나도 값이 초기화되지 않고 유지됨.

👉 주요 내장 함수 (문자열, 숫자, 배열 관련)

바퀴를 다시 발명하지 마라: 내장 함수 ⚙️

PHP는 엄청나게 많은 기본 내장 함수를 제공합니다. 이를 잘 활용하면 수십 줄의 코드를 한 줄로 줄일 수 있습니다.

변수 스코프 (Local vs Global)

전역 스코프 (Global Scope) $msg = "Hello" 함수 스코프 (Local Scope) - function test() echo $msg; ← 에러! (접근 불가) global $msg; echo $msg; ← 정상 출력 ("Hello")
<?php
    // 함수 정의
    function calculateSum($a, $b) {
        $result = $a + $b;
        return $result; // 결과 반환
    }

    // 함수 호출
    $total = calculateSum(10, 20);
    echo "10 + 20 = $total <br>";

    // 기본값이 있는 매개변수
    function greet($name = "손님") {
        echo "안녕하세요, $name 님!";
    }
    greet(); // 손님 출력
?>
웹 폼(Form) 데이터 처리

👉 HTML Form 태그와 PHP 연동 기초

사용자와 소통하기 🗣️

웹 개발의 핵심은 사용자가 HTML <form>에 입력한 데이터를 서버(PHP)가 받아서 처리하는 것입니다.


👉 $_GET과 $_POST 전역 변수 활용

데이터 전달의 양대 산맥 ⛰️

  • $_GET: URL 주소 끝에 파라미터(?id=1&name=kim)로 데이터를 달아서 보냅니다. (검색, 공유용)
  • $_POST: HTTP 본문 안에 데이터를 숨겨서 보냅니다. 길이 제한이 없고 보안에 유리합니다. (로그인, 회원가입용)

GET vs POST 전송 방식 차이

Browser Form id: admin pw: 1234 PHP Server GET 방식 (URL에 노출) login.php?id=admin&pw=1234 ! POST 방식 (HTTP Body에 숨김) Header: POST /login.php Body: id=admin&pw=1234
<!-- 폼 HTML (index.html 역할) -->
<form action="process.php" method="POST">
    이름: <input type="text" name="username">
    <button type="submit">전송</button>
</form>

<?php
    /* process.php 파일 내부 */
    // 사용자가 전송 버튼을 눌렀을 때만 처리
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        // 전송된 데이터 받기
        $name = $_POST["username"];
        echo "환영합니다, $name 님!";
    }
?>
상태 관리 (Session & Cookie)

👉 세션(Session) 시작과 정보 관리

나를 기억해줘: 세션 🧠

웹 서버는 사용자가 누군지 기억하지 못합니다(Stateless). 세션은 서버 메모리에 사용자의 정보를 저장하여 로그인 상태 등을 유지하는 기술입니다.

모든 세션 사용 전에는 반드시 session_start()가 호출되어야 합니다.


👉 쿠키(Cookie) 설정 및 삭제

내 컴퓨터에 남는 흔적: 쿠키 🍪

세션이 '서버'에 저장된다면, 쿠키는 사용자의 웹 브라우저(로컬)에 저장되는 작은 텍스트 조각입니다. (예: "7일간 보지 않기", 장바구니)

Session vs Cookie 동작 원리

클라이언트 (브라우저) Cookie Storage 일반 쿠키 (위변조 위험) theme=dark 세션 식별자 (중요!) PHPSESSID=1a2b3c 모든 요청에 쿠키 포함 전송 식별자(PHPSESSID)로 세션 조회 서버 (PHP / DB) Session Storage Session ID: 1a2b3c user_id = admin role = root (서버에만 저장되어 안전)
<?php
    // 1. 세션 엔진 가동! (파일 맨 꼭대기에 위치해야 함)
    session_start();

    // 2. 세션 변수 굽기 (로그인 처리)
    $_SESSION["userid"] = "admin123";
    $_SESSION["role"] = "manager";

    // 3. 세션 읽기
    echo "현재 로그인된 아이디: " . $_SESSION["userid"] . "<br>";

    // 4. 세션 삭제 (로그아웃 처리)
    session_unset();  // 변수 비우기
    session_destroy(); // 세션 완전 파괴
?>
파일 시스템 제어

DB 없이 데이터 보관하기: 파일 I/O 📁

텍스트 파일을 읽어오거나 텍스트를 파일에 저장할 수 있습니다. 로그(Log)를 남길 때 주로 사용됩니다.

파일 입출력 생명주기

fopen() 파일 열기 (스트림 생성) fread() 읽기 (r) fwrite() 쓰기 (w, a) fclose() 파일 닫기 (메모리 해제)
<?php
    $filename = "log.txt";

    // 1. 파일 쓰기 (w: 덮어쓰기, a: 이어쓰기)
    $file = fopen($filename, "a") or die("파일을 열 수 없습니다.");
    $txt = "새로운 로그 기록 - " . date("H:i:s") . "\n";
    fwrite($file, $txt);
    fclose($file);

    // 2. 파일 존재 여부 확인 후 읽기
    if (file_exists($filename)) {
        // file_get_contents: 파일 내용을 한 번에 문자열로 가져옴
        echo nl2br(file_get_contents($filename));
    }
?>
모듈화 기법

조립식 웹사이트 만들기 🧩

헤더, 푸터, DB 접속 코드처럼 모든 페이지에 공통으로 들어가는 코드를 별도의 파일로 빼서 불러옵니다.

  • include: 파일을 못 찾아도 경고만 띄우고 계속 실행합니다.
  • require: 파일을 못 찾으면 치명적 오류를 내고 즉시 중단합니다. (DB 접속 등에 사용)

include vs require 에러 처리 차이

파일이 없을 때 include Warning 발생하지만 스크립트는 계속 실행 require Fatal Error! (실행 중지)
<!-- header.php 파일 -->
<header><h1>내 사이트</h1></header>

<?php
    // index.php 메인 파일에서 불러오기
    include 'header.php'; // 헤더 UI 불러오기
    
    // DB 연결은 없으면 큰일나므로 require_once 사용 (한 번만 로드)
    require_once 'db_connect.php'; 
    
    echo "<main>메인 콘텐츠</main>";
?>
유틸리티 및 디버깅

👉 date 함수를 이용한 날짜와 시간 처리

시간을 지배하는 자 ⏰

게시글 작성 시간, 로그 기록 등을 남길 때 date() 함수를 사용하여 타임스탬프를 읽기 쉬운 문자열로 변환합니다.


👉 header 함수를 이용한 페이지 이동(Redirection)

다른 페이지로 강제 전송! 🚀

로그인을 성공했거나, 권한이 없는 페이지에 접근했을 때 브라우저의 URL을 강제로 변경하여 이동시킵니다.

⚠️ 주의: header() 함수 이전에 HTML이나 공백이 단 1글자라도 출력되면(echo) 에러가 발생합니다.


👉 기초적인 에러 메시지 확인 및 디버깅 방법

버그와의 전쟁 🐛

PHP는 기본적으로 실서버 환경에서 보안을 위해 에러 메시지를 숨깁니다. 하지만 개발 중에는 에러를 화면에 띄워야 문제를 고칠 수 있습니다.

HTTP Redirection 원리

클라이언트 PHP 서버 login.php index.php 1. 로그인 성공 시 2. 302 Found & Location: index.php (header() 함수 실행) 3. 브라우저가 새 주소로 자동 재요청
<?php
    $isLoggedIn = false;

    if (!$isLoggedIn) {
        // 권한이 없으므로 로그인 페이지로 강제 튕겨내기
        header("Location: login.php?error=need_login");
        
        // 리다이렉션 후 아래 코드가 실행되지 않도록 프로그램 강제 종료!
        exit; 
    }

    echo "비밀 관리자 페이지입니다.";
?>
모던 PHP 표준 생태계
타입 시스템의 원리와 이해
객체 지향 문법 업데이트
새로운 표현식과 편의 기능
의존성 주입
코드 품질 및 테스트
Laravel 프레임워크 생태계
고성능 런타임 및 배포
PHP 시작과 환경 구축
변수와 데이터 타입
연산자 종합
조건 분기문
반복문 제어
배열 완벽 가이드
함수와 변수 스코프
웹 폼(Form) 데이터 처리
상태 관리 (Session & Cookie)
파일 시스템 제어
모듈화 기법
유틸리티 및 디버깅

목차