2011-11-21 48 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

相關問題