2011-11-21 72 views
4

我使用Valum's file uploader上传图像与AJAX。这个脚本提交文件到我的方式,我不完全了解服务器,因此它可能是最好的通过展示我的服务器端代码来说明一下:我想执行一些文件getimagesize()在流而不是字符串

$pathToFile = $path . $filename; 

//Here I get a file not found error, because the file is not yet at this address 
getimagesize($pathToFile); 

$input = fopen('php://input', 'r'); 
$temp = tmpfile(); 
$realSize = stream_copy_to_stream($input, $temp); 

//Here I get a string expected, resource given error 
getimagesize($input); 

fclose($input); 

$target = fopen($pathToFile, 'w'); 
fseek($temp, 0, SEEK_SET); 

//Here I get a file not found error, because the image is not at the $target yet 
getimagesize($pathToFile); 

stream_copy_to_stream($temp, $target); 
fclose($target); 

//Here it works, because the image is at the desired location so I'm able to access it with $pathToFile. However, the (potentially) malicious file is already in my server. 
getimagesize($pathToFile); 

的问题是在这里验证,使用getimagesize()。 getimagesize只支持一个字符串,而我只有资源可用,导致出错:getimagesize需要一个字符串,给定的资源。

当我在脚本的末尾执行getimagesize($ pathTofile)时,它确实有效,但是图像已经上传,损坏可能已经完成。这样做,然后执行检查,然后删除te文件似乎对我来说是不好的做法。

$ _REQUEST中唯一的事情就是文件名,我使用var $ pathToFile。 $ _FILES是空的。

如何在流上执行文件验证?

编辑: 的解决方案是首位在一个临时目录中的文件,并将其复制到目标目录之前执行对临时文件进行验证。

// Store the file in tmp dir, to validate it before storing it in destination dir 
$input = fopen('php://input', 'r'); 
$tmpPath = tempnam(sys_get_temp_dir(), 'upl'); // upl is 3-letter prefix for upload 
$tmpStream = fopen($tmpPath, 'w'); // For writing it to tmp dir 
stream_copy_to_stream($input, $tmpStream); 
fclose($input); 
fclose($tmpStream); 

// Store the file in destination dir, after validation 
$pathToFile = $path . $filename; 
$destination = fopen($pathToFile, 'w'); 
$tmpStream = fopen($tmpPath, 'r'); // For reading it from tmp dir 
stream_copy_to_stream($tmpStream, $destination); 
fclose($destination); 
fclose($tmpStream); 
+0

请添加和getimagesize代码,以及你的问题,否则很难回答。从你的问题看来,它看起来像你有一个字符串以及文件,你可以使用字符串,而不是资源ID。所以很高兴知道是什么阻止你这样做。 – hakre

+0

完成,我希望这可以稍微澄清一点。 – Thomas

回答

2

而不是使用tmpfile(),你可以利用tempnam()sys_get_temp_dir()创建一个临时路径。

然后使用fopen()来获取它的句柄,复制流。

然后你得到一个字符串和一个你需要做的操作的句柄。

//Copy PHP's input stream data into a temporary file 

$inputStream = fopen('php://input', 'r'); 
$tempDir  = sys_get_temp_dir(); 
$tempExtension = '.upload'; 

$tempFile = tempnam($tempDir, $tempExtension); 
$tempStream = fopen($tempFile, "w"); 
$realSize = stream_copy_to_stream($inputStream, $tempStream); 

fclose($tempStream); 

getimagesize($tempFile); 
+0

我认为这是正确的方向,但tempnam()返回一个字符串,而不是资源,所以我怎样才能使用stream_copy_to_stream()?我应该使用fwrite吗?对不起,我有点迷失在这里,我甚至不知道什么是流。 – Thomas

+0

在该字符串上使用'fopen()'。那么你也有资源。 – hakre

+0

我觉得我快到了,唯一的问题是现在目标目录中的文件有0个字节。你知道我做错了什么吗?我将当前的代码放在问题中。 – Thomas

相关问题