Phar 아카이브 사용 소개

Phar 아카이브는 개념상 Java JAR 아카이브와 유사하지만 PHP 애플리케이션의 요구와 유연성에 맞게 조정되었습니다. Phar 아카이브는 완전한 PHP 애플리케이션 또는 라이브러리를 단일 파일로 배포하는 데 사용됩니다. Phar 아카이브 애플리케이션은 다른 PHP 애플리케이션과 똑같이 사용됩니다.

php coolapplication.phar
                

Phar 아카이브 라이브러리를 사용하는 것은 다른 PHP 라이브러리를 사용하는 것과 동일합니다.

                  
<?php
include 'coollibrary.phar';
?>
                  
                

phar 스트림 래퍼는 phar 확장의 핵심을 제공하며 여기에서 자세히 설명합니다. phar 스트림 래퍼를 사용하면 PHP의 표준 파일 함수 fopen(), opendir() 및 일반 파일에서 작동하는 기타 함수를 사용하여 phar 아카이브 내의 파일에 액세스할 수 있습니다. phar 스트림 래퍼는 파일과 디렉토리 모두에서 모든 읽기/쓰기 작업을 지원합니다.

                  
<?php
include 'phar://coollibrary.phar/internal/file.php';
header('Content-type: image/jpeg');
// phars can be accessed by full path or by alias
echo file_get_contents('phar:///fullpath/to/coollibrary.phar/images/wow.jpg');
?>
                  
                

Phar 클래스는 파일 액세스 및 phar 아카이브 생성을 위한 고급 기능을 구현합니다. 여기에서 Phar 클래스에 대해 자세히 설명합니다.

                  
<?php
try {
    // open an existing phar
    $p = new Phar('coollibrary.phar', 0);
    // Phar extends SPL's DirectoryIterator class
    foreach (new RecursiveIteratorIterator($p) as $file) {
        // $file is a PharFileInfo class, and inherits from SplFileInfo
        echo $file->getFileName() . "\n";
        echo file_get_contents($file->getPathName()) . "\n"; // display contents;
    }
    if (isset($p['internal/file.php'])) {
        var_dump($p['internal/file.php']->getMetadata());
    }

    // create a new phar - phar.readonly must be 0 in php.ini
    // phar.readonly is enabled by default for security reasons.
    // On production servers, Phars need never be created,
    // only executed.
    if (Phar::canWrite()) {
        $p = new Phar('newphar.tar.phar', 0, 'newphar.tar.phar');
        // make this a tar-based phar archive, compressed with gzip compression (.tar.gz)
        $p = $p->convertToExecutable(Phar::TAR, Phar::GZ);

        // create transaction - nothing is written to newphar.phar
        // until stopBuffering() is called, although temporary storage is needed
        $p->startBuffering();
        // add all files in /path/to/project, saving in the phar with the prefix "project"
        $p->buildFromIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator('/path/to/project')), '/path/to/');

        // add a new file via the array access API
        $p['file1.txt'] = 'Information';
        $fp = fopen('hugefile.dat', 'rb');
        // copy all data from the stream
        $p['data/hugefile.dat'] = $fp;

        if (Phar::canCompress(Phar::GZ)) {
            $p['data/hugefile.dat']->compress(Phar::GZ);
        }

        $p['images/wow.jpg'] = file_get_contents('images/wow.jpg');
        // any value can be saved as file-specific meta-data
        $p['images/wow.jpg']->setMetadata(array('mime-type' => 'image/jpeg'));
        $p['index.php'] = file_get_contents('index.php');
        $p->setMetadata(array('bootstrap' => 'index.php'));

        // save the phar archive to disk
        $p->stopBuffering();
    }
} catch (Exception $e) {
    echo 'Could not open Phar: ', $e;
}
?>
                  
                

