File: file-upload.xml

package info (click to toggle)
phpdoc 20020310-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 35,272 kB
  • ctags: 354
  • sloc: xml: 799,767; php: 1,395; cpp: 500; makefile: 200; sh: 140; awk: 51
file content (371 lines) | stat: -rw-r--r-- 14,726 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
<?xml version="1.0" encoding="iso-8859-1"?>
 <chapter id="features.file-upload">
  <title>Bestanden uploaden naar server</title>

  <sect1 id="features.file-upload.post-method">
   <title>Met de POST methode uploaden</title>

   <simpara>
    PHP kan 'file uploads' ontvangen van elke browser welke de
    RFC-1867 standaard volgt (Zoals Netscape Navigator 3+ en Microsoft
    Internet Explorer 3 met een patch van Microsoft, of ouder zonder patch).
    Dit maakt het mogelijk voor mensen om text en binary bestanden te 
    uploaden. Met PHP's authenticatie en bestandsfuncties heb je volledige
    controle over wie waar wat mag uploaden en wat er met het bestand gebeurd
    zo gauw het geupload is.
   </simpara>
   <para>
    PHP ondersteunt ook de PUT-methode voor bestand uploads. Dit wordt 
    onder andere gebruikt door Netscape Composer en programma's die W3C's 
    Amaya gebruiken. Zie <link linkend="features.file-upload.put-method">
    PUT Methode Ondersteuning</link> voor meer details.
   </para>
   <para>
    Een 'bestands upload' scherm kan gemaakt worden met een speciaal form
    dat er zo uit ziet:
    <example>
    <title>Bestand Upload Form</title>
     <programlisting>
