PHP 네임스페이스는 클래스, 함수, 상수를 접두사 아래에 두어 그 이름이 다른 사람의 것과 충돌하지 않게 합니다. 파일의 첫 문장으로 namespace App\Models;를 선언하고, 다른 파일에서는 클래스를 \App\Models\User로 부르거나 use App\Models\User;로 가져와 User라고만 씁니다.
네임스페이스 안에서 User는 App\Models\User를 뜻합니다. User::class는 아무것도 만들지 않고 전체 이름을 문자열로 주므로 로그와 오토로더에 편리합니다.
한 파일에 네임스페이스 두 개
실제 프로젝트는 파일마다 네임스페이스를 하나 둡니다. 독립적인 데모라면 각 네임스페이스를 중괄호로 감쌀 때 한 파일에 여러 네임스페이스를 둘 수 있습니다. 어느 네임스페이스에도 속하지 않는 코드는 namespace { }에 들어갑니다.
전체 이름이 다르므로 Order라는 클래스 두 개가 나란히 존재합니다. 라이브러리를 설치하면 네임스페이스가 해결하는 문제가 바로 이것입니다. 여러분의 Order, 결제 라이브러리의 Order, PDF 라이브러리의 Order가 더 이상 충돌하지 않습니다.
use로 가져오고 as로 별칭 붙이기
어디서나 \Shop\Order라고 쓰면 번거롭습니다. 파일(또는 네임스페이스 블록) 맨 위의 use는 이름을 가져와 짧은 형태를 쓸 수 있게 합니다. 두 가져오기의 짧은 이름이 같아진다면 as로 하나에 다른 이름을 붙이세요.
use는 파일의 나머지 부분을 위한 짧은 이름만 만듭니다. 파일을 불러오거나 코드를 실행하지 않으며, 클래스가 아직 존재하든 안 하든 똑같이 동작합니다. 묶어서 가져오기도 허용됩니다: use Shop\{Order, Invoice};.
use function과 use const
네임스페이스 안의 함수와 상수는 use function과 use const로 가져옵니다.
전역 클래스에는 백슬래시가 필요하다
네임스페이스 안에서 한정되지 않은 클래스 이름은 그 네임스페이스를 기준으로 해석되므로, namespace App; 안의 new DateTime()은 App\DateTime을 찾습니다. 함수와 상수는 다릅니다. App\strlen이 없으면 PHP는 전역 strlen으로 돌아갑니다. 클래스는 절대 돌아가지 않습니다.
catch (\Error $e)에 백슬래시가 필요했던 것도 같은 이유입니다. 없으면 PHP는 App\Error를 찾아 실제 에러와 일치하지 않고, 스크립트는 잡히지 않은 Error와 함께 멈춥니다. 위처럼 앞에 백슬래시를 붙이거나 파일 맨 위에 use DateTime;을 추가해 해결하세요. \Exception, \Throwable과 다른 모든 내장 클래스도 마찬가지입니다. 그것을 잡는 방법은 try catch를 참고하세요.
오토로딩과 PSR-4
프로젝트에서는 각 클래스가 자신의 파일에 있고, 파일 경로가 네임스페이스를 따릅니다. 그 규약이 PSR-4입니다. 네임스페이스 접두사가 기준 폴더에 대응하고, 이름의 나머지가 경로가 됩니다. 그러면 spl_autoload_register()로 등록한 오토로더가 클래스를 처음 쓸 때 클래스 파일을 불러옵니다. 이 블록은 클래스 파일 두 개를 디스크에 쓰고 오토로드합니다.
각 클래스 파일은 클래스가 처음 필요한 순간에 한 번 불러와집니다. 실제 프로젝트에서는 이 함수를 직접 쓰지 않습니다. Composer가 composer.json의 몇 줄로 만들어 줍니다.
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
composer dump-autoload 후에는 진입 스크립트 처음의 require __DIR__ . '/vendor/autoload.php'; 한 줄이 모든 App\... 클래스를 필요할 때 불러옵니다.
에러를 일으키는 네임스페이스 규칙
namespace는 파일의 첫 문장이어야 합니다. 그 앞에는declare(strict_types=1);과 주석만 올 수 있습니다.use가져오기는 파일 단위입니다.index.php에서 클래스를 가져와도 포함된 파일 안에서 짧은 이름이 동작하지 않으며, 파일마다 자신의use줄이 필요합니다.use는 파일이나 네임스페이스 블록의 최상위에 둡니다. 클래스 본문 안에서use는 다른 의미로, 트레이트를 가져옵니다.- 문자열은 해석되지 않습니다:
$class = 'User'; new $class();는 전역User를 찾습니다. 전체 이름을 저장하세요. 가능하면User::class로 저장하세요.
마지막 것은 빠르게 확인해 볼 만합니다.
자주 묻는 질문
PHP의 네임스페이스는 무엇인가요?
관련된 클래스, 인터페이스, 함수, 상수를 묶는 접두사이며, 이름을 위한 폴더와 같습니다. 파일 맨 위의 namespace App\Models;는 그 파일의 User 클래스를 App\Models\User에 두므로 다른 라이브러리의 User와 충돌하지 않습니다.
PHP에서 use는 무엇을 하나요?
파일 맨 위의 use App\Models\User;는 그 파일에서 전체 이름 \App\Models\User 대신 User라고 쓸 수 있게 합니다. 아무것도 불러오거나 포함하지 않습니다. 클래스 파일을 불러오는 것은 오토로더의 일입니다. use ... as Alias;는 다른 짧은 이름을 고릅니다.
네임스페이스 안에서 Class not found가 나는 이유는 무엇인가요?
namespace App; 안에서 그냥 쓴 클래스 이름은 네임스페이스를 기준으로 해석되므로 new DateTime()은 App\DateTime을 찾습니다. new \DateTime()으로 쓰거나 맨 위에 use DateTime;을 추가하세요. 함수와 상수는 자동으로 전역 네임스페이스로 돌아가지만 클래스는 그렇지 않습니다.
PHP에서 클래스 이름 앞의 백슬래시는 무엇인가요?
앞의 백슬래시는 이름을 전역 네임스페이스부터 시작하는 완전한 이름으로 만듭니다. \Exception은 코드가 어떤 네임스페이스에 있든 항상 PHP 내장 Exception입니다. 백슬래시가 없으면 이름은 현재 네임스페이스와 use 가져오기를 기준으로 해석됩니다.
네임스페이스와 폴더, PSR-4는 어떤 관계인가요?
PHP 자체는 네임스페이스를 폴더에 묶지 않습니다. 그렇게 하는 것은 PSR-4라는 규약입니다. App\ 같은 접두사를 src/ 같은 디렉터리에 대응시키므로 App\Models\User는 src/Models/User.php에 있습니다. Composer의 오토로더가 이를 따르므로 보통 둘이 일치합니다.