또한 지원되는 대칭 해시 알고리즘(ext/hash가 활성화된 경우 MD5, SHA1, SHA256 및 SHA512)을 사용하고 OpenSSL을 사용하는 비대칭 공개/개인 키 서명을 사용하여 phar 파일 내용을 확인할 수 있습니다. OpenSSL 서명을 활용하려면 공개/개인 키 쌍을 생성하고 개인 키를 사용하여 Phar::setSignatureAlgorithm()을 사용하여 서명을 설정해야 합니다. 또한 이 코드를 사용하여 추출한 공개 키는 다음과 같습니다.

                  
<?php
$public = openssl_get_publickey(file_get_contents('private.pem'));
$pkey = '';
openssl_pkey_export($public, $pkey);
?>
                  
                

확인하는 phar 아카이브에 인접하여 저장해야 합니다. phar 아카이브가 /path/to/my.phar로 저장되는 경우 공개 키는 /path/to/my.phar.pubkey로 저장해야 합니다. 그렇지 않으면 phar가 OpenSSL 서명을 확인할 수 없습니다. Phar 클래스는 또한 일반 파일 시스템 및 웹 기반 응용 프로그램에서 사용하도록 설계된 PHP 응용 프로그램을 패키징하는 데 중요한 Phar::webPhar(), Phar::mungServer()Phar::interceptFileFuncs()의 3가지 정적 메서드를 제공합니다. Phar::webPhar()는 HTTP 호출을 phar 아카이브 내의 올바른 위치로 라우팅하는 전면 컨트롤러를 구현합니다. Phar::mungServer()는 이러한 값을 처리하는 응용 프로그램을 속이기 위해 $_SERVER 배열의 값을 수정하는 데 사용됩니다. Phar::interceptFileFuncs()fopen(), file_get_contents(), opendir() 및 모든 통계 기반 함수(file_exists(), is_readable() 등)에 대한 호출을 가로채고 모든 상대 경로를 phar 아카이브 내의 위치.

예를 들어, phar 아카이브로 사용하기 위해 인기 있는 phpMyAdmin 애플리케이션의 릴리스를 패키징하려면 이 간단한 스크립트만 필요합니다. 그러면 user/password를 수정한 후 웹 서버에서 phpMyAdmin.phar.tar.php에 일반 파일로 액세스할 수 있습니다. :

                  
<?php
@unlink('phpMyAdmin.phar.tar.php');
copy('phpMyAdmin-2.11.3-english.tar.gz', 'phpMyAdmin.phar.tar.php');
$a = new Phar('phpMyAdmin.phar.tar.php');
$a->startBuffering();
$a["phpMyAdmin-2.11.3-english/config.inc.php"] = '<?php
/* Servers configuration */
$i = 0;

/* Server localhost (config:root) [1] */
$i++;
$cfg[\'Servers\'][$i][\'host\'] = \'localhost\';
$cfg[\'Servers\'][$i][\'extension\'] = \'mysqli\';
$cfg[\'Servers\'][$i][\'connect_type\'] = \'tcp\';
$cfg[\'Servers\'][$i][\'compress\'] = false;
$cfg[\'Servers\'][$i][\'auth_type\'] = \'config\';
$cfg[\'Servers\'][$i][\'user\'] = \'root\';
$cfg[\'Servers\'][$i][\'password\'] = \'\';


/* End of servers configuration */
if (strpos(PHP_OS, \'WIN\') !== false) {
    $cfg[\'UploadDir\'] = getcwd();
} else {
    $cfg[\'UploadDir\'] = \'/tmp/pharphpmyadmin\';
    @mkdir(\'/tmp/pharphpmyadmin\');
    @chmod(\'/tmp/pharphpmyadmin\', 0777);
}';
$a->setStub('<?php
Phar::interceptFileFuncs();
Phar::webPhar("phpMyAdmin.phar", "phpMyAdmin-2.11.3-english/index.php");
echo "phpMyAdmin is intended to be executed from a web browser\n";
exit -1;
__HALT_COMPILER();
');
$a->stopBuffering();
?>