Documented move_uploaded_file() and is_uploaded_file().

Clarified some things about $HTTP_POST_FILES, PHP 3/PHP 4, and
how to test for uploaded file safety.
Minor cleanups, too.


git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@32400 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
Torben Wilson 2000-09-10 11:14:16 +00:00
parent d9025f3faf
commit 5cdf44621d
3 changed files with 247 additions and 42 deletions

View file

@ -33,33 +33,44 @@ Send this file: <INPUT NAME="userfile" TYPE="file">
</programlisting>
</example>
The _URL_ should point to a PHP file. The MAX_FILE_SIZE hidden
field must precede the file input field and its value is the maximum
filesize accepted. The value is in bytes. In this destination file,
the following variables will be defined upon a successful upload:
field must precede the file input field and its value is the
maximum filesize accepted. The value is in bytes.
</para>
<para>
In PHP 3, the following variables will be defined within the
destination script upon a successful upload, assuming that <link
linkend="ini.register-globals">register_globals</link> is turned
on in <filename>php.ini</filename>. If <link
linkend="ini.track-vars">track_vars</link> is turned on, they will
also be available within the global array
<varname>$HTTP_POST_VARS</varname>. Note that the following
variable names assume the use of the file upload name 'userfile',
as used in the example above:
<itemizedlist>
<listitem>
<simpara>
$userfile - The temporary filename in which the uploaded file
was stored on the server machine.
<varname>$userfile</varname> - The temporary filename in which
the uploaded file was stored on the server machine.
</simpara>
</listitem>
<listitem>
<simpara>
$userfile_name - The original name or path of the file on the
sender's system.
<varname>$userfile_name</varname> - The original name or path
of the file on the sender's system.
</simpara>
</listitem>
<listitem>
<simpara>
$userfile_size - The size of the uploaded file in bytes.
<varname>$userfile_size</varname> - The size of the uploaded
file in bytes.
</simpara>
</listitem>
<listitem>
<simpara>
$userfile_type - The mime type of the file if the browser
provided this information. An example would be
<varname>$userfile_type</varname> - The mime type of the file
if the browser provided this information. An example would be
&quot;image/gif&quot;.
</simpara>
</listitem>
@ -67,32 +78,119 @@ Send this file: &lt;INPUT NAME=&quot;userfile&quot; TYPE=&quot;file&quot;&gt;
Note that the &quot;$userfile&quot; part of the above variables is
whatever the name of the INPUT field of TYPE=file is in the upload
form. In the above upload form example, we chose to call it
&quot;userfile&quot;.
&quot;userfile&quot;
</para>
<para>
In PHP 4, the behaviour is slightly different, in that the new
global array <varname>$HTTP_POST_FILES</varname> is provided to
contain the uploaded file information. This is still only
available if <link linkend="ini.track-vars">track_vars</link> is
turned on, but <link linkend="ini.track-vars">track_vars</link> is
always turned on in versions of PHP after PHP 4.0.2.
</para>
<para>
The contents of <varname>$HTTP_POST_FILES</varname> are as
follows. Note that this assumes the use of the file upload name
'userfile', as used in the example above:
<variablelist>
<varlistentry>
<term><varname>$HTTP_POST_FILES['userfile']['name']</varname></term>
<listitem>
<para>
The original name of the file on the client machine.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>$HTTP_POST_FILES['userfile']['type']</varname></term>
<listitem>
<para>
The mime type of the file, if the browser provided this
information. An example would be
<literal>&quot;image/gif&quot;</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>$HTTP_POST_FILES['userfile']['size']</varname></term>
<listitem>
<para>
The size, in bytes, of the uploaded file.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>$HTTP_POST_FILES['userfile']['tmp_name']</varname></term>
<listitem>
<para>
The temporary filename of the file in which the uploaded file
was stored on the server.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Files will by default be stored in the server's default temporary
directory. This can be changed by setting the environment variable
<envar>TMPDIR</envar> in the environment in which PHP runs. Setting
it using <function>putenv</function> from within a PHP script will
not work. This environment variable can also be used to make sure
that other operations are working on uploaded files, as well.
directory, unless another location has been given with the <link
linkend="ini.upload-tmp-dir">upload_tmp_dir</link> directive in
<filename>php.ini</filename>. The server's default directory can
be changed by setting the environment variable
<envar>TMPDIR</envar> in the environment in which PHP runs.
Setting it using <function>putenv</function> from within a PHP
script will not work. This environment variable can also be used
to make sure that other operations are working on uploaded files,
as well.
<example>
<title>Validating file uploads.</title>
<programlisting>
&lt?
// Make sure file is coming from upload directory
$uploadpath = get_cfg_var('upload_tmp_dir') . '/' . basename($userfile);
<title>Validating file uploads</title>
<para>
The following examples are for versions of PHP 3 greater than
3.0.16, and versions of PHP 4 greater than 4.0.2. See the
function entries for <function>is_uploaded_file</function> and
<function>move_uploaded_file</function>.
</para>
<programlisting role="php">
&lt?php
if (is_uploaded_file($userfile)) {
copy($userfile, "/place/to/put/uploaded/file");
} else {
echo "Possible file upload attack: filename '$userfile'.";
}
/* ...or... */
move_uploaded_file($userfile, "/place/to/put/uploaded/file");
?>
</programlisting>
<para>
For earlier versions of PHP, you'll need to do something like
the following.
<note>
<para>
This will <emphasis>not</emphasis> work in versions of PHP 4
after 4.0.2. It depends on internal functionality of PHP which
changed after that version.
</para>
</note>
</para>
<programlisting role="php">
&lt?php
/* Userland test for uploaded file. */
function is_uploaded_file($filename) {
if (!$tmp_file = get_cfg_var('upload_tmp_dir')) {
$tmp_file = dirname(tempnam('', ''));
}
$tmp_file .= '/' . basename($filename);
/* User might have trailing slash in php.ini... */
return (ereg_replace('/+', '/', $tmp_file) == $filename);
}
// If you have not set your TMPDIR in pnp.ini, the following line
// can be uncommented, and used instead of the above line
// $uploadpath = dirname(tempnam('', '')) . '/' . basename($userfile);
if (file_exists($uploadpath)){
copy ("$uploadpath", "/place/to/put/uploaded/file");
} else {
echo "Not an uploaded file!";
exit;
}
if (is_uploaded_file($userfile)) {
copy($userfile, "/place/to/put/uploaded/file");
} else {
echo "Possible file upload attack: filename '$userfile'.";
}
?>
</programlisting>
</example>
@ -100,12 +198,13 @@ if (file_exists($uploadpath)){
<simpara>
The PHP script which receives the uploaded file should implement
whatever logic is necessary for determining what should be done
with the uploaded file. You can for example use the $file_size
variable to throw away any files that are either too small or too
big. You could use the $file_type variable to throw away any
files that didn't match a certain type criteria. Whatever the
logic, you should either delete the file from the temporary
directory or move it elsewhere.
with the uploaded file. You can for example use the
<varname>$file_size</varname> variable to throw away any files
that are either too small or too big. You could use the
<varname>$file_type</varname> variable to throw away any files
that didn't match a certain type criteria. Whatever the logic,
you should either delete the file from the temporary directory or
move it elsewhere.
</simpara>
<simpara>
The file will be deleted from the temporary directory at the end

View file

@ -438,7 +438,7 @@ $df = diskfreespace("/"); // $df contains the number of bytes
<function>fgetcsv</function> parses the line it reads for fields
in <acronym>CSV</acronym> format and returns an array containing
the fields read. The field delimiter is a comma, unless you
specifiy another delimiter with the optional third parameter.
specify another delimiter with the optional third parameter.
</simpara>
<simpara>
<parameter>Fp</parameter> must be a valid file pointer to a file
@ -454,9 +454,9 @@ $df = diskfreespace("/"); // $df contains the number of bytes
end of file.
</simpara>
<simpara>
NB A blank line in a CSV file will be returned as an array
comprising just one single null field, and will not be treated as
an error.
N.B. A blank line in a CSV file will be returned as an array
comprising a single null field, and will not be treated as an
error.
</simpara>
<example>
<title>
@ -1751,6 +1751,48 @@ if($fp){
</refsect1>
</refentry>
<refentry id="function.is-uploaded-file">
<refnamediv>
<refname>is_uploaded_file</refname>
<refpurpose>Tells whether the file was uploaded via HTTP POST.</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<funcsynopsis>
<funcprototype>
<funcdef>bool <function>is_uploaded_file</function></funcdef>
<paramdef>string <parameter>filename</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This function is available only in versions of PHP 3 after PHP
3.0.16, and in versions of PHP 4 after 4.0.2.
</para>
<para>
Returns true if the file named by <varname>filename</varname> was
uploaded via HTTP POST. This is useful to help ensure that a
malicious user hasn't tried to trick the script into working on
files upon which it should not be working--for instance,
<filename>/etc/passwd</filename>.
</para>
<para>
This sort of check is especially important if there is any chance
that anything done with uploaded files could reveal their
contents to the user, or even to other users on the same
system.
</para>
<para>
See also <function>move_uploaded_file</function>, and the section
<link linkend="features.file-upload">Handling file uploads</link>
for a simple usage example.
</para>
</refsect1>
</refentry>
<refentry id="function.link">
<refnamediv>
<refname>link</refname>
@ -1848,6 +1890,63 @@ mkdir ("/path/to/my/dir", 0700);
</refsect1>
</refentry>
<refentry id="function.move-uploaded-file">
<refnamediv>
<refname>move_uploaded_file</refname>
<refpurpose>Moves an uploaded file to a new location.</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<funcsynopsis>
<funcprototype>
<funcdef>bool <function>move_uploaded_file</function></funcdef>
<paramdef>string <parameter>filename</parameter></paramdef>
<paramdef>string <parameter>destination</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
This function is available only in versions of PHP 3 after PHP
3.0.16, and in versions of PHP 4 after 4.0.2.
</para>
<para>
This function checks to ensure that the file designated by
<parameter>filename</parameter> is a valid upload file (meaning
that it was uploaded via PHP's HTTP POST upload mechanism). If
the file is valid, it will be moved to the filename given by
<parameter>destination</parameter>.
</para>
<para>
If <parameter>filename</parameter> is not a valid upload file,
then no action will occur, and
<function>move_uploaded_file</function> will return
<literal>false</literal>.
</para>
<para>
If <parameter>filename</parameter> is a valid upload file, but
cannot be moved for some reason, no action will occur, and
<function>move_uploaded_file</function> will return
<literal>false</literal>. Additionally, a warning will be issued.
</para>
<para>
This sort of check is especially important if there is any chance
that anything done with uploaded files could reveal their
contents to the user, or even to other users on the same
system.
</para>
<para>
See also <function>is_uploaded_file</function>, and the section
<link linkend="features.file-upload">Handling file uploads</link>
for a simple usage example.
</para>
</refsect1>
</refentry>
<refentry id="function.pclose">
<refnamediv>
<refname>pclose</refname>

View file

@ -528,8 +528,15 @@ $bar = &amp;test(); // Invalid.
<listitem>
<simpara>
An associative array of variables containing information
about files uploaded via the HTTP POST method.
about files uploaded via the HTTP POST method. See <link
linkend="features.file-upload.post-method">POST method
uploads</link> for information on the contents of
<varname>$HTTP_POST_FILES</varname>.
</simpara>
<para>
<varname>$HTTP_POST_FILES</varname> is available only in PHP
4.0.0 and later.
</para>
</listitem>
</varlistentry>