Page tree


수많은 PHP 개발자들이 각자의 코드를 작성하고 있으므로 서로 같은 이름의 클래스를 만들 수 있으며 특히 DB, User, Service, Request 같은 일반적인 단어를 사용할 경우 중복 가능성이 높습니다.


PHP 5.3 이전 버전을 사용할 경우 외부에서 만든 라이브러리를 사용할 때 기존 클래스와 이름이 같은 클래스가 있다면 한쪽의 클래스명을 변경해야 하거나 아니면 외부 라이브러리 자체를 사용하지 못하는 문제가 있었습니다. 


운영체제에서는 같은 이름의 파일(test.txt)이라도 디렉터리가 다르다면 /tmp/test.txt/home/lesstif/test.txt 에 동시에 존재할 수 있으며 두 개의 파일을 구분하기 위해 /tmp/test.txt 와 같이 절대 경로를 사용하거나 test.txt 가 있는 디렉터리에 들어가서(예: cd  /tmp) vi test.txt 처럼 상대 경로를 사용할 수 있습니다.

네임스페이스(namespace)는 PHP 5.3부터 추가된 기능으로, 개별 클래스가 속한 위치를 운영체제의 디렉터리처럼 구분하여  같은 이름을 가진 클래스를 여러 개 사용할 수 있도록 해줍니다. 


자바 언어의 경우 Logger 라는 동일한 이름의 클래스가 있어도 java.util.logging.Logger 패키지와 org.apache.log4j.Logger 가 서로 다른 패키지이므로 구분하여 사용할 수 있습니다.


네임스페이스를 사용하면 각 클래스가 각기 다른 이름공간을 통해 격리되므로 다른 이가 작성한 코드와 중복되는 것을 걱정하지 않고 코드를 작성할 수 있으므로 많은 개발자와 다양한 외부 라이브러리를 사용하는 큰 규모의 프로젝트를 진행해도 클래스 이름 충돌로 인한 문제를 방지할 수 있습니다.


네임스페이스를 사용하면 클래스는 각각의 이름 공간을 통해 격리되므로 다른 이가 작성한 코드와 중복되는 것을 걱정하지 않고 코드를 작성할 수 있으므로 많은 개발자와 다양한 외부 라이브러리를 사용하는 큰 규모의 프로젝트를 진행해도 클래스 이름 중복으로 인한 문제를 방지할 수 있습니다.


네임스페이스는 특별히 명시하지 않았다면 전역 네임스페이스에 속하게 됩니다.

<?php

class Book
{
    public function show() {
        echo "wikibooks\n";
    }
}

위와 같이 책 정보를 관리하는 Book 이라는 클래스가 있을 경우 최상위 네임스페이스에 속하게 되므로 네임스페이스를 사용하지 않은 BookManager 라는 라이브러리에도 Book 클래스가 있다면 클래스 이름이 중복되므로 둘 중 하나는 클래스의 이름을 변경해야 합니다.


이 문제는 다음과 같이 WikiBooks라는 네임스페이스를 선언하여 해결할 수 있습니다.


네임스페이스는 다음과 같이 <?php 선언부에 바로 이어서 namespace 라는 키워드를 사용하면 됩니다. 네임스페이스는 매우 중요한 키워드이므로 namespace 키워드가 모든 php 구문보다 제일 먼저 와야 하며 php 구문이 나타나면 컴파일 에러가 발생합니다.

예로 다음과 같은 코드들은 컴파일 에러를 발생시킵니다.

<?php
class Book {}
namespace WikiBooks;
}
<?php
$a = 1;
namespace WikiBooks;
}



다음은 WikiBooks 네임스페이스를 선언하고 클래스를 구현한 Book.php 입니다.

<?php
namespace WikiBooks;

class Book
{
    public function show() {
        echo "wikibooks\n";
    }
}


이제 Book 클래스를 사용하는 측은 전체 네임스페이스를 사용하여 패키지를 기술해 주면 됩니다. 다음은 네임스페이스를 사용한 예제입니다.

<?php

include "Book.php";

$b = new WikiBooks\Book();
$b->show();


사용할 때마다 전체 네임스페이스를 기술하기 번거로울 경우 use 키워드를 사용하면 됩니다.

<?php

include "Book.php";

use WikiBooks\Book;
$b = new Book();
$b->show();


또 as 키워드를 사용하여 클래스에 별칭을 부여할 수 있습니다. 다음은 Book 클래스를 MyBook 으로 별칭을 부여하여 사용하는 예제입니다. 이 방법을 사용하면 다른 네임스페이스에 있는 동일한 클래스를 식별하는데 유용합니다.


<?php

include "Book.php";
 
use WikiBooks\Book as MyBook;
$b = new MyBook();
$b->show();


네임스페이스를 계층적으로 구성할 수도 있습니다. WikiBooks 네임스페이스 밑에 Linux 라는 하위 네임스페이스를 둘 경우 다음과 같이 \  를 이용하여 하위 네임스페이스를 기술하면 됩니다

<?php
namespace WikiBooks\Linux;

use FileLog\Logger;
class LinuxBook
{
    public function show() {
        echo "Linux books\n";
    }
}

namespace 사용시 주의할 점은  namespace WikiBooks; 키워드를 사용했을 경우 현재 네임스페이스가 WikiBooks 로 고정되어 버린다는 점입니다.

이 상태에서 FileLog 네임스페이스에 있는 Logger 라는 외부 클래스를 사용하고 싶을 경우가 있습니다. 그래서 다음과 같이 use 키워드를 사용하면 Class 'WikiBooks\FileLog\Logger' not found 라는 에러가 발생할 것입니다.

<?php
namespace WikiBooks;

use FileLog\Logger;
class Book
{
    public function show() {
        echo "wikibooks\n";
		// Class 'WikiBooks\FileLog\Logger' not found
		Logger.info("show function");
    }
}

이는 현재 네임스페이스가 WikiBooks 로 고정되어 버렸으므로 WikiBooks\FileLog\Logger 클래스를 찾기때문에 발생한 문제입니다.


현재 네임스페이스보다 상위에 있는 클래스를 사용하려면 다음과 같이 네임스페이스 앞에 슬래시를 붙여주면 전역 네임스페이스에서 클래스를 찾게 됩니다.

<?php
namespace WikiBooks;

use \FileLog\Logger;
 
class Book
{
    public function show() {
        echo "wikibooks\n";
		// 정상동작
		Logger.info("show function");
    }
}


네임스페이스는 PHP 의 패키지 관리자인 Composer 에서 패키지를 식별하는데 사용되며 내가 만든 패키지를 외부에 제공할 때도 필요하니 잘 익혀 두어야 합니다.

라라벨은 Illuminate 라는 네임스페이스를 사용하여 다른 프레임워크나 패키지와 충돌나지 않도록 하고 있으며 5.1 부터는 PHP 의 표준 코딩 스타일인 PSR-2 에 맞게 코드가 작성되어 있습니다.