 |
|
난이도 : 초급 John Mertic, Software Engineer, SugarCRM
원문 게재일 : 2009 년 1 월 27 일 번역 게재일 : 2009 년 5 월 12 일 PHP V5.3이 곧 릴리스될 예정입니다. 이 "PHP
V5.3의 새로운 기능" 시리즈에서는 PHP V5.3의 흥미롭고 새로운 기능에 대해 설명합니다. Part 1에서는
PHP V5.3의 오브젝트 지향 프로그래밍 및 오브젝트 처리와 관련된 변경 사항을 살펴 보았으며, Part 2에서는
람다 함수와 클로저에 대해 살펴 보았습니다. 그리고 Part 3에서는 PHP V5.3에서 가장 큰 기대를 받으면서도
가장 큰 논란의 대상이기도 한 네임스페이스에 대해 설명합니다. 이제 Part 4에서는 PHP 내에서 사용할 수
있는 아카이브 형식인 Phar에 대해 자세히 설명합니다. Phar는 파일을 아카이브하는 작업뿐 아니라 단일 파일의 전체 PHP 애플리케이션을 전달 및 실행하는 작업에도
사용할 수 있습니다. 현재 버전은 PECL 저장소의 확장으로서 PHP와 함께 사용할 수 있지만 향후 V5.3 버전에서 PHP의 공식 확장이 될 것입니다.
Phar 아카이브는 Java™ 기술의 JAR 아카이브에서 가져온 개념이며 애플리케이션 실행에
필요한 모든 항목을 단일 파일로 묶어서 애플리케이션을 패키징하는 데 사용된다. 이 파일은
컴파일된 애플리케이션이 아닌 아카이브이기 때문에 C와 같은 언어로 작성되는 일반적인 단일 실행
파일의 개념과는 다르다. 실제로 JAR 파일에는 애플리케이션을 구성하는 파일이 포함되어 있기는
하지만 보안 상의 이유로 포함된 파일에 대한 액세스가 제한될 수 있다. Phar 확장도 비슷한 개념을
기반으로 하지만 PHP 웹 환경에 보다 적합하게 설계되었다. 또한 JAR 아카이브와는 달리 Phar
아카이브는 PHP 자체에서 처리할 수 있으며 외부 도구 없이도 생성하거나 사용할 수 있다.
Phar 확장은 완전히 새로운 PHP 기능은 아니다. 처음에 PHP_Archive라는 이름으로 PHP로 작성되었던
이 기능은 2005년에 PEAR 저장소에 추가되었다. 하지만 실제 환경에서는 이 문제에 대한 순수 PHP
솔루션 개발이 매우 느리게 진행되었기 때문에 2007년에 순수 C 확장으로 다시 작성되었으며 SPL의
ArrayAccess 오브젝트를 사용하여 Phar 아카이브를 반복할 수 있도록
지원하는 기능도 동시에 추가되었다. 그 이후로 Phar 아카이브의 성능을 향상시키기 위한 여러 가지
작업이 이루어졌다.
Phar 작성하기
Phar 파일을 작성하려면 여러 단계를 수행해야 한다. 이러한 아카이브를 작성할 수 있는 독립
실행형 도구가 없기 때문에 모든 단계에서 PHP 명령을 사용하여 작업을 수행해야 한다. 또한 Phar
파일을 작성 및 수정하려면 php.ini 설정 phar.readonly를 0으로 설정해야 한다. 이 설정은 PHP의
Phar 아카이브에서 파일을 열거나 참조하는 데 필요하지 않다.
이제 애플리케이션을 개발하는 데 사용할 수 있는 Phar 아카이브를 작성하는 데 필요한 단계를
살펴보자. 이 애플리케이션은 웹 브라우저 또는 명령 프롬프트에서 직접 로드할 수 있도록
설계되었다. 첫 번째 단계는 Phar 파일을 작성하는 작업이므로 먼저 Listing 1의 예제를 실행하여
Phar 오브젝트를 작성한다. 이 오브젝트 참조는 Phar 아카이브의 모든
기능을 제어하는 데 사용된다.
Listing 1. Phar 오브젝트 생성하기
$p = new Phar('/path/to/my.phar', CURRENT_AS_FILEINFO | KEY_AS_FILENAME, 'my.phar');
$p->startBuffering();
|
생성자의 첫 번째 매개변수는 Phar 파일을 저장할 경로이다. 두 번째 매개변수는 임의의 매개변수를
RecursiveDirectoryIterator 상위 클래스에 전달한다. 세 번째 매개변수는
해당 Phar 아카이브가 스트림 컨텍스트에서 참조되는 방법에 대한 별칭이다. 따라서 Listing 1의 경우
이 Phar 내의 파일을 phar://my.phar 형식으로 참조할 수 있다. 또한 Phar::startBuffering()
메소드를 호출하여 Phar::stopBuffering() 명령을 실행하기 전까지의 아카이브
변경 사항을 버퍼링할 수 있다. 반드시 사용할 필요는 없지만 버퍼링을 사용하게 되면 스크립트가 변경될
때마다 변경 사항을 아카이브에 저장하지 않아도 되기 때문에 아카이브를 작성 또는 수정할 때 향상된
성능을 얻을 수 있다.
작성된 Phar는 기본적으로 네이티브 Phar 기반 아카이브 형식을 사용한다. 또한 Phar 파일 형식을 ZIP으로
변경하는 Listing 2와 같이 파일 형식을 ZIP 또는 TAR 형식으로 변환하여 ZIP 또는 TAR 형식의 Phar 파일을
사용할 수 있다.
Listing 2. 저장 형식을 ZIP으로 변경하기
$p = $p->convertToExecutable(Phar::ZIP);
|
아카이브 형식 변환에는 장단점이 있다. 주요 장점은 ZIP 또는 TAR 파일을 처리할 수 있는 도구를
사용하여 아카이브의 컨텐츠를 확인할 수 있다는 것이다. 하지만 네이티브 Phar 기반 아카이브 형식을
사용하지 않는 Phar 아카이브를 사용할 경우에는 아카이브를 로드하기 위한 Phar 확장을 사용하지 않아도
되지만 ZIP 또는 TAR 형식의 Phar 아카이브를 사용할 경우에는 Phar 확장을 사용해야 한다.
그 다음으로, Phar 파일이 로드될 때 가장 먼저 호출되는 코드인 파일 스텁을 정의해야 한다.
Phar 파일 스텁
파일 스텁은 Phar 파일이 로드될 때 초기에 실행되는 간단한 코드이며 항상 __HALT_COMPILER()
토큰으로 끝난다. Listing 3에서는 일반적인 파일 스텁을 보여 준다.
Listing 3. Phar 파일 스텁
<?php
Phar::mapPhar();
include 'phar://myphar.phar/index.php';
__HALT_COMPILER();
|
위에 있는 Phar::mapPhar() 메소드 호출은 매니페스트를 읽어서
Phar 아카이브를 초기화한다. 이 작업은 phar:// 스트림 랩퍼를 사용하여 아카이브 내에서 파일을
참조하기 전에 수행해야 한다. 초기에 로드할 파일은 애플리케이션에서 일반적으로 처음에 로드되는
파일이며, 이 예제의 경우에는 index.php이다.
이 스텁을 Phar 아카이브에 추가하는 방법은 사용 중인 아카이브 형식에 따라 달라진다. Phar
기반 아카이브의 경우, PHP 코드를 단일 매개변수로 받아서 스텁에 문자열로 저장하는 Phar::setStub()
메소드를 사용한다. Listing 4는 이 방법을 보여 주는 예제이다.
Listing 4. Phar::setStub()을 사용하여 파일 스텁 생성하기
$p->setStub('<?php Phar::mapPhar();
include 'phar://myphar.phar/index.php'; __HALT_COMPILER(); ?>');
|
스텁을 사용하여 index.php 페이지로 리디렉션하는 작업만 수행할 경우에는 도우미 메소드
Phar::createDefaultStub()을 사용하여 파일 스텁을 빌드할 수
있다. 이 메소드를 사용할 경우에는 파일 스텁에 포함할 파일 이름만 전달하면 된다. Listing
5에서는 이 도우미 메소드를 사용하도록 Phar::setStub() 메소드
호출을 다시 작성한다.
Listing 5. Phar::createDefaultStub()을 사용하여 파일 스텁 생성하기
$p->setStub($p-> createDefaultStub('index.php'));
|
Phar::createDefaultStub() 메소드의 두 번째 선택적 인수는 Phar가
웹 서버에서 로드된 경우 다른 파일을 포함하는 데 사용된다. 이 메소드는 애플리케이션이 명령행 및
웹 브라우저 컨텍스트에서 사용할 수 있도록 설계된 경우 쉽게 실행할 수 있다.
ZIP 및 TAR 기반 구현의 경우에는 setStub() 명령을 사용하는 대신
위 스텁의 컨텐츠를 .phar/stub.php 파일에 저장한다.
아카이브에 파일 추가하기
Phar 오브젝트는 ArrayAccess SPL
오브젝트를 사용하여 아카이브의 컨텐츠에 배열로 액세스할 수 있는 기능을 제공하므로 여러 가지
방법으로 아카이브에 파일을 추가할 수 있다. 가장 쉬운 방법은 ArrayAccess
인터페이스를 직접 사용하는 것이다.
Listing 6. 아카이브에 파일 추가하기
$p['file.txt'] = 'This is a text file';
$p['index.php'] = file_get_contents('index.php');
|
Listing 6에서는 파일 이름이 배열 키로 지정되어 있고 컨텐츠는 값으로 지정되어 있다. file_get_contents()
함수를 사용하여 값으로 설정할 기존 파일의 컨텐츠를 가져올 수 있다. 위 예제에서 보듯이 기존 파일을 참조하거나 새 파일을 빌드하는
방식으로 아카이브에 파일을 추가할 수 있다. 두 번째 방법은 애플리케이션 빌드 스크립트에서 유용하게 사용할 수 있다.
Phar 아카이브에 저장하는 파일이 대용량인 경우에는 PharFileInfo::setCompressedGZ()
또는 PharFileInfo::setCompressedBZIP2() 메소드를 통해 해당하는 gzip 또는 bzip2 압축을
사용하여 아카이브의 파일을 선택적으로 압축할 수 있다. Listing 7에서는 bzip2를 사용하여 파일을 압축한다.
Listing 7. bzip2를 사용하여 Phar 아카이브의 파일 압축하기
$p['big.txt'] = 'This is a big text file';
$p['big.txt']->setCompressedBZIP2();
|
파일을 압축하거나 압축된 파일이 포함된 아카이브를 사용하려면 PHP 설치에서 bzip2 또는 zlib(gz 압축 파일의 경우)
확장을 사용할 수 있어야 한다.
아카이브에 추가할 파일이 많은 경우, ArrayAccess 인터페이스를 사용하여
파일을 하나씩 추가하면 시간이 많이 걸리지만 이 작업을 간단하게 수행할 수 있는 몇 가지 방법이
있다. 지정된 디렉토리에 있는 파일을 추가하는 Phar::buildFromDirectory()
메소드를 사용하는 것도 이러한 방법 중 하나이다. 이 메소드는 일치할 경우 아카이브에 추가할
파일의 정규 표현식 패턴을 두 번째 매개변수로 전달하여 파일을 필터링할 수도 있다. Listing 8에서는
이 메소드를 사용하는 방법을 보여 준다.
Listing 8. Phar::buildFromDirectory()를 사용하여 아카이브에 파일 추가하기
$p->buildFromDirectory('/path/to/files','./\.php$/');
|
Listing 8의 예제는 지정된 디렉토리에 있는 모든 PHP 파일을 Phar 아카이브에 추가한다. 그런
다음 추가된 파일에 대한 변경 작업이 필요한 경우 ArrayAccess 인터페이스로
돌아가서 파일이 압축되도록 설정하는 등의 작업을 수행할 수 있다.
또한 Phar::buildFromIterator() 메소드를 사용하면 반복기를 사용하여
파일을 추가할 수 있다. 두 가지 스타일의 반복기 즉, Phar 내의 파일 이름을 디스크에 있는 파일의
이름에 맵핑하는 반복기와 SplFileInfo 오브젝트를 리턴하는 반복기가
지원된다. 아래 예제에서 디렉토리의 파일을 아카이브에 추가하는 데 사용된 RecursiveDirectoryIterator는
호환되는 반복기 중 하나이다.
Listing 9. Phar::buildFromIterator()를 사용하여 아카이브에 파일 추가하기
$p->buildFromIterator(new RecursiveIteratorIterator
(new RecursiveDirectoryIterator('/path/to/files')),'/path/to/files');
|
Phar::buildFromIterator() 메소드는 반복기 오브젝트 자체를 단일
인수로 받는다. 위 예제에서는 RecursiveDirectoryIterator 오브젝트를
RecursiveIteratorIterator 오브젝트가 둘러싸고 있으며, 이 바깥쪽
오브젝트는 Phar::buildFromIterator() 메소드에 필요한 호환되는 유형의
반복기를 제공한다.
지금까지 모든 PHP 애플리케이션에서 사용할 수 있는 Phar 아카이브를 작성했으므로 이제 이 아카이브를
쉽게 사용할 수 있는 방법을 살펴보자.
Phar 아카이브 처리하기
Phar 아카이브의 장점은 애플리케이션 내에서 쉽게 통합할 수 있다는 것이다. 네이티브 Phar 기반
아카이브 형식을 사용할 경우에는 더욱 쉽게 통합할 수 있으며, PHP의 기능만으로도 파일을 로드하여
파일의 컨텐츠를 추출할 수 있기 때문에 Phar 확장마저도 설치할 필요가 없다. ZIP 및 TAR 기반 아카이브의
경우에는 Phar 확장을 로드해야 한다.
Phar 아카이브는 일반적인 PHP 파일과 마찬가지로 애플리케이션 내에 포함되도록 설계되었으므로
다른 써드파티 코드를 포함하는 데 익숙한 애플리케이션 개발자라면 Phar 아카이브를 매우 쉽게 사용할
수 있다. Phar를 애플리케이션에 얼마나 쉽게 통합할 수 있는지 확인해 보자.
애플리케이션에 Phar 아카이브 코드 통합하기
Phar 아카이브의 코드를 가장 쉽게 통합하는 방법은 Phar 아카이브를 포함시킨 후 사용할 Phar 파일
내에 파일을 포함시키는 것이다. 아래와 같이 phar:// 스트림 랩퍼를 사용하여 로드된 Phar 아카이브에
있는 파일에 액세스할 수 있다.
Listing 10. Phar 아카이브의 코드 로드하기
include 'myphar.phar';
include 'phar://myphar.phar/file.php';
|
첫 번째 include 구문은 파일 스텁에 지정된 코드가 포함된 myphar.phar 아카이브를 로드한다. 두
번째 include 구문은 스트림 랩퍼를 사용하여 Phar 아카이브를 연 후 아카이브에 있는 파일 중 지정된
파일만을 포함시킨다. 아카이브에 있는 파일을 포함하기 전에 Phar 아카이브 자체를 포함할 필요는
없다(Listing 10 참조).
Phar 아카이브의 PHP 애플리케이션 실행하기
Phar 아카이브를 사용하면 전체 애플리케이션을 하나의 Phar 아카이브로 패키징하여 손쉽게 배포할
수 있다. 이 방법의 장점은 PHP V5.3에서 PHP V5.3에서 향상된 여러 가지 Phar 기능으로 인해 애플리케이션을
쉽게 전개할 수 있고 성능이 저하되지 않는다는 것이다. 하지만 Phar 내에서 실행되도록 애플리케이션을
설계할 경우에는 다음 사항을 애플리케이션 설계 시에 고려해야 한다.
- 생성되어야 하는 파일 중 애플리케이션의 인스턴스와 관련된 파일(예: 구성 파일)은 아카이브에
포함될 수 없으므로 액세스 가능한 별도의 위치에 작성해야 한다. 애플리케이션에서 실행 파일의 일부로
생성되는 캐시 파일의 경우에도 마찬가지이다.
- 최대한의 이식성을 보장하려면 압축하지 않은 Phar 기반 아카이브 형식의 파일을 아카이브에 사용해야
한다. ZIP 및 TAR 기반 아카이브는 Phar 확장이 PHP에 설치되어 있어야만 사용할 수 있지만 Phar 기반 확장은
Phar 확장이 설치되어 있지 않아도 사용할 수 있다.
- 애플리케이션에서 사용되는 모든 파일 참조는 앞 섹션에서 본 것처럼 phar:// 스트림 랩퍼와 아카이브 이름을
사용하도록 변경해야 한다.
PHPMyAdmin은 Phar 아카이브를 얼마나 쉽게 사용할 수 있는지 보여 주기 위한 예로 사용하기 위해 Phar로
패키징된 잘 알려진 PHP 애플리케이션이다(참고자료 참조). 이 애플리케이션은 Phar
아카이브 파일에서 실행하도록 설계되었으며 구성 파일을 Phar 아카이브 외부에 저장하는 기능도 제공한다.
요약
Phar 아카이브는 사용하기 편리한 PHP V5.3의 추가 기능이다. 이 기능을 사용하면 PHP 코드를
하나의 아카이브로 패키징할 수 있으며, 더 나아가 애플리케이션이나 라이브러리를 단 하나의 파일로
배포할 수도 있다. Phar 아카이브는 require 또는 include 함수를 사용하여 PHP 파일에서 쉽게 로드할
수 있을 뿐 아니라 브라우저나 명령행에서 Phar 아카이브 이름을 지정하여 직접 실행할 수도 있다.
참고자료 교육
제품 및 기술 얻기
-
PHPMyAdmin은 Phar 아카이브를 얼마나 쉽게 사용할 수 있는지 보여 주기 위한 예로 사용하기 위해 Phar로
패키징된 잘 알려진 PHP 애플리케이션이다.
-
PHP V5.2.6을 다운로드하자.
-
DVD로 제공되거나 다운로드할 수 있는 IBM 시험판
소프트웨어를 사용하여 후속 오픈 소스 개발 프로젝트를 구현해 보자.
-
IBM 시험판 제품을
다운로드하여 DB2®, Lotus®, Rational®, Tivoli® 및 WebSphere®의 애플리케이션 개발 도구 및
미들웨어 제품을 사용하자.
토론
필자소개  | |  | John Mertic은 Kent State University의 컴퓨터 과학과를 졸업했으며,
SugarCRM에서 소프트웨어 엔지니어로 근무하고 있다. 여러 오픈 소스 프로젝트에 참여했으며, 특히 PHP 프로젝트에 주력하고 있다. 또한 PHP
Windows Installer를 개발 및 유지보수를 수행한다. |
기사에 대한 평가
 |
| 이 문서 북마킹 하기
|
|