downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
search for in the  

<Predefined ConstantsUsing Phar Archives: the phar stream wrapper>
Last updated: Thu, 26 Jun 2008

Using Phar Archives

Table of Contents

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. Unlike Java's implementation of JAR archives, no external tool is required to process or run a PHP Phar archive. 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::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 DirectoryIterator('/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;
}
?>

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



add a noteadd a note User Contributed Notes
Using Phar Archives
There are no user contributed notes for this page.




<Predefined ConstantsUsing Phar Archives: the phar stream wrapper>
Last updated: Thu, 26 Jun 2008
show source | credits | sitemap | contact | advertising | mirror sites
Copyright © 2001-2005 The PHP Group
All rights reserved.
This unofficial mirror is operated at: http://phpbuilder.com/
Last updated: Tue Nov 1 20:20:59 2005 EST
Columns / Articles | Tips / Quickies | News | News Linking and RSS Feeds | Shared Code Library
Mail Archives | Support / Discussion Forums | Get Started! Links | Contribute! | Docs