Я использую Загрузчик файлов 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);