PHP

PHP

    course-modernization-guide

    PHP 강의 현대화 가이드 (PHP 5.x → PHP 8.x, 2026년 기준)

    이 문서는 기존 PHP 5.x 기반 강의를 2026년 현업 표준에 맞게 전면 개편하기 위한 상세 가이드입니다.
    강사와 콘텐츠 기여자 모두를 대상으로 작성되었습니다.


    목차

    1. 왜 지금 개편해야 하는가
    2. 반드시 제거해야 할 레거시 기능
    3. 반드시 도입해야 할 현대 기능
    4. 모듈 구조 재설계
    5. Vanilla PHP vs 프레임워크 선택 가이드
    6. 개편 우선순위 로드맵

    1. 왜 지금 개편해야 하는가

    PHP 버전 지원 현황 (2026년 기준)

    버전출시지원 종료상태
    PHP 5.620142018년 종료완전 폐기
    PHP 7.420192022년 종료폐기
    PHP 8.020202023년 종료폐기
    PHP 8.120212025년 종료Security only
    PHP 8.220222026년 12월현재 지원
    PHP 8.320232027년 12월현재 권장
    PHP 8.420242028년 12월최신 안정 버전

    기존 강의의 PHP 5.x 코드는 현재 모든 프로덕션 환경에서 실행 자체가 불가능합니다.
    특히 mysql_* 함수는 PHP 7.0에서 완전 제거되어 학습자가 그대로 따라 하면 오류만 발생합니다.


    2. 반드시 제거해야 할 레거시 기능

    2-1. mysql_* 함수 전체 — 최우선 제거 대상

    PHP 7.0에서 완전 삭제된 함수들입니다. 강의 내 모든 예제를 교체해야 합니다.

    // ❌ 절대 사용 금지 (PHP 7.0+ 에서 Fatal Error)
    $conn = mysql_connect("localhost", "root", "password");
    mysql_select_db("mydb");
    $result = mysql_query("SELECT * FROM users");
    $row = mysql_fetch_array($result);
    mysql_close($conn);
    
    // ✅ PDO로 교체 (권장)
    $pdo = new PDO("mysql:host=localhost;dbname=mydb;charset=utf8mb4", "root", "password", [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ]);
    $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
    $stmt->execute([$id]);
    $row = $stmt->fetch();
    
    // ✅ MySQLi로 교체 (차선책)
    $conn = new mysqli("localhost", "root", "password", "mydb");
    $conn->set_charset("utf8mb4");
    $stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
    $stmt->bind_param("i", $id);
    $stmt->execute();
    $result = $stmt->get_result();
    $row = $result->fetch_assoc();
    

    PDO를 권장하는 이유: MySQL뿐 아니라 PostgreSQL, SQLite 등 여러 DB를 동일한 코드로 다룰 수 있어 이식성이 높습니다.


    2-2. Short Open Tag <? — 제거

    short_open_tag 옵션에 의존하는 코드는 환경마다 동작이 달라집니다.

    // ❌ 환경 의존적, 사용 금지
    <? echo $name; ?>
    
    // ✅ 항상 표준 태그 사용
    <?php echo $name; ?>
    
    // ✅ echo 단축 태그는 PHP 5.4+부터 short_open_tag와 무관하게 항상 사용 가능
    <?= $name ?>
    

    2-3. 구버전 슈퍼전역변수 — 제거

    PHP 5.4에서 완전 삭제된 변수들입니다.

    // ❌ 삭제됨
    $HTTP_POST_VARS['name']
    $HTTP_GET_VARS['id']
    $HTTP_SERVER_VARS['REMOTE_ADDR']
    
    // ✅ 슈퍼전역변수 사용
    $_POST['name']
    $_GET['id']
    $_SERVER['REMOTE_ADDR']
    

    2-4. 클래스 프로퍼티 var 키워드 — 교체

    // ❌ PHP 4 스타일 — 가시성(visibility) 명시 없음
    class User {
        var $name;
        var $email;
    }
    
    // ✅ 명시적 가시성 키워드 사용
    class User {
        public string $name;
        protected string $email;
        private int $id;
    }
    

    2-5. 인용부호 없는 배열 키 — 수정

    // ❌ PHP 8.0+ 에서 오류 발생
    echo $row[name];
    echo $_GET[id];
    
    // ✅ 반드시 문자열 키에 따옴표 사용
    echo $row['name'];
    echo $_GET['id'];
    

    2-6. SQL 직접 삽입 (SQL Injection) — 보안 취약점 제거

    강의 내 모든 SQL 예제에 보안 취약점이 있습니다.

    // ❌ SQL Injection 취약점 — 절대 사용 금지
    $id = $_GET['id'];
    $result = mysql_query("SELECT * FROM board WHERE id=$id");
    
    // ✅ PDO Prepared Statement 사용
    $id = (int) $_GET['id']; // 타입 캐스팅도 함께
    $stmt = $pdo->prepare("SELECT * FROM board WHERE id = :id");
    $stmt->execute([':id' => $id]);
    $row = $stmt->fetch();
    

    2-7. ereg_* 정규표현식 함수 — 제거

    PHP 7.0에서 완전 삭제되었습니다.

    // ❌ 삭제됨
    ereg("^[a-z]+$", $str);
    ereg_replace("[^a-z]", "", $str);
    
    // ✅ PCRE 함수 사용
    preg_match("/^[a-z]+$/", $str);
    preg_replace("/[^a-z]/", "", $str);
    

    2-8. create_function() — 제거

    PHP 8.0에서 완전 삭제되었습니다.

    // ❌ 삭제됨
    $fn = create_function('$x', 'return $x * 2;');
    
    // ✅ 익명 함수(클로저) 또는 화살표 함수 사용
    $fn = fn($x) => $x * 2;
    

    3. 반드시 도입해야 할 현대 기능

    3-1. 타입 선언 (Type Declarations) — PHP 7.0+

    PHP는 이제 사실상 타입이 있는 언어입니다. 타입 선언은 버그를 사전에 차단하는 가장 효과적인 방법입니다.

    <?php
    declare(strict_types=1); // 파일 최상단에 반드시 선언
    
    // 매개변수 타입 + 반환 타입
    function getUser(int $id): ?array {
        // int가 아닌 값이 들어오면 TypeError 발생
    }
    
    // 프로퍼티 타입 (PHP 7.4+)
    class User {
        public int $id;
        public string $name;
        public ?string $bio = null; // nullable
    }
    
    // Union 타입 (PHP 8.0+)
    function process(int|string $input): void { }
    
    // Intersection 타입 (PHP 8.1+)
    function save(Countable&Iterator $collection): void { }
    

    3-2. Named Arguments — PHP 8.0+

    함수 호출 시 매개변수 이름을 명시해 가독성을 높입니다.

    // ❌ 순서를 외워야 하는 기존 방식
    array_slice($array, 0, 10, true);
    
    // ✅ Named Arguments — 순서 무관, 의미 명확
    array_slice(array: $array, offset: 0, length: 10, preserve_keys: true);
    

    3-3. Match 표현식 — PHP 8.0+

    switch의 개선된 대안입니다. 엄격한 비교(===)를 사용하고 값을 반환합니다.

    // ❌ 기존 switch — 느슨한 비교, fall-through 위험
    switch ($status) {
        case 1:
            $label = '활성';
            break;
        case 2:
            $label = '비활성';
            break;
        default:
            $label = '알 수 없음';
    }
    
    // ✅ match — 엄격한 비교, 표현식으로 값 반환
    $label = match($status) {
        1       => '활성',
        2       => '비활성',
        default => '알 수 없음',
    };
    

    3-4. Nullsafe 연산자 (?->) — PHP 8.0+

    중첩된 null 체크를 단순화합니다.

    // ❌ 기존 방식 — 중첩 if 지옥
    $city = null;
    if ($user !== null) {
        if ($user->getAddress() !== null) {
            $city = $user->getAddress()->getCity();
        }
    }
    
    // ✅ Nullsafe 연산자
    $city = $user?->getAddress()?->getCity();
    

    3-5. Constructor Property Promotion — PHP 8.0+

    생성자에서 프로퍼티 선언과 초기화를 동시에 처리합니다.

    // ❌ 기존 방식 — 반복 코드
    class User {
        public int $id;
        public string $name;
        public string $email;
    
        public function __construct(int $id, string $name, string $email) {
            $this->id    = $id;
            $this->name  = $name;
            $this->email = $email;
        }
    }
    
    // ✅ Constructor Promotion — 한 줄로 선언 + 초기화
    class User {
        public function __construct(
            public readonly int    $id,
            public readonly string $name,
            public string          $email,
        ) {}
    }
    

    3-6. Enum — PHP 8.1+

    마법 상수(define, const 배열)를 대체하는 타입 안전한 열거형입니다.

    // ❌ 기존 방식 — 타입 안전성 없음
    define('STATUS_ACTIVE',   1);
    define('STATUS_INACTIVE', 2);
    define('STATUS_PENDING',  3);
    
    // ✅ Enum — 타입 안전, IDE 자동완성 지원
    enum UserStatus: int {
        case Active   = 1;
        case Inactive = 2;
        case Pending  = 3;
    
        public function label(): string {
            return match($this) {
                self::Active   => '활성',
                self::Inactive => '비활성',
                self::Pending  => '대기 중',
            };
        }
    }
    
    $status = UserStatus::Active;
    echo $status->label(); // "활성"
    

    3-7. Readonly Properties — PHP 8.1+

    불변 값 객체(Value Object) 구현에 필수입니다.

    class UserId {
        public function __construct(
            public readonly int $value,
        ) {}
    }
    
    $id = new UserId(42);
    $id->value = 99; // Error: Cannot modify readonly property
    

    3-8. Fibers — PHP 8.1+

    비동기 코드 패턴의 기반이 됩니다. (ReactPHP, Amp, Swoole과 연계)

    $fiber = new Fiber(function(): void {
        $value = Fiber::suspend('첫 번째 중단');
        echo "재개 값: $value\n";
    });
    
    $result = $fiber->start();       // "첫 번째 중단" 반환
    $fiber->resume('안녕하세요');   // "재개 값: 안녕하세요" 출력
    

    3-9. declare(strict_types=1) 습관화

    <?php
    declare(strict_types=1);
    // 이 한 줄이 암묵적 타입 변환을 막아 숨겨진 버그를 사전에 차단합니다.
    

    3-10. Composer와 Autoloading — 필수 도구

    PHP 현대 개발의 가장 기초적인 도구입니다. 반드시 강의에 포함해야 합니다.

    # 패키지 설치
    composer require vlucas/phpdotenv
    
    # 개발 의존성 설치
    composer require --dev phpunit/phpunit pestphp/pest
    
    // composer.json — PSR-4 오토로딩 설정
    {
        "autoload": {
            "psr-4": {
                "App\\": "src/"
            }
        }
    }
    

    3-11. 환경 변수 관리 (.env) — 보안 필수

    // ❌ 기존 방식 — 하드코딩된 비밀번호
    $conn = mysql_connect("localhost", "root", "1234");
    
    // ✅ .env 파일로 분리
    // .env
    DB_HOST=localhost
    DB_USER=root
    DB_PASS=secret
    DB_NAME=myapp
    
    // PHP
    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    $dotenv->load();
    
    $pdo = new PDO(
        "mysql:host={$_ENV['DB_HOST']};dbname={$_ENV['DB_NAME']};charset=utf8mb4",
        $_ENV['DB_USER'],
        $_ENV['DB_PASS'],
    );
    

    3-12. PSR 표준 준수

    현업에서 통용되는 PHP 코딩 표준입니다.

    PSR내용적용 도구
    PSR-1기본 코딩 표준PHP CS Fixer
    PSR-2/12코딩 스타일 가이드PHP CS Fixer
    PSR-4오토로딩 표준Composer
    PSR-7HTTP 메시지 인터페이스Guzzle, Slim
    PSR-11DI 컨테이너Laravel, Symfony
    PSR-15HTTP 미들웨어Slim, Laminas

    4. 모듈 구조 재설계

    기존 구조의 문제점

    기존: 개발환경 → 기초문법 → 게시판 만들기 (단순 절차형)
    
    • mysql_* 함수 기반의 절차형 코드만 다룸
    • 보안(SQL Injection, XSS 등) 개념 전무
    • 객체지향 프로그래밍 미흡
    • 테스트, 배포, 현업 워크플로우 없음
    • Composer, 프레임워크 등 현대 생태계 미포함

    새로운 커리큘럼 구조


    1단계 — 개발 환경 (신입 ~ 입문)

    #주제핵심 내용
    1-1PHP란 무엇인가PHP 8.x의 위치, 생태계, 사용 사례
    1-2개발 환경 구성Docker + PHP 8.3 + MySQL 8 (XAMPP 대신 Docker 권장)
    1-3에디터 설정VS Code + PHP Intelephense + PHP CS Fixer 자동화
    1-4Composer 입문패키지 설치, autoload, vendor/ 이해
    1-5첫 번째 PHP 프로그램declare(strict_types=1) 습관 포함

    2단계 — 기초 문법 (입문 ~ 초급)

    #주제핵심 내용
    2-1변수와 타입타입 선언, strict_types, 타입 캐스팅
    2-2연산자와 우선순위Nullish coalescing (??), Spaceship (<=>)
    2-3제어문match 표현식, if/else, for, foreach
    2-4함수타입 힌트, 반환 타입, 화살표 함수(fn)
    2-5배열구조 분해 할당, spread 연산자, array 함수
    2-6문자열Heredoc, Nowdoc, str_contains, str_starts_with
    2-7에러 처리try/catch/finally, Throwable, 사용자 정의 예외

    3단계 — 객체지향 프로그래밍 (초급 ~ 중급)

    #주제핵심 내용
    3-1클래스와 객체Constructor Promotion, readonly, 가시성
    3-2상속과 인터페이스abstract, interface, trait
    3-3매직 메서드__construct, __toString, __invoke
    3-4네임스페이스PSR-4, use, 오토로딩
    3-5EnumBacked Enum, 메서드 포함 Enum
    3-6SOLID 원칙단일 책임, 의존성 역전 원칙 실습

    4단계 — 데이터베이스 (중급)

    #주제핵심 내용
    4-1PDO 기초연결, Prepared Statement, fetch 모드
    4-2PDO 실전CRUD 작성, 트랜잭션
    4-3SQL Injection 방어Prepared Statement의 원리
    4-4데이터베이스 설계정규화, 인덱스, utf8mb4 설정
    4-5마이그레이션 개념수동 SQL 마이그레이션 → Phinx 소개

    5단계 — 웹 개발 실전 (중급)

    #주제핵심 내용
    5-1HTTP 기초요청/응답, 헤더, 상태 코드
    5-2폼 처리와 보안XSS 방어(htmlspecialchars), CSRF 토큰, 입력 검증
    5-3쿠키와 세션session_regenerate_id(), 세션 하이재킹 방어
    5-4파일 업로드MIME 타입 검증, 파일명 보안, 저장 위치
    5-5REST API 기초JSON 응답, HTTP 메서드, 상태 코드 설계
    5-6환경 변수 관리.env, vlucas/phpdotenv

    6단계 — 현대적 PHP 프로젝트 (중급 ~ 고급)

    #주제핵심 내용
    6-1라우터 구현직접 구현해보기 → Slim Framework 소개
    6-2미들웨어 패턴PSR-15, 인증/로깅 미들웨어
    6-3의존성 주입(DI)수동 DI → PHP-DI 컨테이너
    6-4테스트 입문PHPUnit, Pest 기초, TDD 개념
    6-5배포GitHub Actions / GitLab CI, PHP-FPM + Nginx
    6-6보안 점검OWASP Top 10 PHP 관점 정리

    5. Vanilla PHP vs 프레임워크 선택 가이드

    학습 관점

    Vanilla PHP 먼저 → 프레임워크는 나중
    

    프레임워크가 내부에서 무엇을 하는지 이해하려면 Vanilla PHP 기반 지식이 반드시 필요합니다.
    라우팅, DI 컨테이너, ORM의 원리를 모른 채 프레임워크를 배우면 "마법사 신드롬"에 빠집니다.

    프레임워크 선택 기준 (2026년 기준)

    LaravelSymfonySlimLaminas
    학습 곡선낮음높음매우 낮음높음
    커뮤니티매우 활발활발보통보통
    국내 채용 수요매우 높음중간낮음낮음
    용도풀스택 웹앱엔터프라이즈마이크로 API엔터프라이즈
    ORMEloquentDoctrine없음(선택)Laminas DB
    PHP 최소 요구PHP 8.2+PHP 8.1+PHP 7.4+PHP 8.1+

    강의 적용 권장안

    [4단계까지] — 순수 PHP + PDO로 진행
        ↓
    [5단계] — Slim Framework로 라우팅 + REST API 구현
        ↓
    [별도 Laravel 트랙] — Eloquent ORM, Blade, Artisan, Queue 등
    

    Laravel을 선택해야 하는 경우

    • 국내 스타트업/중소기업 취업 목표
    • 빠른 프로토타이핑이 필요한 프로젝트
    • 풀스택 개발자를 목표로 하는 학습자
    • 활발한 패키지 생태계(Cashier, Telescope, Horizon 등) 활용

    Symfony를 선택해야 하는 경우

    • 대기업/금융/공공 프로젝트 목표
    • Laravel의 내부 구조를 더 깊이 이해하고 싶을 때 (Laravel이 Symfony 컴포넌트를 다수 사용)
    • 컴포넌트 단위로 필요한 것만 골라 쓰고 싶을 때

    Vanilla PHP(+ Slim)으로 충분한 경우

    • 간단한 REST API 서버
    • 레거시 시스템 유지보수
    • PHP 내부 원리 학습 목적
    • 소규모 사이드 프로젝트

    6. 개편 우선순위 로드맵

    Phase 1 — 즉시 수행 (긴급)

    • [ ] mysql_* → PDO/MySQLi 전환 (백업 강의 전체)
    • [ ] Short tag <? → <?php 교체
    • [ ] $HTTP_POST_VARS 등 구버전 슈퍼전역변수 제거
    • [ ] SQL Injection 취약 예제 전면 교체
    • [ ] 개발 환경을 XAMPP → Docker 기반으로 전환

    Phase 2 — 단기 (1~2개월)

    • [ ] 타입 선언 + strict_types 예제 전면 도입
    • [ ] var 키워드 → 명시적 가시성으로 교체
    • [ ] Composer + Autoloading 모듈 신규 추가
    • [ ] PDO Prepared Statement 전용 모듈 추가
    • [ ] 세션/쿠키 보안 강화 예제 업데이트

    Phase 3 — 중기 (2~4개월)

    • [ ] OOP 모듈 강화 (Enum, Readonly, Constructor Promotion)
    • [ ] match 표현식, Named Arguments, Nullsafe 연산자 추가
    • [ ] REST API 모듈 신규 작성
    • [ ] PHPUnit/Pest 테스트 기초 모듈 추가
    • [ ] GitLab CI 배포 파이프라인 강의 추가

    Phase 4 — 장기 (4개월+)

    • [ ] Laravel 입문 트랙 신설
    • [ ] OWASP Top 10 PHP 보안 모듈 신설
    • [ ] PHP 8.4 신기능 (Property Hooks, Asymmetric Visibility) 추가
    • [ ] 비동기 PHP (Fibers, ReactPHP 또는 Swoole) 소개 모듈

    참고 자료

    • PHP 공식 문서
    • PHP: The Right Way
    • PHP 버전 지원 일정
    • Laravel 공식 문서
    • Symfony 공식 문서
    • Composer 공식 문서
    • PSR 표준 목록
    • OWASP PHP 보안 가이드
    Last updated on 2026-4-19 by Myeongjin Cho
    • 목차
    • 1. 왜 지금 개편해야 하는가
      • PHP 버전 지원 현황 (2026년 기준)
    • 2. 반드시 제거해야 할 레거시 기능
      • 2-1. mysql_* 함수 전체 — 최우선 제거 대상
      • 2-2. Short Open Tag <? — 제거
      • 2-3. 구버전 슈퍼전역변수 — 제거
      • 2-4. 클래스 프로퍼티 var 키워드 — 교체
      • 2-5. 인용부호 없는 배열 키 — 수정
      • 2-6. SQL 직접 삽입 (SQL Injection) — 보안 취약점 제거
      • 2-7. ereg_* 정규표현식 함수 — 제거
      • 2-8. create_function() — 제거
    • 3. 반드시 도입해야 할 현대 기능
      • 3-1. 타입 선언 (Type Declarations) — PHP 7.0+
      • 3-2. Named Arguments — PHP 8.0+
      • 3-3. Match 표현식 — PHP 8.0+
      • 3-4. Nullsafe 연산자 (?->) — PHP 8.0+
      • 3-5. Constructor Property Promotion — PHP 8.0+
      • 3-6. Enum — PHP 8.1+
      • 3-7. Readonly Properties — PHP 8.1+
      • 3-8. Fibers — PHP 8.1+
      • 3-9. declare(strict_types=1) 습관화
      • 3-10. Composer와 Autoloading — 필수 도구
      • 3-11. 환경 변수 관리 (.env) — 보안 필수
      • 3-12. PSR 표준 준수
    • 4. 모듈 구조 재설계
      • 기존 구조의 문제점
      • 새로운 커리큘럼 구조
    • 5. Vanilla PHP vs 프레임워크 선택 가이드
      • 학습 관점
      • 프레임워크 선택 기준 (2026년 기준)
      • 강의 적용 권장안
    • 6. 개편 우선순위 로드맵
      • Phase 1 — 즉시 수행 (긴급)
      • Phase 2 — 단기 (1~2개월)
      • Phase 3 — 중기 (2~4개월)
      • Phase 4 — 장기 (4개월+)
    • 참고 자료
    커뮤니티
    PHP 공식 웹사이트한국 PHP 개발자 커뮤니티
    유용한 정보
    책 소스 코드
    Copyright © 2026 EZPHP.NET