mirror of
https://github.com/macintoshplus/doc-fr.git
synced 2026-03-24 08:52:09 +01:00
393 lines
16 KiB
XML
393 lines
16 KiB
XML
<?xml version='1.0' encoding='utf-8'?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: e9f972da6918eabb189ba377822a1d6ad982c96d Maintainer: jpauli Status: ready -->
|
|
<!-- Reviewed: yes -->
|
|
<chapter xml:id="phar.using" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Utiliser les archives Phar</title>
|
|
|
|
<section xml:id="phar.using.intro" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Utiliser les archives Phar : Introduction</title>
|
|
<para>
|
|
Les archives Phar sont identiques dans le concept aux archives JAR
|
|
de Java, mais sont conçues plus spécifiquement pour les besoins et
|
|
la flexibilité des applications PHP. Une archive Phar est utilisée
|
|
pour distribuer une application PHP complète ou une bibliothèque
|
|
sous forme d'un fichier unique.
|
|
Une application sous forme d'archive Phar est utilisée exactement de
|
|
la même façon que n'importe quelle autre application PHP :
|
|
</para>
|
|
<screen>
|
|
<![CDATA[
|
|
php applicationsympa.phar
|
|
]]>
|
|
</screen>
|
|
<para>
|
|
L'utilisation d'une bibliothèque sous forme d'archive Phar est la
|
|
même que n'importe quelle autre bibliothèque PHP :
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
include 'bibliothequesympa.phar';
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Le flux <literal>phar</literal> fournit le cœur de l'extension phar, et
|
|
est décrit en détails <link linkend="phar.using.stream">ici</link>.
|
|
Le flux phar permet l'accès aux fichiers contenus dans une archive phar via les
|
|
fonctions standards de fichier <function>fopen</function>, <function>opendir</function>, et
|
|
toute autre fonctionnant sur des fichiers normaux. Le flux <literal>phar</literal> supporte toutes
|
|
les opérations de lecture/écriture à la fois sur les fichiers et sur les répertoires.
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
include 'phar://bibliothequesympa.phar/fichier/interne.php';
|
|
header('Content-type: image/jpeg');
|
|
// les phars peuvent être atteint via le chemin complet ou via des alias
|
|
echo file_get_contents('phar:///chemin/complet/vers/bibliothequesympa.phar/images/wow.jpg');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
La classe <classname>Phar</classname> implémente des fonctionnalités
|
|
avancées pour accéder aux fichiers et créer des archives phar. La
|
|
classe Phar est décrite en détails <link linkend="phar.using.object">ici</link>.
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
try {
|
|
// ouvre un phar existant
|
|
$p = new Phar('bibliothequesympa.phar', 0);
|
|
// Phar étend la classe DirectoryIterator de SPL
|
|
foreach (new RecursiveIteratorIterator($p) as $file) {
|
|
// $file est une classe PharFileInfo et hérité de SplFileInfo
|
|
echo $file->getFileName() . "\n";
|
|
echo file_get_contents($file->getPathName()) . "\n"; // affiche le contenu;
|
|
}
|
|
if (isset($p['fichier/interne.php'])) {
|
|
var_dump($p['fichier/interne.php']->getMetadata());
|
|
}
|
|
|
|
// crée un nouveau phar - phar.readonly doit être à 0 dans php.ini
|
|
// phar.readonly est activé par défaut pour des raisons de sécurité.
|
|
// Sur des serveurs de production, les Phars n'ont pas besoin d'être créés,
|
|
// juste d'être exécutés.
|
|
if (Phar::canWrite()) {
|
|
$p = new Phar('nouveauphar.tar.phar', 0, 'nouveauphar.tar.phar');
|
|
// On crée une archive Phar basée sur tar, compressée par gzip (.tar.gz)
|
|
$p = $p->convertToExecutable(Phar::TAR, Phar::GZ);
|
|
|
|
// crée une transaction - rien n'est écrit dans nouveauphar.phar
|
|
// jusqu'à ce que stopBuffering() ne soit appelé, bien qu'un stockage temporaire soit requis
|
|
$p->startBuffering();
|
|
// ajoute tous les fichiers de /chemin/vers/leprojet dans le phar avec le préfixe "projet"
|
|
$p->buildFromIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator('/chemin/vers/leprojet')), '/chemin/vers/');
|
|
|
|
// ajoute un nouveau fichier en utilisant l'API d'accès par tableau
|
|
$p['fichier1.txt'] = 'Information';
|
|
$fp = fopen('grosfichier.dat', 'rb');
|
|
// copie toutes les données du flux
|
|
$p['data/grosfichier.dat'] = $fp;
|
|
|
|
if (Phar::canCompress(Phar::GZ)) {
|
|
$p['data/grosfichier.dat']->compress(Phar::GZ);
|
|
}
|
|
|
|
$p['images/wow.jpg'] = file_get_contents('images/wow.jpg');
|
|
// toute valeur peut être sauvegardée comme métadonnée spécifique au fichier
|
|
$p['images/wow.jpg']->setMetadata(array('mime-type' => 'image/jpeg'));
|
|
$p['index.php'] = file_get_contents('index.php');
|
|
$p->setMetadata(array('bootstrap' => 'index.php'));
|
|
|
|
// sauvegarde l'archive phar sur le disque
|
|
$p->stopBuffering();
|
|
}
|
|
} catch (Exception $e) {
|
|
echo 'N\'a pas pu ouvrir le Phar: ', $e;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
D'autre part, la vérification du contenu du fichier phar peut être faite en utilisant un des
|
|
algorithme de signature symétrique (MD5, SHA1, SHA256 et SHA512 si ext/hash est activée) et
|
|
en utilisant la signature asymétrique par clé publique/privée de OpenSSL.
|
|
Pour tirer parti de la signature OpenSSL, vous devez générer une paire de clés publique/privée et
|
|
utiliser la clé privée pour signer avec <function>Phar::setSignatureAlgorithm</function>. En plus, la
|
|
clé publique, extraite en utilisant ce code :
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$public = openssl_get_publickey(file_get_contents('private.pem'));
|
|
$pkey = '';
|
|
openssl_pkey_export($public, $pkey);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
doit être sauvegardée à part de l'archive phar qu'elle vérifie. Si l'archive phar est sauvegardée
|
|
en tant que <literal>/chemin/vers/mon.phar</literal>, la clé publique doit être sauvegardée en tant
|
|
que <literal>/chemin/vers/mon.phar.pubkey</literal>, sans quoi phar ne sera pas capable de vérifier
|
|
la signature OpenSSL.
|
|
</para>
|
|
<para>
|
|
La classe <classname>Phar</classname> fournit aussi trois méthodes statiques, <function>Phar::webPhar</function>,
|
|
<function>Phar::mungServer</function> et <function>Phar::interceptFileFuncs</function> qui sont cruciales
|
|
pour empaqueter des applications PHP visant à être utilisée sur un système de fichiers classique ou en tant qu'application web.
|
|
<function>Phar::webPhar</function> implémente un contrôleur qui route les appels HTTP vers le bon endroit de l'archive phar.
|
|
<function>Phar::mungServer</function> est utilisé pour modifier les valeurs du tableau <varname>$_SERVER</varname> pour
|
|
dire aux applications d'utiliser ces valeurs. <function>Phar::interceptFileFuncs</function> dit à Phar d'intercepter les appels à
|
|
<function>fopen</function>, <function>file_get_contents</function>, <function>opendir</function>, et
|
|
à toutes les fonctions basées sur stat (<function>file_exists</function>, <function>is_readable</function>, etc) et
|
|
route tous les chemins relatif vers les bons endroits de l'archive phar.
|
|
</para>
|
|
<para>
|
|
Par exemple, empaqueter une version de la célèbre application phpMyAdmin dans une archive phar nécessite
|
|
juste ce simple script et, dès lors, <literal>phpMyAdmin.phar.tar.php</literal> peut être accédé comme un fichier
|
|
classique à partir de votre serveur web, après avoir modifié le couple utilisateur/motdepasse :
|
|
</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>Utiliser les archives Phar : le flux phar</title>
|
|
<para>
|
|
Le flux Phar supporte totalement <function>fopen</function> pour les
|
|
lectures/écritures (pas les concaténations), <function>unlink</function>, <function>stat</function>,
|
|
<function>fstat</function>, <function>fseek</function>, <function>rename</function>,
|
|
et les opérations de flux sur les répertoires <function>opendir</function>, et <function>rmdir</function>
|
|
et <function>mkdir</function>.
|
|
</para>
|
|
<para>
|
|
La compression et les métadonnées individuelles par fichier peuvent aussi être manipulées
|
|
au sein de l'archive Phar en utilisant les contextes de flux :
|
|
</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://mon.phar/unfichier.php', 0, $context);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Le flux <literal>phar</literal> n'agit pas sur les fichiers distants et ne peut pas
|
|
considérer les fichiers distants, etc... même si les options INI
|
|
<link linkend="ini.allow-url-fopen">allow_url_fopen</link> et
|
|
<link linkend="ini.allow-url-include">allow_url_include</link> sont
|
|
désactivées.
|
|
</para>
|
|
<para>
|
|
Bien qu'il soit possible de créer des archives phar de zéro en utilisant juste les
|
|
opérations sur les flux, il est préférable d'utiliser la fonctionnalité incluse dans
|
|
la classe Phar. Le flux est mieux utilisé pour les opérations de lecture.
|
|
</para>
|
|
</section>
|
|
<section xml:id="phar.using.object" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Utiliser les archives Phar : les classes Phar et PharData</title>
|
|
<para>
|
|
La classe <classname>Phar</classname> supporte la lecture et la manipulation des
|
|
archives Phar, ainsi que l'itération à travers la fonctionnalité héritée de la classe
|
|
<classname>RecursiveDirectoryIterator</classname>.
|
|
Avec le support de l'interface <classname>ArrayAccess</classname>,
|
|
les fichiers contenus dans une archive Phar peuvent être accédés
|
|
comme s'ils étaient membres d'un tableau associatif.
|
|
</para>
|
|
<para>
|
|
La classe <classname>PharData</classname> étend la classe <classname>Phar</classname>, et
|
|
permet la création et la modification d'archives tar et zip non exécutables (données) même si
|
|
<literal>phar.readonly</literal>=1 dans php.ini. Ainsi,
|
|
<function>PharData::setAlias</function> et <function>PharData::setStub</function>
|
|
sont toutes deux désactivées car les concepts d'alias et de conteneur sont restreints aux
|
|
archives phar exécutables.
|
|
</para>
|
|
<para>
|
|
Il est important de noter que quand une archive Phar est créée, le chemin complet
|
|
doit être passé au constructeur de l'objet <classname>Phar</classname>.
|
|
Un chemin relatif empêcherait l'initialisation.
|
|
</para>
|
|
<para>
|
|
En supposant que <literal>$p</literal> est un objet initialisé de cette façon :
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$p = new Phar('/chemin/vers/monphar.phar', 0, 'monphar.phar');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Une archive Phar vide sera créée en tant que <literal>/chemin/vers/monphar.phar</literal>,
|
|
ou si <literal>/chemin/vers/monphar.phar</literal> existe déjà, il sera ouvert
|
|
de nouveau. Le terme <literal>monphar.phar</literal> démontre le concept d'un alias
|
|
qui peut être utilisé pour référencer <literal>/chemin/vers/monphar.phar</literal> dans des URL comme ceci :
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// ces deux appels à file_get_contents() sont équivalents si
|
|
// /chemin/vers/monphar.phar a un alias explicite de "monphar.phar"
|
|
// dans son mainfeste, ou si le phar a été initialisé avec l'instantiation de
|
|
// l'objet Phar de l'exemple précedent
|
|
$f = file_get_contents('phar:///chemin/vers/monphar.phar/nimportequoi.txt');
|
|
$f = file_get_contents('phar://monphar.phar/nimportequoi.txt');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Avec l'objet <classname>Phar</classname> <literal>$p</literal> nouvellement créé,
|
|
les choses suivantes sont possibles :
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
<literal>$a = $p['fichier.php']</literal> crée une <classname>PharFileInfo</classname>
|
|
qui réfère au contenu de <literal>phar://monphar.phar/fichier.php</literal>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<literal>$p['fichier.php'] = $v</literal> crée un nouveau fichier
|
|
(<literal>phar://monphar.phar/fichier.php</literal>), ou écrase
|
|
un fichier existant au sein de <literal>monphar.phar</literal>. <literal>$v</literal>
|
|
peut être soit une chaîne ou un pointeur vers un fichier ouvert, dans quel cas
|
|
le contenu du fichier sera utilisé pour créer le nouveau fichier. Notez que
|
|
<literal>$p->addFromString('fichier.php', $v)</literal> est équivalent en terme de
|
|
fonctionnalité au cas ci-dessus. Il est aussi possible d'ajouter le contenu d'un fichier
|
|
avec <literal>$p->addFile('/chemin/vers/fichier.php', 'fichier.php')</literal>.
|
|
Enfin, un répertoire vide peut être créé avec
|
|
<literal>$p->addEmptyDir('vide')</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<literal>isset($p['fichier.php'])</literal> peut être utilisé pour déterminer
|
|
si <literal>phar://monphar.phar/fichier.php</literal> existe au sein de
|
|
<literal>monphar.phar</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<literal>unset($p['fichier.php'])</literal> efface
|
|
<literal>phar://monphar.phar/fichier.php</literal> de
|
|
<literal>monphar.phar</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
<para>
|
|
De plus, l'objet <classname>Phar</classname> est le seul moyen
|
|
d'accéder aux métadonnées spécifiques de Phar, via
|
|
<function>Phar::getMetadata</function>,
|
|
et c'est aussi le seul moyen de régler ou de récupérer le
|
|
conteneur du chargeur de l'archive Phar via
|
|
<function>Phar::getStub</function> et
|
|
<function>Phar::setStub</function>.
|
|
De plus, la compression pour l'archive Phar entière peut
|
|
être manipulée seulement via la classe <classname>Phar</classname>.
|
|
</para>
|
|
<para>
|
|
La liste complète des fonctionnalités de l'objet
|
|
<classname>Phar</classname> est documentée ci-dessous.
|
|
</para>
|
|
<para>
|
|
La classe <classname>PharFileInfo</classname> étend la classe
|
|
<classname>SplFileInfo</classname>
|
|
et ajoute plusieurs méthodes pour manipuler les métadonnées
|
|
spécifiques à Phar d'un fichier contenu dans un Phar,
|
|
telles que manipuler la compression ou les métadonnées.
|
|
</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
|
|
-->
|