&lt;FORM ENCTYPE=&quot;multipart/form-data&quot; ACTION=&quot;_URL_&quot; METHOD=POST&gt;
&lt;INPUT TYPE=&quot;hidden&quot; name=&quot;MAX_FILE_SIZE&quot; value=&quot;1000&quot;&gt;
Send this file: &lt;INPUT NAME=&quot;userfile&quot; TYPE=&quot;file&quot;&gt;
&lt;INPUT TYPE=&quot;submit&quot; VALUE=&quot;Stuur Bestand&quot;&gt;
&lt;/FORM&gt;
     </programlisting>
    </example>
    De URL moet naar een PHP bestand wijzen. Het MAX_FILE_SIZE 'hidden' 
    veld moet VOOR het 'file input' veld komen en de waarde hiervan wordt
    gebruikt als de maximaal toegestane grootte van het bestand dat 
    geupload wordt. Deze waarde is in bytes.
   </para>

   <para>
    In PHP 3 worden de volgende variablen gevuld in het script
    zodra de upload succesvol is afgerond. (aangenomen wordt dat
    <link linkend="ini.register-globals">register_globals</link> 
    aan is gezet in <filename>php3.ini</filename>). Als <link
    linkend="ini.track-vars">track_vars</link> aanstaat zijn ze (ook) te 
    vinden in de globale array <varname>$HTTP_POST_VARS</varname>. 
    Let op: De variablen in het volgende voorbeeld hebben de prefix
    'userfile' zoals aangegeven is in het bovenstaande voorbeeld:

    <itemizedlist>
     <listitem>
      <simpara>
       <varname>$userfile</varname> - De tijdelijke bestandsnaam
       waarin het geuploade bestand is opgeslagen op de server.
      </simpara>
     </listitem>
     <listitem>
      <simpara>
       <varname>$userfile_name</varname> - De originele naam of
       het originele pad van het bestand op het systeem van de gebruiker. 
      </simpara>
     </listitem>
     <listitem>
      <simpara>
       <varname>$userfile_size</varname> - De grootte van het
       'ge-uploade' bestand in bytes. 
      </simpara>
     </listitem>
     <listitem>
      <simpara>
       <varname>$userfile_type</varname> - Het mime-type van het bestand
       als de browser deze informatie heeft meegestuurd. Een voorbeeld
       zou zijn: &quot;image/gif&quot;.
      </simpara>
     </listitem>
    </itemizedlist>
    Let op: het deel &quot;$userfile&quot; van de bovenstaande variablen
    is wat het NAME= veld van het INPUT veld met TYPE=file is. In het
    bovenstaande voorbeeld kozen we ervoor om het &quot;userfile&quot;
    te noemen.
   </para>

   <para>
    PHP 4 gedraagt zich enigzins anders, in PHP4 word de globale array
    <varname>$HTTP_POST_FILES</varname> aangemaakt waarin informatie over
    het ge-uploade bestand wordt opgeslagen. Deze is alleen te gebruiken
    als <link linkend="ini.track-vars">track_vars</link> is aangezet.
    In alle versies na PHP 4.0.2 staat deze echter standaard aan.
   </para>

   <para>
    De inhoud van <varname>$HTTP_POST_FILES</varname> is als volgt:
    (Hier word weer gebruik gemaakt van &quot;userfile&quot; zoals in het
    bovenstaande voorbeeld.)
    <variablelist>
     <varlistentry>
      <term><varname>$HTTP_POST_FILES['userfile']['name']</varname></term>
      <listitem>
       <para>
        De originele naam van het bestand op het systeem van de gebruiker.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><varname>$HTTP_POST_FILES['userfile']['type']</varname></term>
      <listitem>
       <para>
        Het mime-type van het bestand als de browser deze informatie
        meegestuurd heeft. Bijvoorbeeld:
        <literal>&quot;image/gif&quot;</literal>.
        </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><varname>$HTTP_POST_FILES['userfile']['size']</varname></term>
      <listitem>
       <para>
        De grootte van het ge-uploade bestand in bytes.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><varname>$HTTP_POST_FILES['userfile']['tmp_name']</varname></term>
      <listitem>
       <para>
        De tijdelijke bestandsnaam waarin het ge-uploade bestand is 
        opgeslagen op de server. 
       </para>
      </listitem>
     </varlistentry>
    </variablelist>
   </para>

   <para>
    Ge-uploade bestanden worden standaard in de standaard tijdelijke
    directory van de server opgeslagen, tenzij er een andere locatie
    is opgegeven met het
    <link linkend="ini.upload-tmp-dir">upload_tmp_dir</link> directive in
    <filename>php.ini</filename>. De server zijn standaard tijdelijke
    kan worden veranderd worden door de 'environment' variable
    <envar>TMPDIR</envar> te veranderen in het 'environment' waar PHP
    in draait. Dit kun je <emphasis>niet</emphasis> doen in een script
    met de PHP functie <function>putenv</function>. Deze 'environment'
    variable kan ook gebruikt worden om te controleren of bewerkingen
    op ge-uploade bestanden wel juist werken.
    <example>
     <title>Validating file uploads</title>
     <para>
      De volgende voorbeelden zijn voor PHP 3 versies boven 3.0.16 en
      voor PHP 4 versies boven 4.0.2. Kijk voor meer informatie bij
      de functies <function>is_uploaded_file</function> en
      <function>move_uploaded_file</function>. 
     </para>
     <programlisting role="php">
&lt?php 
if (is_uploaded_file($userfile)) {
    copy($userfile, "/plaats/voor/ge-uploadbestand");
} else {
    echo "Mogelijke file-upload aanval: bestandsnaam '$userfile'.";
}
/* ...of... */
move_uploaded_file($userfile, "/plaats/voor/ge-uploadbestand");
?>
     </programlisting>
     <para>
      Voor eerdere versies van PHP zal je iets als het volgende moeten
      gebruiken.
      <note>
       <para>
        Dit zal <emphasis>niet</emphasis> werken in PHP 4 versies ouder
        dan 4.0.2. Dit voorbeeld is afhankelijk van een bepaalde
        functionaliteit in PHP welke veranderd is na deze versie.
       </para>
      </note>
     </para>
     <programlisting role="php">
&lt?php 
/* Gebruikerstest voor ge-upload bestand. */ 
function is_uploaded_file($filename) {
    if (!$tmp_file = get_cfg_var('upload_tmp_dir')) {
        $tmp_file = dirname(tempnam('', ''));
    }
    $tmp_file .= '/' . basename($filename);
    /* Gebruiker kan een slash als einde hebben in php.ini... */
    return (ereg_replace('/+', '/', $tmp_file) == $filename);
}

