features/file-upload.xml
fc174e8d6162091550edde46159917ee7e5a2e73
...
...
@@ -132,6 +132,15 @@
132
132
</para>
133
133
</listitem>
134
134
</varlistentry>
135
+
<varlistentry>
136
+
<term><varname>$_FILES['userfile']['full_path']</varname></term>
137
+
<listitem>
138
+
<para>
139
+
The full path as submitted by the browser. This value does not always contain a real directory structure, and cannot be trusted.
140
+
Available as of PHP 8.1.0.
141
+
</para>
142
+
</listitem>
143
+
</varlistentry>
135
144
</variablelist>
136
145
</para>
137
146

...
...
@@ -156,9 +165,6 @@
156
165
<programlisting role="php">
157
166
<![CDATA[
158
167
<?php
159
-
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
160
-
// of $_FILES.
161
-

162
168
$uploaddir = '/var/www/uploads/';
163
169
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
164
170

...
...
@@ -230,7 +236,9 @@ print "</pre>";
230
236
foreach ($_FILES["pictures"]["error"] as $key => $error) {
231
237
if ($error == UPLOAD_ERR_OK) {
232
238
$tmp_name = $_FILES["pictures"]["tmp_name"][$key];
233
-
$name = $_FILES["pictures"]["name"][$key];
239
+
// basename() may prevent filesystem traversal attacks;
240
+
// further validation/sanitation of the filename may be appropriate
241
+
$name = basename($_FILES["pictures"]["name"][$key]);
234
242
move_uploaded_file($tmp_name, "data/$name");
235
243
}
236
244
}
...
...
@@ -302,7 +310,7 @@ foreach ($_FILES["pictures"]["error"] as $key => $error) {
302
310
<term><constant>UPLOAD_ERR_NO_TMP_DIR</constant></term>
303
311
<listitem>
304
312
<para>
305
-
Value: 6; Missing a temporary folder. Introduced in PHP 5.0.3.
313
+
Value: 6; Missing a temporary folder.
306
314
</para>
307
315
</listitem>
308
316
</varlistentry>
...
...
@@ -310,7 +318,7 @@ foreach ($_FILES["pictures"]["error"] as $key => $error) {
310
318
<term><constant>UPLOAD_ERR_CANT_WRITE</constant></term>
311
319
<listitem>
312
320
<para>
313
-
Value: 7; Failed to write file to disk. Introduced in PHP 5.1.0.
321
+
Value: 7; Failed to write file to disk.
314
322
</para>
315
323
</listitem>
316
324
</varlistentry>
...
...
@@ -321,7 +329,6 @@ foreach ($_FILES["pictures"]["error"] as $key => $error) {
321
329
Value: 8; A PHP extension stopped the file upload. PHP does not
322
330
provide a way to ascertain which extension caused the file upload to
323
331
stop; examining the list of loaded extensions with <function>phpinfo</function> may help.
324
-
Introduced in PHP 5.2.0.
325
332
</para>
326
333
</listitem>
327
334
</varlistentry>
...
...
@@ -364,7 +371,7 @@ foreach ($_FILES["pictures"]["error"] as $key => $error) {
364
371
<link linkend="ini.max-input-time">max_input_time</link> sets the maximum
365
372
time, in seconds, the script is allowed to receive input; this includes
366
373
file uploads. For large or multiple files, or users on slower connections,
367
-
the default of <literal>60 seconds</literal> may be exceeded.
374
+
the default of <literal>60</literal> seconds may be exceeded.
368
375
</simpara>
369
376
</warning>
370
377
<simpara>
...
...
@@ -373,7 +380,7 @@ foreach ($_FILES["pictures"]["error"] as $key => $error) {
373
380
<literal>post_max_size</literal> large enough.
374
381
</simpara>
375
382
<simpara>
376
-
Since PHP 5.2.12, the
383
+
The
377
384
<link linkend="ini.max-file-uploads">max_file_uploads</link> configuration
378
385
setting controls the maximum number of files that can uploaded in one
379
386
request. If more files are uploaded than the limit, then
...
...
@@ -388,12 +395,6 @@ foreach ($_FILES["pictures"]["error"] as $key => $error) {
388
395
sensitive information in other directories.
389
396
</simpara>
390
397
<simpara>
391
-
Please note that the <productname>CERN httpd</productname> seems to strip off everything
392
-
starting at the first whitespace in the content-type mime header
393
-
it gets from the client. As long as this is the case, <productname>CERN httpd</productname>
394
-
will not support the file upload feature.
395
-
</simpara>
396
-
<simpara>
397
398
Due to the large amount of directory listing styles we cannot guarantee
398
399
that files with exotic names (like containing spaces) are handled properly.
399
400
</simpara>
...
...
@@ -435,12 +436,7 @@ foreach ($_FILES["pictures"]["error"] as $key => $error) {
435
436
<varname>$_FILES['userfile']</varname>,
436
437
<varname>$_FILES['userfile']['name']</varname>, and
437
438
<varname>$_FILES['userfile']['size']</varname> will be
438
-
initialized (as well as in <varname>$HTTP_POST_FILES</varname> for PHP versions prior
439
-
to 4.1.0).
440
-
When
441
-
<link linkend="ini.register-globals">register_globals</link> is on, globals for uploaded
442
-
files are also initialized. Each of these will be a numerically
443
-
indexed array of the appropriate values for the submitted files.
439
+
initialized.
444
440
</simpara>
445
441
<simpara>
446
442
For instance, assume that the filenames
...
...
@@ -462,13 +458,49 @@ foreach ($_FILES["pictures"]["error"] as $key => $error) {
462
458
</simpara>
463
459
<warning>
464
460
<simpara>
465
-
Since PHP 5.2.12, the
461
+
The
466
462
<link linkend="ini.max-file-uploads">max_file_uploads</link>
467
463
configuration setting acts as a limit on the number of files that can be
468
464
uploaded in one request. You will need to ensure that your form does not
469
465
try to upload more files in one request than this limit.
470
466
</simpara>
471
467
</warning>
468
+
<para>
469
+
<example>
470
+
<title>Uploading an entire directory</title>
471
+
<simpara>
472
+
In HTML file upload fields, it is possible to upload an entire directory with the <literal>webkitdirectory</literal> attribute.
473
+
This feature is supported in most modern browsers.
474
+
</simpara>
475
+
<simpara>
476
+
With the <literal>full_path</literal> information, it is possible to store the relative paths,
477
+
or reconstruct the same directory in the server.
478
+
</simpara>
479
+
<programlisting role="html">
480
+
<![CDATA[
481
+
<form action="file-upload.php" method="post" enctype="multipart/form-data">
482
+
Send this directory:<br />
483
+
<input name="userfile[]" type="file" webkitdirectory multiple />
484
+
<input type="submit" value="Send files" />
485
+
</form>
486
+
]]>
487
+
</programlisting>
488
+
</example>
489
+

490
+
<warning>
491
+
<simpara>
492
+
The <literal>webkitdirectory</literal> attribute is non-standard and is not on a standards track.
493
+
Do not use it on production sites facing the Web: it will not work for every user.
494
+
There may also be large incompatibilities between implementations and the behavior may change in the future.
495
+
</simpara>
496
+
<simpara>
497
+
PHP only parses the relative path information submitted by the browser/user-agent,
498
+
and passes that information to the <varname>$_FILES</varname> array.
499
+
There is no guarantee that the values in the <literal>full_path</literal> array contains a real directory structure,
500
+
and the PHP application must not trust this information.
501
+
</simpara>
502
+
</warning>
503
+
</para>
472
504
</sect1>
473
505

474
506
<sect1 xml:id="features.file-upload.put-method">
...
...
@@ -547,6 +579,15 @@ fclose($putdata);
547
579
</para>
548
580
</sect1>
549
581

582
+
<sect1 xml:id="features.file-upload.errors.seealso">
583
+
&reftitle.seealso;
584
+
<para>
585
+
<simplelist>
586
+
<member><link linkend="security.filesystem">Filesystem Security</link></member>
587
+
</simplelist>
588
+
</para>
589
+
</sect1>
590
+

550
591
</chapter>
551
592

552
593
<!-- Keep this comment at the end of the file
553
594