PHP文件上传,使用FILES超全局数组

时间:2010-05-07 01:31:44

标签: php file upload

假设我正在为项目设置上传功能。 我正在使用PHP5,我想知道如果使用$ _FILES超全局数组,我可以访问“tmp_name”数组键,这是要上载的文件的临时路径和名称,以显示图像的预览,然后将其移至服务器中的“uploads”文件夹。

我的想法是这样的: 使用jQuery检测“文件”输入字段何时更改(当用户选择图像文件时),然后发出ajax调用以上传文件,即使在使用“move_uploaded_file”之前,也会将其移动到临时文件夹。 如果我可以以某种方式访问​​“tmp_name”数组键,我可能会将其放入“img”标签以显示预览。 稍后在单击提交按钮时将文件移动到其最终位置。

我不是要求任何代码示例或任何东西,因为我很高兴能够自己完成这项工作,我只是想知道是否可以以任何方式访问该数组密钥。

2 个答案:

答案 0 :(得分:2)

是的,你可以。

  

在PHP中,当用户提交带有$ _FILES超全局的表单时,会填充有关上载文件的有用信息。在里面你会发现每个上传文件的原始名称,内容类型,服务器上的临时上传位置,错误代码以及字节大小。

取自Fixing the $_FILES superglobal

以下是从print_r数组的网站获取的示例$_FILES输出,

Array
 (
    [download_zip] => Array
     (
        [name] => dummy.txt
        [type] => text/plain
        [tmp_name] => /Applications/MAMP/tmp/php/php5TBPsw
        [error] => 0
        [size] => 1
     )

    [download_screenshot] => Array
     (
        [name] => dummy.txt
        [type] => text/plain
        [tmp_name] => /Applications/MAMP/tmp/php/phpTncd39
        [error] => 0
        [size] => 1
     ) 
)

您可以使用tmp_name语法访问$files_array['download_zip']['tmp_name']

更新

$path = $files_array['download_zip']['tmp_name'];
echo "<img src='$path'>"; 

答案 1 :(得分:2)

要在图像标记中使用它们,您需要将相关的临时文件存储在Web根目录中的某个位置,因为它们通常位于文件系统中的其他位置,位于Web根目录之外,并且您不希望输出用户的路径,因为它将无用(img标签无法映射到该路径),以及安全性差(您正在提供有关文件系统的信息)。

您可以通过 a)将每个文件复制到webroot中的某个位置(代价高昂),或 b)更改您的配置以将所有上传的文件放入Web根目录中的临时文件夹(具有很大的安全隐患)。

在计划中时要牢记安全......

请注意其他临时文件的安全性。确保只有与此应用程序的此部分相关的内容存储在Web根目录中。您不希望发现您已经提供了足够的信息来允许某人计算对其他文件的访问权限,并且因为其他上传的数据在您的网络中可用(即使很短的时间)根

这可能是更好的方式:

也许更好的解决方案是获取临时名称,以某种方式对其进行模糊处理,将其添加到将其传递给网守文件的路径中,然后发送它。

这样的东西
/images/path/to/gatekeeper.png?name=[obfuscated file name here]

然后您可以使用/images/path/to/.htaccess来确保将网守视为php文件而不是png文件,方法是添加:

<Files gatekeeper.png>
    ForceType application/x-httpd-php
</Files>

现在,网守可以取消模糊文件名,将其从临时路径中拉出来并发送,而不向用户透露任何内容,移动实际文件或更改配置。

请确保您不希望文件持续存在,因为如果它们稍后刷新,并且文件已移动(几乎肯定会有),那么它只会是一个损坏的图像。如果没有找到,可能会检查网守是否存在并给他们一个“文件不再可用”图像。您还可以强制仅在网守级别发送图像文件或其他安全问题。

您可以这样做(从内存中输入,可能无法运行,并且没有处理错误,缺少值等,但您应该能够将此作为起点......):

<?php
// This is all inside gatekeeper.png, which is just a .php file with a .png extension
// It's not very good code, just an example to point you in the right direction.

// Specify this will be a png file for the browser...
header("content-type: image/png");


//Read the file name from the $_GET and un-obfuscate it.
$file = "/path/to/temp/directory/outside/file/root/that/we/hopefully/have/access/to/";
$file .= $_GET["name"];


// Check that the file exists, and send a "not found" image if not.
// http://us.php.net/manual/en/function.file-exists.php
if (!file_exists($file)) {etc...}


// Read the image file, send it to the user, and close it...
// http://us.php.net/manual/en/function.imagepng.php
$im = imagecreatefrompng($file);
imagepng($im);
imagedestroy($im);


die();

?>