cvs: phpdoc-ca /features file-upload.xml

[email protected] ("Eduard Capell Brufau") Mon, 29 Aug 2005 19:08:05 -0000
Newsgroups php.doc.ca
Message-ID <cvseduardcapell1125342485@cvsserver>
--eduardcapell1125342485
Content-Type: text/plain

eduardcapell		Mon Aug 29 15:08:05 2005 EDT

  Added files:                 
    /phpdoc-ca/features	file-upload.xml 
  Log:
  
  
--eduardcapell1125342485
Content-Type: text/plain
Content-Disposition: attachment; filename="eduardcapell-20050829150805.txt"


http://cvs.php.net/co.php/phpdoc-ca/features/file-upload.xml?r=1.1&p=1
Index: phpdoc-ca/features/file-upload.xml
+++ phpdoc-ca/features/file-upload.xml
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- $Revision: 1.1 $ -->
<!-- EN-Revision: 1.86 Maintainer: eduardcapell Status: ready -->
 <chapter id="features.file-upload">
  <title>Gestió de les càrregues de fitxers</title>

  <sect1 id="features.file-upload.post-method">
   <title>Càrregues amb el mètode POST</title>
   <simpara>
    Aquesta característica permet que la gent carregui fitxers de text i
    binaris. Amb les funcions de PHP d'autenticació i de manipulació de fitxers,
    teniu un control complert sobre qui pot carregar fitxers i que se'n fa
    d'aquests fitxers un cop s'han rebut al servidor.
   </simpara>
   <simpara>
    El PHP pot rebre càrregues de fitxers des de qualsevol navegador que
    compleixi amb l'estàndard RFC-1867 (això inclou 
    <productname>Netscape Navigator 3</productname> o superior, 
    <productname>Microsoft Internet Explorer 3</productname> 
    amb un pegat de Microsoft, o posteriors sense el pegat).
   </simpara>

   <note>
    <title>Nota Relacionada amb Configuracions</title>
    <para>
     Vegeu també les directives 
     <link linkend="ini.file-uploads">file_uploads</link>, 
     <link linkend="ini.upload-max-filesize">upload_max_filesize</link>,
     <link linkend="ini.upload-tmp-dir">upload_tmp_dir</link>,
     <link linkend="ini.post-max-size">post_max_size</link> and
     <link linkend="ini.max-input-time">max_input_time</link>  
     a &php.ini;
    </para>
   </note>

   <para>
    El PHP també suporta càrregues amb el mètode PUT, tal com ho fan els 
    clients <productname>Netscape Composer</productname> i
    <productname>Amaya de W3C</productname>. Vegeu el 
    <link linkend="features.file-upload.put-method">Suport del Mètode 
    PUT</link> per més detalls.
   </para>

   <para>
    <example>
     <title>Formulari de Càrrega de Fitxers</title>
     <para>
      Una pantalla de càrrega de fitxers es pot construir amb un formulari
      especial que seria similar al següent:
     </para>
     <programlisting role="html">
     <!-- The HTML comments in this example code are stripped.
     This needs to be fixed in livedocs. -->
