mirror of
https://github.com/php/doc-es.git
synced 2026-03-23 23:12:09 +01:00
391 lines
16 KiB
XML
391 lines
16 KiB
XML
<?xml version='1.0' encoding='utf-8'?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: e9f972da6918eabb189ba377822a1d6ad982c96d Maintainer: PhilDaiguille Status: ready -->
|
|
<!-- Reviewed: yes -->
|
|
<chapter xml:id="phar.using" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Utilizar los archivos Phar</title>
|
|
|
|
<section xml:id="phar.using.intro" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Utilizar los archivos Phar : Introducción</title>
|
|
<para>
|
|
Los archivos Phar son idénticos en concepto a los archivos JAR
|
|
de Java, pero están diseñados específicamente para las necesidades y
|
|
la flexibilidad de las aplicaciones PHP. Un archivo Phar se utiliza
|
|
para distribuir una aplicación PHP completa o una biblioteca
|
|
en forma de un único archivo.
|
|
Una aplicación en forma de archivo Phar se utiliza exactamente de
|
|
la misma forma que cualquier otra aplicación PHP:
|
|
</para>
|
|
<screen>
|
|
<![CDATA[
|
|
php aplicacionesympa.phar
|
|
]]>
|
|
</screen>
|
|
<para>
|
|
El uso de una biblioteca en forma de archivo Phar es el mismo que cualquier otra biblioteca PHP:
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
include 'bibliothequesympa.phar';
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
El flujo <literal>phar</literal> proporciona el núcleo de la extensión phar, y
|
|
es descrito en detalle <link linkend="phar.using.stream">aquí</link>.
|
|
El flujo phar permite el acceso a los ficheros contenidos en un archivo phar mediante las
|
|
funciones estándar de ficheros <function>fopen</function>, <function>opendir</function>, y
|
|
cualquier otra que funcione con ficheros normales. El flujo <literal>phar</literal> soporta todas
|
|
las operaciones de lectura/escritura tanto en ficheros como en directorios.
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
include 'phar://bibliothequesympa.phar/fichero/interne.php';
|
|
header('Content-type: image/jpeg');
|
|
// los phars pueden ser alcanzados mediante la ruta completa o mediante alias
|
|
echo file_get_contents('phar:///ruta/completa/hacia/bibliothequesympa.phar/images/wow.jpg');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
La clase <classname>Phar</classname> implementa funcionalidades
|
|
avanzadas para acceder a los ficheros y crear archivos phar. La
|
|
clase Phar es descrita en detalle <link linkend="phar.using.object">aquí</link>.
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
try {
|
|
// abre un phar existente
|
|
$p = new Phar('bibliothequesympa.phar', 0);
|
|
// Phar extiende la clase DirectoryIterator de SPL
|
|
foreach (new RecursiveIteratorIterator($p) as $file) {
|
|
// $file es una clase PharFileInfo y heredada de SplFileInfo
|
|
echo $file->getFileName() . "\n";
|
|
echo file_get_contents($file->getPathName()) . "\n"; // muestra el contenido;
|
|
}
|
|
if (isset($p['fichero/interne.php'])) {
|
|
var_dump($p['fichero/interne.php']->getMetadata());
|
|
}
|
|
|
|
// crea un nuevo phar - phar.readonly debe ser 0 en php.ini
|
|
// phar.readonly está activado por omisión por razones de seguridad.
|
|
// En servidores de producción, los Phars no necesitan ser creados,
|
|
// solo ejecutados.
|
|
if (Phar::canWrite()) {
|
|
$p = new Phar('nuevophar.tar.phar', 0, 'nuevophar.tar.phar');
|
|
// Se crea un archivo Phar basado en tar, comprimido por gzip (.tar.gz)
|
|
$p = $p->convertToExecutable(Phar::TAR, Phar::GZ);
|
|
|
|
// crea una transacción - nada se escribe en nuevophar.phar
|
|
// hasta que stopBuffering() sea llamado, aunque se requiere almacenamiento temporal
|
|
$p->startBuffering();
|
|
// añade todos los ficheros de /ruta/hacia/elproyecto en el phar con el prefijo "proyecto"
|
|
$p->buildFromIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator('/ruta/hacia/elproyecto')), '/ruta/hacia/');
|
|
|
|
// añade un nuevo fichero utilizando la API de acceso por array
|
|
$p['fichero1.txt'] = 'Información';
|
|
$fp = fopen('grosfichero.dat', 'rb');
|
|
// copia todos los datos del flujo
|
|
$p['data/grosfichero.dat'] = $fp;
|
|
|
|
if (Phar::canCompress(Phar::GZ)) {
|
|
$p['data/grosfichero.dat']->compress(Phar::GZ);
|
|
}
|
|
|
|
$p['images/wow.jpg'] = file_get_contents('images/wow.jpg');
|
|
// cualquier valor puede ser guardado como metadatos específicos del fichero
|
|
$p['images/wow.jpg']->setMetadata(array('mime-type' => 'image/jpeg'));
|
|
$p['index.php'] = file_get_contents('index.php');
|
|
$p->setMetadata(array('bootstrap' => 'index.php'));
|
|
|
|
// guarda el archivo phar en el disco
|
|
$p->stopBuffering();
|
|
}
|
|
} catch (Exception $e) {
|
|
echo 'No ha podido abrir el Phar: ', $e;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Por otro lado, la verificación del contenido del archivo phar puede realizarse utilizando uno de
|
|
los algoritmos de firma simétrica (MD5, SHA1, SHA256 y SHA512 si ext/hash está activada) y
|
|
utilizando la firma asimétrica por clave pública/privada de OpenSSL.
|
|
Para aprovechar la firma OpenSSL, debe generarse un par de claves pública/privada y
|
|
utilizar la clave privada para firmar con <function>Phar::setSignatureAlgorithm</function>. Además, la
|
|
clave pública, extraída utilizando este código:
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$public = openssl_get_publickey(file_get_contents('private.pem'));
|
|
$pkey = '';
|
|
openssl_pkey_export($public, $pkey);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
debe ser guardada por separado del archivo phar que verifica. Si el archivo phar es guardado
|
|
como <literal>/ruta/hacia/mon.phar</literal>, la clave pública debe ser guardada como
|
|
<literal>/ruta/hacia/mon.phar.pubkey</literal>, de lo contrario phar no será capaz de verificar
|
|
la firma OpenSSL.
|
|
</para>
|
|
<para>
|
|
La clase <classname>Phar</classname> también proporciona tres métodos estáticos, <function>Phar::webPhar</function>,
|
|
<function>Phar::mungServer</function> y <function>Phar::interceptFileFuncs</function> que son cruciales
|
|
para empaquetar aplicaciones PHP destinadas a ser utilizadas en un sistema de ficheros clásico o como aplicación web.
|
|
<function>Phar::webPhar</function> implementa un controlador que enruta las llamadas HTTP al lugar correcto del archivo phar.
|
|
<function>Phar::mungServer</function> se utiliza para modificar los valores del array <varname>$_SERVER</varname> para
|
|
indicar a las aplicaciones que utilicen estos valores. <function>Phar::interceptFileFuncs</function> indica a Phar que intercepte las llamadas a
|
|
<function>fopen</function>, <function>file_get_contents</function>, <function>opendir</function>, y
|
|
a todas las funciones basadas en stat (<function>file_exists</function>, <function>is_readable</function>, etc) y
|
|
enruta todos los caminos relativos a los lugares correctos del archivo phar.
|
|
</para>
|
|
<para>
|
|
Por ejemplo, empaquetar una versión de la famosa aplicación phpMyAdmin en un archivo phar requiere
|
|
simplemente este script y, a partir de entonces, <literal>phpMyAdmin.phar.tar.php</literal> puede ser accedido como un fichero
|
|
clásico desde su servidor web, después de haber modificado la pareja usuario/contraseña:
|
|
</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 está destinado a ser ejecutado desde un navegador web\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>Utilizar los archivos Phar : el flujo phar</title>
|
|
<para>
|
|
El flujo Phar soporta totalmente <function>fopen</function> para las
|
|
lecturas/escrituras (no las concatenaciones), <function>unlink</function>, <function>stat</function>,
|
|
<function>fstat</function>, <function>fseek</function>, <function>rename</function>,
|
|
y las operaciones de flujo sobre los directorios <function>opendir</function>, y <function>rmdir</function>
|
|
y <function>mkdir</function>.
|
|
</para>
|
|
<para>
|
|
La compresión y los metadatos individuales por fichero pueden también ser manipulados
|
|
dentro del archivo Phar utilizando los contextos de flujo:
|
|
</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/unfichero.php', 0, $context);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
El flujo <literal>phar</literal> no actúa sobre los ficheros remotos y no puede
|
|
considerar los ficheros remotos, etc... incluso si las opciones INI
|
|
<link linkend="ini.allow-url-fopen">allow_url_fopen</link> y
|
|
<link linkend="ini.allow-url-include">allow_url_include</link> están
|
|
desactivadas.
|
|
</para>
|
|
<para>
|
|
Aunque es posible crear archivos phar desde cero utilizando solo las
|
|
operaciones sobre los flujos, es preferible utilizar la funcionalidad incluida en
|
|
la clase Phar. El flujo es mejor utilizado para las operaciones de lectura.
|
|
</para>
|
|
</section>
|
|
<section xml:id="phar.using.object" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Utilizar los archivos Phar : las clases Phar y PharData</title>
|
|
<para>
|
|
La clase <classname>Phar</classname> soporta la lectura y la manipulación de los
|
|
archivos Phar, así como la iteración a través de la funcionalidad heredada de la clase
|
|
<classname>RecursiveDirectoryIterator</classname>.
|
|
Con el soporte de la interfaz <classname>ArrayAccess</classname>,
|
|
los ficheros contenidos en un archivo Phar pueden ser accedidos
|
|
como si fueran miembros de un array asociativo.
|
|
</para>
|
|
<para>
|
|
La clase <classname>PharData</classname> extiende la clase <classname>Phar</classname>, y
|
|
permite la creación y modificación de archivos tar y zip no ejecutables (datos) incluso si
|
|
<literal>phar.readonly</literal>=1 en php.ini. Por lo tanto,
|
|
<function>PharData::setAlias</function> y <function>PharData::setStub</function>
|
|
están ambas desactivadas ya que los conceptos de alias y contenedor están restringidos a
|
|
los archivos phar ejecutables.
|
|
</para>
|
|
<para>
|
|
Es importante señalar que cuando un archivo Phar es creado, la ruta completa
|
|
debe ser pasada al constructor del objeto <classname>Phar</classname>.
|
|
Una ruta relativa impediría la inicialización.
|
|
</para>
|
|
<para>
|
|
Suponiendo que <literal>$p</literal> es un objeto inicializado de esta forma:
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$p = new Phar('/ruta/hacia/monphar.phar', 0, 'monphar.phar');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Un archivo Phar vacío será creado como <literal>/ruta/hacia/monphar.phar</literal>,
|
|
o si <literal>/ruta/hacia/monphar.phar</literal> ya existe, será abierto
|
|
de nuevo. El término <literal>monphar.phar</literal> demuestra el concepto de un alias
|
|
que puede ser utilizado para referenciar <literal>/ruta/hacia/monphar.phar</literal> en URLs como esto:
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// estas dos llamadas a file_get_contents() son equivalentes si
|
|
// /ruta/hacia/monphar.phar tiene un alias explícito de "monphar.phar"
|
|
// en su manifiesto, o si el phar fue inicializado con la instanciación de
|
|
// el objeto Phar del ejemplo anterior
|
|
$f = file_get_contents('phar:///ruta/hacia/monphar.phar/algo.txt');
|
|
$f = file_get_contents('phar://monphar.phar/algo.txt');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Con el objeto <classname>Phar</classname> <literal>$p</literal> recién creado,
|
|
las siguientes cosas son posibles:
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
<literal>$a = $p['fichero.php']</literal> crea una <classname>PharFileInfo</classname>
|
|
que se refiere al contenido de <literal>phar://monphar.phar/fichero.php</literal>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<literal>$p['fichero.php'] = $v</literal> crea un nuevo fichero
|
|
(<literal>phar://monphar.phar/fichero.php</literal>), o sobrescribe
|
|
un fichero existente dentro de <literal>monphar.phar</literal>. <literal>$v</literal>
|
|
puede ser una cadena o un puntero a un fichero abierto, en cuyo caso
|
|
el contenido del fichero será utilizado para crear el nuevo fichero. Tenga en cuenta que
|
|
<literal>$p->addFromString('fichero.php', $v)</literal> es equivalente en términos de
|
|
funcionalidad al caso anterior. También es posible añadir el contenido de un fichero
|
|
con <literal>$p->addFile('/ruta/hacia/fichero.php', 'fichero.php')</literal>.
|
|
Finalmente, un directorio vacío puede ser creado con
|
|
<literal>$p->addEmptyDir('vacío')</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<literal>isset($p['fichero.php'])</literal> puede ser utilizado para determinar
|
|
si <literal>phar://monphar.phar/fichero.php</literal> existe dentro de
|
|
<literal>monphar.phar</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
<literal>unset($p['fichero.php'])</literal> elimina
|
|
<literal>phar://monphar.phar/fichero.php</literal> de
|
|
<literal>monphar.phar</literal>.
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
<para>
|
|
Además, el objeto <classname>Phar</classname> es el único medio
|
|
de acceder a los metadatos específicos de Phar, mediante
|
|
<function>Phar::getMetadata</function>,
|
|
y es también el único medio de establecer o recuperar el
|
|
contenedor del cargador del archivo Phar mediante
|
|
<function>Phar::getStub</function> y
|
|
<function>Phar::setStub</function>.
|
|
Además, la compresión para el archivo Phar completo puede
|
|
ser manipulada solo mediante la clase <classname>Phar</classname>.
|
|
</para>
|
|
<para>
|
|
La lista completa de funcionalidades del objeto
|
|
<classname>Phar</classname> está documentada a continuación.
|
|
</para>
|
|
<para>
|
|
La clase <classname>PharFileInfo</classname> extiende la clase
|
|
<classname>SplFileInfo</classname>
|
|
y añade varios métodos para manipular los metadatos
|
|
específicos de Phar de un fichero contenido en un Phar,
|
|
tales como manipular la compresión o los metadatos.
|
|
</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
|
|
-->
|