1
0
mirror of https://github.com/php/doc-fr.git synced 2026-03-23 22:52:18 +01:00
Files
archived-doc-fr/reference/phar/using.xml
Louis-Arnaud 5755a1bd8c Style impersonnel dans reference/ (a-d) (#2539)
* style: remplacer vous/votre/vos par style impersonnel dans reference/[a-d]*
2026-02-25 11:54:29 +01:00

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 d'OpenSSL.
Pour tirer parti de la signature OpenSSL, il faut 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 du 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 manifeste, ou si le phar a été initialisé avec l'instantiation de
// l'objet Phar de l'exemple précédent
$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. À noter que
<literal>$p-&gt;addFromString('fichier.php', $v)</literal> est équivalent en termes de
fonctionnalité au cas ci-dessus. Il est aussi possible d'ajouter le contenu d'un fichier
avec <literal>$p-&gt;addFile('/chemin/vers/fichier.php', 'fichier.php')</literal>.
Enfin, un répertoire vide peut être créé avec
<literal>$p-&gt;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
-->