<![CDATA[
<!-- El tipus de codificació de les dades, enctype, HA DE SER especificat tal 
com està a continuació. -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
    <!-- MAX_FILE_SIZE ha de precedir el camp d'entrada -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- El nom de l'element d'entrada determina el nom al vector $_FILES -->
    Enviar aquest fitxer: <input name="userfile" type="file" />
    <input type="submit" value="Enviar" />
</form>
]]>
     </programlisting>
     <para>
      El literal <literal>__URL__</literal> de l'exemple anterior hauria de ser
      substituït, i hauria d'apuntar a un fitxer PHP.
     </para>
     <para>
      El camp ocult, <literal>MAX_FILE_SIZE</literal> (expressat en octets) ha
      de precedir el camp d'entrada del fitxer, i el seu valor serà el tamany
      màxim acceptat pel fitxer. És un valor que el navegador pot comprovar, i
      que PHP també comprova. És molt senzill d'enganyar els navegadors, i, per
      tant, no us fieu d'aquesta característica. Els paràmetres del PHP per
      maximum-size, en canvi, no poden ser enganyats. Aquest element del
      formulari s'hauria d'utilitzar sempre , ja que mira d'evitar que els
      usuaris passin per la molèstia d'esperar que un fitxer molt gran s'intenti
      transferir, per acabar comprovant que era massa gran i la transferència
      falla.
     </para>
    </example>
   </para>

   <note>
    <para>
     Assegureu-vos que el formulari de càrrega de fitxers té l'atribut 
     <literal>enctype="multipart/form-data"</literal>. Si no ho té, la càrrega
     del fitxer no funcionarà.
    </para>
   </note>

   <para>
    La variable global <link linkend="reserved.variables.files">$_FILES</link>
    existeix des de PHP 4.1.0 (Utilitzeu <varname>$HTTP_POST_FILES</varname> en
    el seu lloc si és el cas que utilitzeu una versió anterior). Aquests vectors
    contindran tota la informació sobre el fitxer carregat.
   </para>

   <para>
    El continut del vector 
    <link linkend="reserved.variables.files">$_FILES</link> del formulari
    d'exemple anterior seria de la manera que us mostrem a continuació. Se
    suposa que el camp del formulari que contè el fitxer  es diu 
    <emphasis>userfile</emphasis>, però podria ser qualsevol altre nom.
    <variablelist>
     <varlistentry>
      <term><varname>$_FILES['userfile']['name']</varname></term>
      <listitem>
       <para>
        El nom original del fitxer a la màquina client.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><varname>$_FILES['userfile']['type']</varname></term>
      <listitem>
       <para>
        El tipus mime del fitxer, si el navegador ha enviat aquesta informació.
        Un exemple seria <literal>"image/gif"</literal>. Aquest tipus mim, però,
        no es comprova per part de PHP, i, per tant, no tingueu la seguretat que
        aquest valor és del tot fiable.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><varname>$_FILES['userfile']['size']</varname></term>
      <listitem>
       <para>
        La mida, en octets, del fitxe carregat.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><varname>$_FILES['userfile']['tmp_name']</varname></term>
      <listitem>
       <para>
        El nom temporal del fitxer amb el qual ha estat guardat al servidor.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><varname>$_FILES['userfile']['error']</varname></term>
      <listitem>
       <para>
        El <link linkend="features.file-upload.errors">codi d'error</link>
        associat a aquesta càrrega. Aquest element es va afegir al PHP 4.2.0
       </para>
      </listitem>
     </varlistentry>
    </variablelist>
   </para>

   <para>
    Els fitxers seran desats per defecte a la carpeta temporal del servidor, si
    no és que s'ha especificat una altra ubicació a la directiva 
    <link linkend="ini.upload-tmp-dir">upload_tmp_dir</link> a &php.ini;. 
    La carpeta per defecte del servidor es pot canviar, establint la variable
    d'entorn <envar>TMPDIR</envar> en l'entorn en que corri el PHP.
    Establint-la amb la funció <function>putenv</function> des d'una seqüència
    PHP no funcionarà. Aquesta variable d'entorn també es pot utilitzar per
    assegurar-se que d'altres operacions funcionen en els fitxers carregats..
    <example>
     <title>Validació dels fitxers carregats</title>
     <para>
      Vegeu també les funcions <function>is_uploaded_file</function> i 
      <function>move_uploaded_file</function> per més informació. El següent
      exemple processa el fitxer carregat que ens ha arribat des d'un formulari.
     </para>
     <programlisting role="php">
