yohgaki Mon Jan 28 02:59:19 2002 EDT Modified files: /phpdoc/en/features file-upload.xml Log: Promote track vars instead of globals. Added more pitfalls.
Index: phpdoc/en/features/file-upload.xml diff -u phpdoc/en/features/file-upload.xml:1.28 phpdoc/en/features/file-upload.xml:1.29 --- phpdoc/en/features/file-upload.xml:1.28 Wed Dec 12 15:46:34 2001 +++ phpdoc/en/features/file-upload.xml Mon Jan 28 02:59:19 2002 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="iso-8859-1"?> -<!-- $Revision: 1.28 $ --> +<!-- $Revision: 1.29 $ --> <chapter id="features.file-upload"> <title>Handling file uploads</title> @@ -50,62 +50,35 @@ </para> <para> - In PHP, 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 in PHP 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> - <varname>$userfile</varname> - The temporary filename in which - the uploaded file was stored on the server machine. - </simpara> - </listitem> - <listitem> - <simpara> - <varname>$userfile_name</varname> - The original name or path - of the file on the sender's system. - </simpara> - </listitem> - <listitem> - <simpara> - <varname>$userfile_size</varname> - The size of the uploaded - file in bytes. - </simpara> - </listitem> - <listitem> - <simpara> - <varname>$userfile_type</varname> - The mime type of the file - if the browser provided this information. An example would be - "image/gif". - </simpara> - </listitem> - </itemizedlist> - Note that the "$userfile" 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 - "userfile" + Variables defined for uploaded files differs depends on PHP + version and configuration. Following variables will be defined + within the destination script upon a successful upload. When <link + linkend="ini.track-vars">track_vars</link> is enabled, + $HTTP_POST_FILES/ $_FILES array is initialized. <link + linkend="ini.track-vars">track_vars</link> is always on from PHP + 4.0.3. Finally, related variables may be initialized as globals + when <link linkend="ini.register-globals">register_globals</link> + is turned on . However, use of globals is not recommended anymore. </para> - + <note> + <para> + <link linkend="ini.track-vars">track_vars</link> is always on + from PHP 4.0.3. From PHP 4.1.0 or later, $_FILES may be used + instead of + <varname>$HTTP_POST_FILES</varname>. <varname>$_FILES</varname> is + always global, so <literal>global</literal> is should not be used + for $_FILES in function scope. + </para> + </note> <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. + <varname>$HTTP_POST_FILES</varname>/<varname>$_FILES</varname> is + provided to contain the uploaded file information. </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: + 'userfile', as used in the example script above: <variablelist> <varlistentry> <term><varname>$HTTP_POST_FILES['userfile']['name']</varname></term> @@ -144,6 +117,50 @@ </varlistentry> </variablelist> </para> + <note> + <para> + PHP3 does not support $HTTP_POST_FILES. + </para> + </note> + + <para> + When <link linkend="ini.register-globals">register_globals</link> + is turned on in <filename>php.ini</filename>. Note that the + following variable names assume the use of the file upload name + 'userfile', as used in the example script above: + + <itemizedlist> + <listitem> + <simpara> + <varname>$userfile</varname> - The temporary filename in which + the uploaded file was stored on the server machine. + </simpara> + </listitem> + <listitem> + <simpara> + <varname>$userfile_name</varname> - The original name or path + of the file on the sender's system. + </simpara> + </listitem> + <listitem> + <simpara> + <varname>$userfile_size</varname> - The size of the uploaded + file in bytes. + </simpara> + </listitem> + <listitem> + <simpara> + <varname>$userfile_type</varname> - The mime type of the file + if the browser provided this information. An example would be + "image/gif". + </simpara> + </listitem> + </itemizedlist> + Note that the "$userfile" 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 + "userfile" + </para> <para> Files will by default be stored in the server's default temporary @@ -167,13 +184,14 @@ <programlisting role="php"> <![CDATA[ <?php -if (is_uploaded_file($userfile)) { - copy($userfile, "/place/to/put/uploaded/file"); +// PHP 4.1.0 or later, $_FILES may be usedd instead of $HTTP_POST_FILES +if (is_uploaded_file($HTTP_POST_FILES['userfile'])) { + copy($HTTP_POST_FILES['userfile'], "/place/to/put/uploaded/file"); } else { - echo "Possible file upload attack: filename '$userfile'."; + echo "Possible file upload attack: filename '".$HTTP_POST_FILES['userfile'"."."; } /* ...or... */ -move_uploaded_file($userfile, "/place/to/put/uploaded/file"); +move_uploaded_file($HTTP_POST_FILES['userfile'], "/place/to/put/uploaded/file"); ?> ]]> </programlisting> @@ -191,20 +209,21 @@ <programlisting role="php"> <![CDATA[ <?php +// PHP 4.1.0 or later, $_FILES may be usedd instead of $HTTP_POST_FILES /* Userland test for uploaded file. */ -function is_uploaded_file($filename) { +function is_uploaded_file($HTTP_POST_FILES['filename']) { if (!$tmp_file = get_cfg_var('upload_tmp_dir')) { $tmp_file = dirname(tempnam('', '')); } - $tmp_file .= '/' . basename($filename); + $tmp_file .= '/' . basename($HTTP_POST_FILES['filename']); /* User might have trailing slash in php.ini... */ - return (ereg_replace('/+', '/', $tmp_file) == $filename); + return (ereg_replace('/+', '/', $tmp_file) == $HTTP_POST_FILES['filename']); } -if (is_uploaded_file($userfile)) { - copy($userfile, "/place/to/put/uploaded/file"); +if (is_uploaded_file($HTTP_POST_FILES['userfile'])) { + copy($HTTP_POST_FILES['userfile'], "/place/to/put/uploaded/file"); } else { - echo "Possible file upload attack: filename '$userfile'."; + echo "Possible file upload attack: filename '".$HTTP_POST_FILES['userfile']"."."; } ?> ]]> @@ -215,12 +234,12 @@ 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 - <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. + <varname>$HTTP_POST_FILES['file_size']</varname> variable to throw + away any files that are either too small or too big. You could + use the <varname>$HTTP_POST_FILES['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 @@ -235,6 +254,18 @@ greater than the file size that has been set in the <link linkend="ini.upload-max-filesize">upload_max_filesize</link> ini-setting. The default is 2 Megabytes. + </simpara> + <simpara> + If memory limit is enabled, larger <link + linkend="ini.memory-limit">memory_limit</link> may be needed. Make + sure to set <link linkend="ini.memory-limit">memory_limit</link> + large enough. + </simpara> +<!-- FIXME: max_execution_time INI --> + <simpara> + If <literal>max_execution_time</literal> is set too small, script + execution may be exceeded the value. Make sure to set + <literal>max_execution_time</literal> large enough. </simpara> <simpara> Not validating which file you operate on may mean that users can access