if (is_uploaded_file($userfile)) {
    copy($userfile, "/plaats/voor/ge-uploadbestand");
} else {
    echo "Mogelijke bestands-upload aanval: bestandsnaam '$userfile'.";
}
?>
     </programlisting>
    </example>
   </para>
   <simpara>
    Het PHP script welke het ge-uploade bestand ontvangt moet zelf
    implementeren wat er moet gebeuren met het ge-uploade bestand.
    Je kunt bijvoorbeeld besluiten om bestanden weg te gooien welke
    groter of juist kleiner zijn dan de <varname>$file_size</varname> 
    variable. Je kunt de <varname>$file_type</varname> variable gebruiken
    om bestanden te verwijderen welke niet voldoen aan een bepaald criteria.
    Wat je ook doet, je moet het bestand uit de tijdelijke directory 
    verwijderen of het verplaatsen naar een andere directory.
   </simpara>
   <simpara>
    Het bestand zal worden verwijderd uit de tijdelijke directory aan
    het einde van het script als het bestand niet verplaatst of hernoemd is.
   </simpara>
  </sect1>
 
  <sect1 id="features.file-upload.common-pitfalls">
   <title>Standaard valkuilen</title>
   <simpara>
    Het veld MAX_FILE_SIZE kan geen grotere bestandsgrootte opgeven dan
    de maximale grootte die is aangegeven met upload_max_filesize in php.ini
    of met het php_upload_max_filesize Apache .conf directive.
    Standaard is de maximale grootte 2 Megabytes.
   </simpara>
   <simpara>
    Als je niet controleert of je op het juiste bestand bewerkingen
    uitvoert, kunnen gebruikers hiervan misbruik maken en gevoelige
    informatie in andere directories benaderen.
   </simpara>
   <simpara>
    Let op: CERN httpd haalt alles voor de eerste spatie weg in de 
    content-type mime header die gestuurd word door de gebruiker.
    Zolang CERN httpd dit doet ondersteunt PHP voor deze server
    niet de bestands-upload mogelijkheid.
   </simpara>
  </sect1>

  <sect1 id="feature-fileupload.multiple">
   <title>Meerdere bestanden uploaden</title>
   <simpara>
    Het is mogelijk meerdere bestanden tegelijk te uploaden. Deze
    informatie kun je ge-ordend in arrays verkrijgen. Om dit mogelijk
    te maken moet je dezelfde syntax gebruiken als bij een HTML form
    met meerdere selects en/of checkboxes.
   </simpara>
   <note>
    <para>
     Ondersteuning voor meerdere file uploads werd toegevoegd in
     versie 3.0.10.
    </para>
   </note>
   <para>
    <example>
     <title>Meerdere bestanden uploaden</title>
     <programlisting>
&lt;form action=&quot;file-upload.php&quot; method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&gt;
  Send these files:&lt;br&gt;
  &lt;input name=&quot;userfile[]&quot; type=&quot;file&quot;&gt;&lt;br&gt;
  &lt;input name=&quot;userfile[]&quot; type=&quot;file&quot;&gt;&lt;br&gt;
  &lt;input type=&quot;submit&quot; value=&quot;Send files&quot;&gt;