<![CDATA[
<?php
// En versions de PHP anteriors a 4.1.0, s'ha d'utilitar $HTTP_POST_FILES 
// enlloc de $_FILES.

$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "El fitxer és vàlid i s'ha carregat correctament..\n";
} else {
    echo "Possible atac per càrrega de fitxer!\n";
}

echo 'Aquí teniu més informació de depuració:';
print_r($_FILES);

print "</pre>";

?>
]]>
     </programlisting>
    </example>
   </para>
   <simpara>
    La seqüència PHP que rep el fitxer carregat ha d'implementar la lògica
    necessària per tal de saber què cal fer amb el fitxer carregat. Potser
    voldreu, per exemple, utilitzar la variable 
    <varname>$_FILES['userfile']['size']</varname> per descartar els fitxers que
    són massa petits o massa grans. O bé podeu utilitzar la variable 
    <varname>$_FILES['userfile']['type']</varname> per a eliminar els fitxers
    que no compleixein certs criteris, però utilitzeu-la només com una primera
    part de la comprovació, perquè aquest valor està completament sota el
    control del client i no es comprova per part de PHP. Des de PHP 4.2.0, podeu
    utilitzar <varname>$_FILES['userfile']['error']</varname> i planificar la
    vostra lògica en funció dels 
    <link linkend="features.file-upload.errors">codis d'error</link>.
    En qualsevol cas, sigui quina sigui la lògica que empreu, sempre hauríeu
    d'esborrar el fitxer de la carpeta temporal, o moure'l a una altra ubicació.
   </simpara>
   <simpara>
    Si no s'ha seleccionat cap fitxer al formulari client, el PHP retornarà un
    valor 0 per <varname>$_FILES['userfile']['size']</varname> i un valor buit 
    en <varname>$_FILES['userfile']['tmp_name']</varname>.
   </simpara>
   <simpara>
    El fitxer s'esborrarà del directori temporal al final de la petició si no ha
    estat renomenat o mogut.
   </simpara>
    <example>
     <title>Càrrega d'un vector de fitxers</title>
     <para>
      El PHP suporta <link linkend="faq.html.arrays">vectors en HTML</link> fins
      i tot amb els fitxers.
     </para>
     <programlisting role="html">
<![CDATA[
<form action="" method="post" enctype="multipart/form-data">
<p>Pictures:
<input type="file" name="pictures[]" />
<input type="file" name="pictures[]" />
<input type="file" name="pictures[]" />
<input type="submit" value="Send" />
</p>
</form>
]]>
     </programlisting>
     <programlisting role="php">
