getimagesize () в потоке вместо строки - PullRequest
4 голосов
/ 21 ноября 2011

Я использую Загрузчик файлов Valum для загрузки изображений с помощью AJAX.Этот скрипт передает файл на мой сервер способом, который я не до конца понимаю, поэтому, вероятно, лучше всего объяснить, показывая мой код на стороне сервера:

$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);

Ответы [ 2 ]

6 голосов
/ 12 сентября 2012

PHP 5.4 теперь поддерживает getimagesizefromstring

См. Документы: http://php.net/manual/pt_BR/function.getimagesizefromstring.php

Вы можете попробовать:

$input = fopen('php://input', 'r');
$string = stream_get_contents($input);
fclose($input);

getimagesizefromstring($string);
2 голосов
/ 21 ноября 2011

Вместо использования 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);
...