&lt;/form&gt;
     </programlisting>
    </example>
   </para>
   <simpara>
    Als het bovenstaande form verstuurd wordt, worden de globale arrays
    <computeroutput>$userfile</computeroutput>,  
    <computeroutput>$userfile_name</computeroutput> and
    <computeroutput>$userfile_size</computeroutput> aangemaakt in
    de globale scope (ook $HTTP_POST_FILES (PHP 4) en $HTTP_POST_VARS (PHP 3)
    worden aangemaakt.) Deze arrays zijn numeriek geindexeerde arrays met de
    juiste waarden voor de ge-uploade bestanden.
   </simpara>
   <simpara>
    Bijvoorbeeld, stel dat de bestanden
    <filename>/home/test/review.html</filename> en
    <filename>/home/test/xwp.out</filename> ge-upload worden.
    In dit geval zou <computeroutput>$userfile_name[0]</computeroutput>
    de waarde <computeroutput>review.html</computeroutput> en 
    <computeroutput>$userfile_name[1]</computeroutput> de waarde
    <computeroutput>xwp.out</computeroutput> bevatten. Navolgend
    zou <computeroutput>$userfile_size[0]</computeroutput> de grootte
    van het bestand <filename>review.html</filename>'s bevatten,
    enzovoort.
   </simpara>
   <simpara>
    <computeroutput>$userfile['name'][0]</computeroutput>,
    <computeroutput>$userfile['tmp_name'][0]</computeroutput>,
    <computeroutput>$userfile['size'][0]</computeroutput> en
    <computeroutput>$userfile['type'][0]</computeroutput> zijn ook beschikbaar.
   </simpara>
  </sect1>

  <sect1 id="features.file-upload.put-method">
   <title>PUT methode ondersteuning</title>

   <para>
    PHP ondersteunt ook de HTTP PUT methode welke gebruikt wordt door 
    o.a. Netscape Composer en W3C Amaya. PUT aanvragen zijn veel simpeler
    dan een bestand uploaden en zien er ongeveer als volgt uit:
    <informalexample>
     <programlisting>
PUT /pad/bestandsnaam.html HTTP/1.1
     </programlisting>
    </informalexample>
   </para>
   <para>
    Dit betekent normaal gezien dat de server het bestand ook als
    /pad/filename.html wilt opslaan. Dit is natuurlijk geen goed idee
    omdat je niet wilt dat anderen bestanden overschrijven in je web tree.
    Om zo'n 'request' te verwerken vertel je je server eerst met wat voor
    PHP script je dit request wilt verwerken. Met Apache kun je dit doen
    met het <emphasis>Script</emphasis> directive. Het kan ongeveer 
    overal in je configuratie bestand geplaatst worden. Een standaard
    plaats hiervoor is bijvoorbeeld een &lt;Directory&gt; blok. 
    Een enkele regel als voorbeeld:
    <informalexample>
     <programlisting>
Script PUT /put.php
     </programlisting>
    </informalexample>
   </para>
   <simpara>
    Dit vertelt Apache om alle PUT requests waarvoor URIs die overeenkomen
    met de context waarin deze regel geplaatst is, naar het put.php script
    te sturen. We gaan er vanuit dat je de juist mime-headers heb gebruikt
    om PHP met de .php extensie te laten werken en dat PHP actief is.
   </simpara>
   <simpara>
    In je 'put.php' zou je dan iets als volgt neer zetten:
   </simpara>
   <para>
    <informalexample><programlisting>
&lt;? copy($PHP_UPLOADED_FILE_NAME,$DOCUMENT_ROOT.$REQUEST_URI); ?&gt;
    </programlisting></informalexample>
   </para>
   <simpara>
    Dit kopieert het bestand naar de locatie welke gevraagd werd in 
    het request. Waarschijnlijk zal je nog enige tests uitvoeren op 
    het bestand voordat je het bestand daadwerkelijk kopieert. De enige
    truc hier is dat PHP het bestand opslaat in een tijdelijk bestand
    zoals bij de
    <link linkend="features.file-upload.post-method">POST-methode</link>.
    Zogauw het request is afgehandeld word het tijdelijke bestand verwijderd.
    Let dus op dat je script het tijdelijke bestand verplaatst of hernoemd.
    De naam van dit tijdelijke bestand is opgeslagen in de variable
    <varname>$PHP_PUT_FILENAME</varname> en je kunt de voorgestelde locatie
    vinden in <varname>$REQUEST_URI</varname> (Dit kan anders zijn bij
    niet-Apache web servers). Dit is nogmaals een suggestie van de 
    gebruiker. Je hoeft deze suggestie niet te gebruiken, je kunt
    bijvoorbeeld alle bestanden in een speciale uploads directory plaatsen.
   </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:
-->