PHP 신규 프로젝트를 배포하거나 라이브러리를 추가한 뒤 Fatal error: Uncaught Error: Class 'App\Services\UserService' not found 같은 치명적 에러를 마주쳐 당황했던 경험이 있으신가요?
대부분의 개발자들은 단순한 파일 경로 문제로 지레짐작하고 require_once를 남발하지만, 정작 원인이 Composer 오토로더(Autoloader) 캐시나 PSR-4 네임스페이스 대소문자 불일치라는 사실을 모르는 경우가 많습니다.
이번 글에서는 이 에러가 정확히 왜 발생하는지 원인을 철저히 분석하고, 네임스페이스와 Composer 오토로딩 체계를 올바르게 정립하여 에러를 깔끔하게 해결하는 방법을 완벽하게 정리해서 소개하겠습니다.

 

1단계: Class not found 에러 발생 원인 이해하기

PHP에서 Fatal error: Uncaught Error: Class '...' not found 에러는 스크립트 실행 중 객체를 생성(new ClassName())하거나 정적 메서드를 호출하려고 할 때, 해당 클래스 정의를 인터프리터가 메모리상에서 찾지 못하면 발생합니다.
과거 PHP 5 이전 시절에는 외부 파일의 클래스를 가져오기 위해 모든 PHP 파일 상단에 requireinclude를 일일이 작성해야 했습니다.
하지만 modern PHP(PHP 7/8) 환경에서는 표준 규격인 PSR-4 오토로딩 체계를 사용하므로, 파일 경로와 네임스페이스가 1:1로 정확히 매핑되어야만 클래스를 정상적으로 불러올 수 있습니다.

 

주요 발생 원인 3가지 한눈에 보기
발생 원인상세 내용대표적인 증상
네임스페이스/파일명 대소문자 불일치리눅스 OS 환경은 대소문자를 엄격히 구분함로컬(Windows/Mac)에서는 정상 동작하나 운영 서버 배포 시 에러 발생
Composer Classmap 미갱신새 클래스 파일 작성 후 오토로더 캐시를 갱신하지 않음composer.json에는 정상이지만 클래스를 인식하지 못함
PSR-4 매핑 디렉터리 경로 오류composer.jsonautoload.psr-4 설정 오류네임스페이스의 루트 경로와 실제 폴더 구조가 다름

 

2단계: 에러 해결을 위한 단계별 점검 체계

이 에러를 만났을 때 당황하지 않고 체계적으로 해결할 수 있는 단계별 점검 방법입니다.

1. 네임스페이스 및 use 구문 확인: 클래스 상단의 namespace 선언과 호출하는 파일의 use 구문 스펠링 및 대소문자가 정확한지 검증합니다.
2. composer.json 오토로드 설정 확인: autoload 항목에 설정된 PSR-4 네임스페이스와 실제 디렉터리 구조가 동일한지 점검합니다.
3. Composer Dump-Autoload 실행: 클래스 맵 및 PSR-4 덤프 파일 재생성을 위해 CLI 명령어를 실행합니다.
4. vendor/autoload.php 로드 여부 체크: 진입점 파일(index.php)에 Composer의 오토로더 파일이 require 되어 있는지 확인합니다.

 

3단계: 실전 코드 예제와 올바른 해결법

실무에서 흔히 저지르는 잘못된 코드 패턴과 이를 PSR-4 규칙에 맞게 올바르게 수정한 코드를 비교해 보겠습니다.

 

잘못된 구현 및 올바른 해결 예제

✗ 잘못된 코드 (네임스페이스 및 폴더 대소문자 불일치, composer.json 미반영)

<?php
// File: src/services/userservice.php (소문자 파일명 및 폴더)
namespace app\services; // 대소문자가 표준과 다름

class userService {
    public function getUser() {
        return "홍길동";
    }
}

// File: index.php
require_once __DIR__ . '/vendor/autoload.php';

// 존재하지 않는 대소문자 네임스페이스 호출로 Class not found 에러 발생!
$service = new App\Services\UserService();
?>

✓ 올바른 코드 (PSR-4 표준 준수 및 composer.json 설정)

// 1. composer.json 설정
{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

// 2. File: src/Services/UserService.php (PSR-4 규칙: 대소문자 정확히 일치)
<?php
namespace App\Services;

class UserService {
    public function getUser(): string {
        return "홍길동";
    }
}

// 3. File: public/index.php (오토로더 로드 및 정교한 use 구문)
<?php
require_once __DIR__ . '/../vendor/autoload.php';

use App\Services\UserService;

$service = new UserService();
echo $service->getUser();
?>

실행 결과 / 출력값:

# CLI terminal에서 오토로더 갱신 명령 실행
$ composer dump-autoload -o
Generating optimized autoload files (including classmaps)
Classmap successfully generated.

# index.php 실행 결과
홍길동

 

4단계: 흔히 범하는 실수와 주의사항

개발 과정에서 개발자들이 자주 놓치는 3가지 치명적인 실수입니다.

로컬(Mac/Windows)에서는 작동하는데 운영 서버(Linux)에서만 에러가 발생하는 경우:
Mac과 Windows 파일 시스템은 기본적으로 대소문자를 구분하지 않거나 보존형(Case-insensitive)입니다. 반면 Linux는 대소문자를 엄격히 구분합니다. 파일명이 Userservice.php이고 네임스페이스가 UserService이면 로컬에서는 작동하지만 서버에서는 바로 Class not found 에러가 터집니다.

새 클래스 추가 후 composer dump-autoload를 실행하지 않는 실수:
Classmap 방식을 혼용하거나 최적화 모드(-o)를 사용하는 환경에서는 새 클래스 파일을 생성한 뒤 덤프 명령을 실행하지 않으면 오토로더가 신규 파일 위치를 알지 못합니다.

백슬래시(\)와 슬래시(/) 혼용 실수:
PHP 네임스페이스 구분자는 반드시 역슬래시(\)입니다. 코드 상단 use App/Services/UserService; 처럼 일반 슬래시를 사용하면 파싱 에러나 클래스 탐색 실패 원인이 됩니다.

 

5단계: 마무리 및 요약

PHP의 Class not found 에러 원인과 완벽한 해결법을 다시 한번 요약하겠습니다.

  • 클래스 파일의 위치, 파일명, 네임스페이스 선언 간의 대소문자가 100% 일치하는지 체크합니다.
  • composer.jsonpsr-4 매핑 설정이 디렉터리 구조와 일치하는지 확인합니다.
  • 클래스 추가/수정 후에는 composer dump-autoload -o 명령으로 오토로딩 캐시를 최적화 및 갱신합니다.

PHP의 클래스 로딩 메커니즘을 제대로 이해하고 PSR-4 표준 규격을 철저히 준수하는 관습은 프로젝트의 안정성을 극대화하는 핵심 기반이다. 파일명 대소문자와 Composer 최적화 습관이 모여서 배포 시 발생하는 원인을 알 수 없는 수많은 버그를 사전에 완벽히 차단한다는 점을 잊지 말자. 이 글의 단계별 점검 체계를 참고해 개발 프로젝트의 네임스페이스와 오토로딩 설정을 재점검하면, 배포 오류 없는 깨끗하고 안정적인 PHP 백엔드 시스템을 구축할 수 있을 것이다.