<![CDATA[
<?php
foreach ($_FILES["pictures"]["error"] as $key => $error) {
    if ($error == UPLOAD_ERR_OK) {
        $tmp_name = $_FILES["pictures"]["tmp_name"][$key];
        $name = $_FILES["pictures"]["name"][$key];
        move_uploaded_file($tmp_name, "data/$name");
    }
}
?>
]]>
     </programlisting>
    </example>
  </sect1>

  <sect1 id="features.file-upload.errors">
   <title>Explicació dels Missatges d'Error</title>
   <simpara>
    Des de PHP 4.2.0, el PHP retorna un codi d'error corresponent juntament amb
    el vector del fitxer. El codi d'error el podem trobar al segment 
    <literal>error</literal> del vector que crea el PHP durant la càrrega del
    fitxer. En altres paraules, l'error el podem trobar a 
    <varname>$_FILES['userfile']['error']</varname>.
   </simpara>
   <para>
    <variablelist>
     <varlistentry>
      <term><constant>UPLOAD_ERR_OK</constant></term>
      <listitem>
       <para>
        Valor: 0; No hi ha errors, el fitxer s'ha carregat amb èxit.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><constant>UPLOAD_ERR_INI_SIZE</constant></term>
      <listitem>
       <para>
        Valor: 1; El fitxer carregat excedeix la directiva 
        <link linkend="ini.upload-max-filesize">upload_max_filesize</link> 
        de &php.ini;.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><constant>UPLOAD_ERR_FORM_SIZE</constant></term>
      <listitem>
       <para>
        Valor: 2; El fitxer carregat excedeix el valor 
        <emphasis>MAX_FILE_SIZE</emphasis> que estava especificada al formulari
        HTML.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><constant>UPLOAD_ERR_PARTIAL</constant></term>
      <listitem>
       <para>
        Valor: 3; El fitxer carregat només s'ha pogut carregar en part.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><constant>UPLOAD_ERR_NO_FILE</constant></term>
      <listitem>
       <para>
        Valor: 4; No s'ha carregat cap fitxer.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><constant>UPLOAD_ERR_NO_TMP_DIR</constant></term>
      <listitem>
       <para>
        Valor: 6; Falta una carpeta temporal. Això es va introduir al PHP 4.3.10
        i al PHP 5.0.3.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><constant>UPLOAD_ERR_CANT_WRITE</constant></term>
      <listitem>
       <para>
        Valor: 7; No s'ha pogut escriure al disc. Introduït al PHP 5.1.0.
       </para>
      </listitem>
     </varlistentry>
    </variablelist>
   </para>
   <note>
    <para>
     Els noms previs van passar a ser constants a partir de 4.3.0.
    </para>
   </note>
  </sect1>

  <sect1 id="features.file-upload.common-pitfalls">
   <title>Obstacles habituals</title>
   <simpara>
    L'ítem <literal>MAX_FILE_SIZE</literal> no pot establir un tamany de fitxer
    superior al valor indicat pel paràmetre ini 
    <link linkend="ini.upload-max-filesize">upload_max_filesize</link>. El valor
    per defecte és 2 Megabytes.
   </simpara>
   <simpara>
    Si s'ha establert un límit de memòria, potser farà falta un valor superior
    en la variable <link linkend="ini.memory-limit">memory_limit</link>.
    Assegureu-vos que reserveu una quantitat suficient de memòria al valor de 
    <link linkend="ini.memory-limit">memory_limit</link>.
   </simpara>
   <simpara>
    Si el valor de 
    <link linkend="ini.max-execution-time">max_execution_time</link> és massa
    petit, l'execució de la seqüència pot ser superior al valor indicat.
    Assegureu-vos que <literal>max_execution_time</literal> és prou gran.
   </simpara>
   <note>
    <simpara>
     <link linkend="ini.max-execution-time">max_execution_time</link> només
     afecta el temps d'execució de la pròpia seqüència. Qualsevol temps passat
     en activitat que té lloc fora de l'execució de la seqüència PHP, com ara
     crides al sistema (funció <function>system</function>, funció 
     <function>sleep</function>, consultes a bases de dades, temps ocupat pel 
     processament de la càrrega de fitxers, etc. no s'inclouen en el temps 
     d'execució de la seqüència.
    </simpara>
   </note>
   <warning>
    <simpara>
     <link linkend="ini.max-input-time">max_input_time</link> indica el màxim
     temps, en segons, que la seqüència pot dedicar a rebre dades; això inclou
     càrregues de fitxers. Per a fitxers grans, o fitxers múltiples, per a
     usuaris amb connexions lentes, el valor per defecte de 
     <literal>60 seconds</literal> pot ser massa petit.
    </simpara>
   </warning>
   <simpara>
    Si <link linkend="ini.post-max-size">post_max_size</link> està establert a
    un valor massa baix, no es podran carregar fitxers grans. Assegureu-vos que
    el valor de <literal>post_max_size</literal> és prou gran.
   </simpara>
   <simpara>
    Si no valideu el fitxer sobre el que treballeu, pot passar que els usuaris
    puguin accedir a informació sensible en altres directoris.
   </simpara>
   <simpara>
    Observeu que el <productname>CERN httpd</productname> sembla que elimina tot
    el que ve a continuació del primer espai en blanc en la capçalera del tipus
    de contingut mime. Mentre aquest sigui el cas, 
    <productname>CERN httpd</productname> no suportarà la característica de
    càrrega de fitxers.
   </simpara>
   <simpara>
    Degut a la gran quantitat d'estils de llistats de directoris, no podem
    garantir que fitxers amb noms exòtics (per exemple, amb espais), es puguin
    gestonar correctament.
   </simpara>
   <simpara>
    El desenvolupador no pot barrejar camps d'entrada normals i camps de càrrega
    de fitxers a la mateixa variable del formulari (utilitzant un nom de la
    variable d'entrada com ara <literal>foo[]</literal>).
   </simpara>
  </sect1>
  
  <sect1 id="features.file-upload.multiple">
   <title>Uploading multiple files</title>
   <simpara>
    Multiple files can be uploaded using different
    <literal>name</literal> for <literal>input</literal>.
   </simpara>
   <simpara>
    It is also possible to upload multiple files simultaneously and
    have the information organized automatically in arrays for you. To
    do so, you need to use the same array submission syntax in the
    HTML form as you do with multiple selects and checkboxes:
   </simpara>
   <note>
    <para>
     Support for multiple file uploads was added in PHP 3.0.10.
    </para>
   </note>
   <para>
    <example>
     <title>Càrrega de fitxers múltiples</title>
     <programlisting role="html">
<![CDATA[
<form action="file-upload.php" method="post" enctype="multipart/form-data">
  Send these files:<br />
  <input name="userfile[]" type="file" /><br />
  <input name="userfile[]" type="file" /><br />
  <input type="submit" value="Enviar els fitxers" />
</form>
]]>
     </programlisting>
    </example>
   </para>
   <simpara>
    Quan s'envia el formulari anterior, els vectors 
    <varname>$_FILES['userfile']</varname>,
    <varname>$_FILES['userfile']['name']</varname>, i
    <varname>$_FILES['userfile']['size']</varname> s'inicialitzaran (igual que 
    la variable <varname>$HTTP_POST_FILES</varname> per versions de PHP 
    anteriors a 4.1.0).
    
    Quan <link linkend="ini.register-globals">register_globals</link> està
    activada, les variables globals pels fitxers carregats també s'inicialitzen.
    Cada una d'aquestes serà un vector indexat numèricament, que contindrà els
    valors apropiats pels fitxers enviats.
   </simpara>
   <simpara>
    Per exemple, imagineu que hem rebut els fitxers amb els noms 
    <filename>/home/test/review.html</filename> i
    <filename>/home/test/xwp.out</filename>. En aquest cas, 
    <varname>$_FILES['userfile']['name'][0]</varname> contindria el valor 
    <filename>review.html</filename>, i 
    <varname>$_FILES['userfile']['name'][1]</varname> contindria el valor 
    <filename>xwp.out</filename>. De manera semblant,
    <varname>$_FILES['userfile']['size'][0]</varname> contindria el tamany de 
    <filename>review.html</filename> i així successivament.
   </simpara>
   <simpara>
    <varname>$_FILES['userfile']['name'][0]</varname>,
    <varname>$_FILES['userfile']['tmp_name'][0]</varname>,
    <varname>$_FILES['userfile']['size'][0]</varname>, i
    <varname>$_FILES['userfile']['type'][0]</varname> també tindran valors·
   </simpara>
  </sect1>

  <sect1 id="features.file-upload.put-method">
   <title>Suport del mètode PUT</title>
   <simpara>
    El suport del mètode PUT ha canviat entre les versions PHP 3 i PHP 4.
    A PHP 4, s'ha d'utilitzar el flux de dades d'entrada estàndard, per tal de
    llegir el contingut d'un HTTP PUT.
   </simpara>
   <para>
    <example>
     <title>Guardar fitxers amb HTTP PUT en PHP 4</title>
     <programlisting role="php">
<![CDATA[
<?php
/* Les dades PUT arriben en el flux stdin */
$putdata = fopen("php://stdin", "r");

/* Obrim un fitxer per escriptura */
$fp = fopen("myputfile.ext", "w");

/* Llegim les dades, 1KB cada cop, i les anem escrivint */
while ($data = fread($putdata, 1024))
  fwrite($fp, $data);

/* Tanquem els fluxes de dades */
fclose($fp);
fclose($putdata);
?>
]]>
     </programlisting>
    </example>
   </para>
   <note>
    <para>
     Tota la documentació següent fa referència exclusivament a PHP 3.
    </para>
   </note>
   <para>
    El PHP dóna suport al mètode HTTP PUT que és utilitzat per clients com 
    <productname>Netscape Composer</productname> i 
    <productname>W3C Amaya</productname>. Les peticions PUT són molt més simples
    que una càrrega de fitxer, i són semblants a:
    <informalexample>
     <programlisting role="HTTP">
<![CDATA[
PUT /path/filename.html HTTP/1.1
]]>
     </programlisting>
    </informalexample>
   </para>
   <para>
    Normalment això significaria que el client remot indicari el nom (amb la 
    ruta complerta) amb el qual s'hauria de guardar el fitxer al servidor, de la
    manera següent: <filename>/path/filename.html</filename>, relatiu a l'arrel 
    del servidor web. És evident que no és una bona idea que l'Apache o el PHP
    deixin de forma automàtica que qualsevol sobreescrigui qualsevol fitxer del
    servdidor web. Per tant, per a gestionar una petició així, primer se li ha
    de dir al servidor web que es vol que una seqüència PHP gestioni la petició.
    En Apache, això es fa amb la directiva <emphasis>Script</emphasis>. Es pot
    posar aquesta directiva pràcticament a qualsevol lloc del fitxer de
    configuració de l'Apache. Un lloc habitual és dins d'un bloc 
    &lt;Directory&gt; o bé &lt;Virtualhost&gt; block. La línia seria així:
    <informalexample>
     <programlisting>
<![CDATA[
Script PUT /put.php
]]>
     </programlisting>
    </informalexample>
   </para>
   <simpara>
    Això li diria a l'Apache que totes les peticions PUT que s'ajustin al
    context en què posem aquesta línia es transferiran a la seqüència put.php.
    Això suposa, evidentment, que hem habilitat el PHP per l'extensió .php i que
    el PHP està actiu.
   </simpara>
   <simpara>
    Dins del vostre fitxer put.php hi posaríem alguna cosa com això:
   </simpara>
   <para>
    <informalexample><programlisting role="php">
<![CDATA[
<?php copy($PHP_UPLOADED_FILE_NAME, $DOCUMENT_ROOT . $REQUEST_URI); ?>
]]>
    </programlisting></informalexample>
   </para>
   <simpara>
    Això copiaria el fitxer a la ubicació sol·licitada pel client. Probablement
    voldríem fer alguna operació de control i/o autenticació de l'usuari abans
    de fer la còpia del fitxer. L'únic truc especial aquí és el fet que quan el
    PHP veu una petició PUT, guarda el fitxer en una ubicació temporal, de la
    mateixa manera que les peticions amb el 
    <link linkend="features.file-upload.post-method">mètode POST</link>.
    Quan finalitza la petició, el fitxer temporal s'esborrarà. Per tan, la
    seqüència que gestiona la petició PUT ha de copiar el fitxer a algun altre
    lloc. El nom del fitxer temporal és a la variable 
    <varname>$PHP_PUT_FILENAME</varname> i podeu veure la destinació suggerida
    la variable <varname>$REQUEST_URI</varname> (aquest nom pot ser diferent en 
    servidors web no Apache). Aquest fitxer de destinació és el que el client ha
    indicat, i no necessàriament li hem de fer cas. Podríem, per exemple, copiar
    tots els fitxers carregats a una ubicació especial de càrregues de fitxers
    dels clients.
   </simpara>
  </sect1>

 </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:"../../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
-->

--eduardcapell1125342485--