PHP 신규 프로젝트를 배포하거나 라이브러리를 추가한 뒤 Fatal error: Uncaught Error: Class 'App\Services\UserService' not found 같은 치명적 에러를 마주쳐 당황했던 경험이 있으신가요?
대부분의 개발자들은 단순한 파일 경로 문제로 지레짐작하고 require_once를 남발하지만, 정작 원인이 Composer 오토로더(Autoloader) 캐시나 PSR-4 네임스페이스 대소문자 불일치라는 사실을 모르는 경우가 많습니다.
이번 글에서는 이 에러가 정확히 왜 발생하는지 원인을 철저히 분석하고, 네임스페이스와 Composer 오토로딩 체계를 올바르게 정립하여 에러를 깔끔하게 해결하는 방법을 완벽하게 정리해서 소개하겠습니다.
PHP에서 Fatal error: Uncaught Error: Class '...' not found 에러는 스크립트 실행 중 객체를 생성(new ClassName())하거나 정적 메서드를 호출하려고 할 때, 해당 클래스 정의를 인터프리터가 메모리상에서 찾지 못하면 발생합니다.
과거 PHP 5 이전 시절에는 외부 파일의 클래스를 가져오기 위해 모든 PHP 파일 상단에 require나 include를 일일이 작성해야 했습니다.
하지만 modern PHP(PHP 7/8) 환경에서는 표준 규격인 PSR-4 오토로딩 체계를 사용하므로, 파일 경로와 네임스페이스가 1:1로 정확히 매핑되어야만 클래스를 정상적으로 불러올 수 있습니다.
| 발생 원인 | 상세 내용 | 대표적인 증상 |
|---|---|---|
| 네임스페이스/파일명 대소문자 불일치 | 리눅스 OS 환경은 대소문자를 엄격히 구분함 | 로컬(Windows/Mac)에서는 정상 동작하나 운영 서버 배포 시 에러 발생 |
| Composer Classmap 미갱신 | 새 클래스 파일 작성 후 오토로더 캐시를 갱신하지 않음 | composer.json에는 정상이지만 클래스를 인식하지 못함 |
| PSR-4 매핑 디렉터리 경로 오류 | composer.json의 autoload.psr-4 설정 오류 | 네임스페이스의 루트 경로와 실제 폴더 구조가 다름 |
이 에러를 만났을 때 당황하지 않고 체계적으로 해결할 수 있는 단계별 점검 방법입니다.
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 되어 있는지 확인합니다.
실무에서 흔히 저지르는 잘못된 코드 패턴과 이를 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 실행 결과
홍길동
개발 과정에서 개발자들이 자주 놓치는 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; 처럼 일반 슬래시를 사용하면 파싱 에러나 클래스 탐색 실패 원인이 됩니다.
PHP의 Class not found 에러 원인과 완벽한 해결법을 다시 한번 요약하겠습니다.
- 클래스 파일의 위치, 파일명, 네임스페이스 선언 간의 대소문자가 100% 일치하는지 체크합니다.
composer.json의psr-4매핑 설정이 디렉터리 구조와 일치하는지 확인합니다.- 클래스 추가/수정 후에는
composer dump-autoload -o명령으로 오토로딩 캐시를 최적화 및 갱신합니다.
PHP의 클래스 로딩 메커니즘을 제대로 이해하고 PSR-4 표준 규격을 철저히 준수하는 관습은 프로젝트의 안정성을 극대화하는 핵심 기반이다. 파일명 대소문자와 Composer 최적화 습관이 모여서 배포 시 발생하는 원인을 알 수 없는 수많은 버그를 사전에 완벽히 차단한다는 점을 잊지 말자. 이 글의 단계별 점검 체계를 참고해 개발 프로젝트의 네임스페이스와 오토로딩 설정을 재점검하면, 배포 오류 없는 깨끗하고 안정적인 PHP 백엔드 시스템을 구축할 수 있을 것이다.