PHP5에 오토로딩 기능이 추가되었지만 라이브러리를 오토로딩하려면 직접 spl_autoload_register 메소드를 호출하여 일일이 등록해야 한다. 외부 라이브러리를 사용할 경우 일일이 이를 등록하는 것은 만만한 작업이 아니다.
PSR-4 는 PSR-0 을 대체하는 새로운 오토로딩 표준으로 다음과 같이 정규화된 클래스 이름(FQCN; Fully Qualified Class Name) 을 규정하고 있으며 이를 준수하여 패키지를 개발할 경우 패캐지 관리자인 컴포저를 통해 손쉽게 의존성 있는 모든 패키지를 로딩할 수 있다.
xxxxxxxxxx
\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
실습
테스트하려는 프로젝트 구조는 다음과 같다
proj
├── composer.json
├── index.php
└── src
└── lib
└── Worker.php
index.php에서 Worker.php를 호출할 것이다.
x# Worker.php
<?php
class Worker
{
public function foo()
{
echo "Worker::foo()\n";
}
}
index.php에서 Worker 클래스를 사용하기 위해서는 Worker.php 파일을 포함시켜야 한다.
xxxxxxxxxx
# index.php
<?php
require_once __DIR__ . "/src/lib/Worker.php";
$w = new Worker();
$w->work();
위처럼 require_oce
를 이용하여 Worker.php 파일을 가져와 Worker 객체를 생성할 수 있다.
하지만 포함해야할 파일이 많아질수록 관리가 어려워진다.
xxxxxxxxxx
require_once __DIR__ . "/src/lib/Worker0.php";
require_once __DIR__ . "/src/lib/Worker1.php";
require_once __DIR__ . "/src/lib/Worker2.php";
...
모든 파일을 하나씩 포함시키기 위해 코드를 추가하다보면 관리하기 어렵고 오타로 인한 실수가 발생할 수 있다. autoload를 통해 단 한줄만 추가하여 편리하게 파일을 가져와 사용할 수 있다.
require_once 'vendor/autoload.php'
psr4 적용
Worker.php에 namespace를 추가한다.
xxxxxxxxxx
# Worker.php
<?php
#namespace 지정
namespace wor\lib;
class Worker
{
public function foo()
{
echo "Worker::foo()\n";
}
}
namespace는 클래스가 저장된 디렉토리와 일치해야한다.
그리고 composer를 실행하여 설정해줘야한다. composer 설치 방법은 이전 포스트에서 확인할 수 있다.
composer.json 수정
xxxxxxxxxx
{
"autoload" : {
"psr-4" : {
"wor\\" : "src/"
}
}
.
}
wor\\lib\\Worker
와 같이 클래스를 오토로딩할 때 wor\\
네임스페이스의 전두사가 src/
디렉터리에 대응되어있다면, 오토로더는 src/lib/Worker.php
파일을 찾을 것이고 그리고 해당 파일이 존재하면 이것을 불러올 것이다.
composer 실행
xxxxxxxxxx
$ composer dump-autoload
실행하면 다음과 같이 /vendor
에 파일들이 추가된다.
xxxxxxxxxx
wor
├── composer.json
├── index.php
├── src
│ └── lib
│ └── Worker.php
# 생성된 내용들
└── vendor
├── autoload.php
└── composer
├── autoload_classmap.php
├── autoload_namespaces.php
├── autoload_psr4.php
├── autoload_real.php
├── autoload_static.php
├── ClassLoader.php
└── LICENSE
이렇게 해주고 vm에도 파일들을 다 업로드 해줘야 적용이 되었다.
이제 index.php에서 사용하려면 autoloader파일을 포함하고, 사용할 namespace를 지정해주면 된다.
xxxxxxxxxx
<?php
# 생성된 autoload.php를 포함한다.
require_once __DIR__ . "/vendor/autoload.php";
# Worker.php에서 지정한 namespace 사용
use wor\lib\Worker;
$w = new Worker();
$w->work();
Worker.php 파일을 정상적으로 읽어오는 것을 확인할 수 있다.