mirror of
https://github.com/sigmasternchen/php-doc-en
synced 2025-03-15 16:38:54 +00:00

Phar 2.0.0 has been released 2009-07-29, so older versions are certainly no longer relevant for the PHP manual. git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@352054 c90b9560-bf6c-de11-be94-00142212c4b1
386 lines
15 KiB
XML
386 lines
15 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<chapter xml:id="phar.using" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Using Phar Archives</title>
|
|
|
|
<section xml:id="phar.using.intro" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Using Phar Archives: Introduction</title>
|
|
<para>
|
|
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:
|
|
</para>
|
|
<screen>
|
|
<![CDATA[
|
|
php coolapplication.phar
|
|
]]>
|
|
</screen>
|
|
<para>
|
|
Using a Phar archive library is identical to using any other PHP library:
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
include 'coollibrary.phar';
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
The <literal>phar</literal> stream wrapper provides the core of the phar extension, and
|
|
is explained in detail <link linkend="phar.using.stream">here</link>.
|
|
The phar stream wrapper allows accessing the files within a phar archive using
|
|
PHP's standard file functions <function>fopen</function>, <function>opendir</function>, and
|
|
others that work on regular files. The <literal>phar</literal> stream wrapper supports all
|
|
read/write operations on both files and directories.
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
The <classname>Phar</classname> class implements advanced functionality for accessing
|
|
files and for creating phar archives. The Phar class is explained in detail
|
|
<link linkend="phar.using.object">here</link>.
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
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. 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
|
|
<function>Phar::setSignatureAlgorithm</function>. In addition, the public key
|
|
as extracted using this code:
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$public = openssl_get_publickey(file_get_contents('private.pem'));
|
|
$pkey = '';
|
|
openssl_pkey_export($public, $pkey);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
must be saved adjacent to the phar archive it verifies. If the phar archive
|
|
is saved as <literal>/path/to/my.phar</literal>, the public key must be saved
|
|
as <literal>/path/to/my.phar.pubkey</literal>, or phar will be unable to verify
|
|
the OpenSSL signature.
|
|
</para>
|
|
<para>
|
|
The <classname>Phar</classname> class also provides 3 static methods, <function>Phar::webPhar</function>,
|
|
<function>Phar::mungServer</function> and <function>Phar::interceptFileFuncs</function> that are crucial
|
|
to packaging up PHP applications designed for usage on regular filesystems and for web-based applications.
|
|
<function>Phar::webPhar</function> implements a front controller that routes HTTP calls to the correct
|
|
location within the phar archive. <function>Phar::mungServer</function> is used to modify the values of
|
|
the <varname>$_SERVER</varname> array to trick applications that process these values.
|
|
<function>Phar::interceptFileFuncs</function> instructs Phar to intercept calls to
|
|
<function>fopen</function>, <function>file_get_contents</function>, <function>opendir</function>, and
|
|
all of the stat-based functions (<function>file_exists</function>, <function>is_readable</function> and so on) and
|
|
route all relative paths to locations within the phar archive.
|
|
</para>
|
|
<para>
|
|
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 <literal>phpMyAdmin.phar.tar.php</literal> can be accessed as a regular file
|
|
from your web server after modifying the user/password:
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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();
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
</section>
|
|
<section xml:id="phar.using.stream" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Using Phar Archives: the phar stream wrapper</title>
|
|
<para>
|
|
The Phar stream wrapper fully supports <function>fopen</function> for
|
|
read and write (not append), <function>unlink</function>, <function>stat</function>,
|
|
<function>fstat</function>, <function>fseek</function>, <function>rename</function>
|
|
and directory stream operations <function>opendir</function> and <function>rmdir</function>
|
|
and <function>mkdir</function>.
|
|
</para>
|
|
<para>
|
|
Individual file compression and per-file metadata can also be manipulated
|
|
in a Phar archive using stream contexts:
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$context = stream_context_create(array('phar' =>
|
|
array('compress' => Phar::GZ)),
|
|
array('metadata' => array('user' => 'cellog')));
|
|
file_put_contents('phar://my.phar/somefile.php', 0, $context);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
The <literal>phar</literal> stream wrapper does not operate on remote files,
|
|
and cannot operate on remote files, and so is allowed even when the
|
|
<link linkend="ini.allow-url-fopen">allow_url_fopen</link> and
|
|
<link linkend="ini.allow-url-include">allow_url_include</link> INI options
|
|
are disabled.
|
|
</para>
|
|
<para>
|
|
Although it is possible to create phar archives from scratch just using
|
|
stream operations, it is best to use the functionality built into
|
|
the Phar class. The stream wrapper is best used for read-only operations.
|
|
</para>
|
|
</section>
|
|
<section xml:id="phar.using.object" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Using Phar Archives: the Phar and PharData class</title>
|
|
<para>
|
|
The <classname>Phar</classname> class supports reading and manipulation
|
|
of Phar archives, as well as iteration through inherited functionality of
|
|
the <classname>RecursiveDirectoryIterator</classname>
|
|
class. With support for the <classname>ArrayAccess</classname>
|
|
interface, files inside a Phar archive can be accessed as if they were
|
|
part of an associative array.
|
|
</para>
|
|
<para>
|
|
The <classname>PharData</classname> class extends the <classname>Phar</classname>, and
|
|
allows creating and modifying non-executable (data) tar and zip archives even if
|
|
<literal>phar.readonly</literal>=1 in php.ini. As such,
|
|
<function>PharData::setAlias</function> and <function>PharData::setStub</function>
|
|
are both disabled as the concept of alias and stub are unique to executable phar
|
|
archives.
|
|
</para>
|
|
<para>
|
|
It is important to note that when creating a Phar archive, the full path
|
|
should be passed to the <classname>Phar</classname> object constructor.
|
|
Relative paths will fail to initialize.
|
|
</para>
|
|
<para>
|
|
Assuming that <literal>$p</literal> is a Phar object initialized as follows:
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$p = new Phar('/path/to/myphar.phar', 0, 'myphar.phar');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
An empty Phar archive will be created at <literal>/path/to/myphar.phar</literal>,
|
|
or if <literal>/path/to/myphar.phar</literal> already exists, it will be opened
|
|
again. The literal <literal>myphar.phar</literal> demonstrates the concept of an alias
|
|
that can be used to reference <literal>/path/to/myphar.phar</literal> in URLs as in:
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// these two calls to file_get_contents() are equivalent if
|
|
// /path/to/myphar.phar has an explicit alias of "myphar.phar"
|
|
// in its manifest, or if the phar was initialized with the
|
|
// previous example's Phar object setup
|
|
$f = file_get_contents('phar:///path/to/myphar.phar/whatever.txt');
|
|
$f = file_get_contents('phar://myphar.phar/whatever.txt');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
With the newly created <literal>$p</literal> <classname>Phar</classname> object,
|
|
the following is possible:
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
<literal>$a = $p['file.php']</literal> creates a <classname>PharFileInfo</classname>
|
|
class that refers to the contents of <literal>phar://myphar.phar/file.php</literal>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<literal>$p['file.php'] = $v</literal> creates a new file
|
|
(<literal>phar://myphar.phar/file.php</literal>), or overwrites
|
|
an existing file within <literal>myphar.phar</literal>. <literal>$v</literal>
|
|
can be either a string or an open file pointer, in which case the entire
|
|
contents of the file will be used to create the new file. Note that
|
|
<literal>$p->addFromString('file.php', $v)</literal> is functionally
|
|
equivalent to the above. Also possible is to add the contents of a file
|
|
with <literal>$p->addFile('/path/to/file.php', 'file.php')</literal>.
|
|
Lastly, an empty directory can be created with
|
|
<literal>$p->addEmptyDir('empty')</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<literal>isset($p['file.php'])</literal> can be used to determine
|
|
whether <literal>phar://myphar.phar/file.php</literal> exists within
|
|
<literal>myphar.phar</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<literal>unset($p['file.php'])</literal> erases
|
|
<literal>phar://myphar.phar/file.php</literal> from
|
|
<literal>myphar.phar</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
<para>
|
|
In addition, the <classname>Phar</classname> object is the only way to access
|
|
Phar-specific metadata, through
|
|
<function>Phar::getMetadata</function>,
|
|
and the only way to set or retrieve a Phar archive's PHP loader stub through
|
|
<function>Phar::getStub</function> and
|
|
<function>Phar::setStub</function>.
|
|
Additionally, compression for the entire Phar archive at once can only be manipulated
|
|
using the <classname>Phar</classname> class.
|
|
</para>
|
|
<para>
|
|
The full list of <classname>Phar</classname> object functionality is documented
|
|
below.
|
|
</para>
|
|
<para>
|
|
The <classname>PharFileInfo</classname> class extends the
|
|
<classname>SplFileInfo</classname>
|
|
class, and adds several methods for manipulating Phar-specific details of a file
|
|
contained within a Phar, such as manipulating compression and metadata.
|
|
</para>
|
|
</section>
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|