phar-php-using-php-intro-4

  • Using Phar Archives
  • Using Phar Archives: Introduction

  • Using Phar Archives: Introduction
  • Using Phar Archives: Introduction

    Using Phar Archives: Introduction

    Phar archives are similar in concept to Java JAR
    archives, but are tailored to the needs and to the flexibility of
    PHP applications. A Phar archive is used to distribute a complete
    PHP application or library in a single file. A Phar archive
    application is used exactly like any other PHP application:

    php coolapplication.phar
      
    

    Using a Phar archive library is identical to using
    any other PHP library:

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

    The phar stream wrapper provides the core
    of the phar extension, and is explained in detail here. The phar stream
    wrapper allows accessing the files within a phar archive using
    PHP’s standard file functions fopen(),
    opendir(), and others that work on regular
    files. The phar stream wrapper supports all read/write
    operations on both files and directories.

    <?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');
    ?>

    The Phar class implements advanced functionality for
    accessing files and for creating phar archives. The Phar class is
    explained in detail here.

    <?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::TARPhar::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;
    }
    ?>

    In addition, verification of phar file contents can
    be done using any of the supported symmetric hash algorithms (MD5,
    SHA1, SHA256 and SHA512 if ext/hash is enabled) and using
    asymmetric public/private key signing using OpenSSL (new in Phar
    2.0.0). To take advantage of OpenSSL signing, you need to generate
    a public/private key pair, and use the private key to set the
    signature using Phar::setSignatureAlgorithm(). In addition,
    the public key as extracted using this code:

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

    must be saved adjacent to the phar archive it verifies. If the phar
    archive is saved as /path/to/my.phar, the public key must
    be saved as /path/to/my.phar.pubkey, or phar will be
    unable to verify the OpenSSL signature.

    As of version 2.0.0, The Phar class also provides 3 static methods,
    Phar::webPhar(), Phar::mungServer() and Phar::interceptFileFuncs() that are crucial
    to packaging up PHP applications designed for usage on regular
    filesystems and for web-based applications. Phar::webPhar() implements a front controller
    that routes HTTP calls to the correct location within the phar
    archive. Phar::mungServer() is used to modify
    the values of the $_SERVER array to trick applications
    that process these values. Phar::interceptFileFuncs() instructs Phar to
    intercept calls to fopen(),
    file_get_contents(), opendir(), and all of the stat-based
    functions (file_exists(), is_readable() and so on) and route all
    relative paths to locations within the phar archive.

    As an example, packaging up a release of the
    popular phpMyAdmin application for use as a phar archive requires
    only this simple script and then phpMyAdmin.phar.tar.php
    can be accessed as a regular file from your web server after
    modifying the user/password:

    <?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();
    ?>