Сообщение от kupidon
|
Я не знаю как его загрузить
|
У вас не только с этим проблемы. Мне некогда, поэтому общие положения.
Форма содержит поле для ввода сетевого пути к файлу. Этих полей может быть много. Как клонировать и добавить поле в форму на форуме уже не раз писалось, найти. Пусть это поле имеет имя file[].
Также формой передается id товара, а при необходимости и его родителя.
Загрузка локальных файлов осуществляется полем тоже с именем file[].
Загрузку файлов можно начитать только если id товара действительно, а если и родитель, то и он. Это условие описано ранее. Далее могут быть два сценария:
1) последовательная загрузка: сначала локальные файлы если есть с полной обработкой, затем сетевые при их наличии с полной обработкой
2) комбинированная: создается массив ссылок на временные файлы, затем проходом в цикле они отдаются в полную обработку.
Сервер имеет функцию производящую основные операции с изображениями. Если функция возвращает 0, значит ошибок при обработке не возникало. В противном случае, это код ошибки.
$mime = ['image/png', 'image/jpeg']; //разрешенные типы
$size = 1000000; //макс. размер.
function processingIMG($f) {
if(!$im = @imagecreatefromstring($f)) return 1; //файл не является изображением
//далее операции
//сохранение
return 0;
}
В случае первого сценария проверяются файлы массива $_FILES на отсутствие ошибок при загрузке, загружен ли файл по HTTP, предварительно на тип, и на допустимый размер. Проверка на размер очень важна, о ней ниже. Если Эти условия соблюдены временный файл отдается processingIMG(file_get_contents($_FILES['file']['tmp_name'][$i])).
Затем обрабатываются файлы сетевые если они есть, и это тоже массив файлов.
if($url = array_diff(filter_var_array($_POST['file'], FILTER_VALIDATE_URL), [false])) {
foreach($url as $a) {
$hdr = get_headers($a, 1);
if(strpos($hdr[0], '200')) {
if(in_array($hdr['Content-Type'], $mime) && $hdr['Content-Length'] <= $size) $upl[] = $a;
}
}
foreach($upl as $url) {
if($f = @file_get_contents($url)) {
if(processingIMG($f)) echo 'Error';
}
}
}
Из полученного массива ссылок сетевых файлов будут удалены те, что имеют некорректный сетевой путь. Прежде чем реально загружать сетевые файлы, сначала получается информация о них, посредством запроса заголовков. После анализа заголовков из массива списка сетевых файлов будут удалены те, у которых заголовок не вернул статус 200, и у которых тип не является разрешенным и размер больше разрешенного. При этом надо учесть, что изображение может отдаваться не по прямой ссылке, а скриптом, но в заголовке будет не тип изображения, и он будет исключен из набора. Кроме этого url не обязательно прямой путь, возможны перенаправления, количество которых должно быть определено, если разрешено, и проанализировано (рассказывать не буду, запускайте get_headers на примерах, смотрите результаты, анализируйте, думайте, действуйте).
Полученный массив валидных ссылок обходится циклом, где производится загрузка файлов посредством file_get_contents($url) и загруженный файл отдается также на дальнейшую обработку в processingIMG().
Если так хочется получить список временных файлов, которые потом одним циклом обработать, то сетевые файлы нужно сначала загрузить, каждый в созданный временный файл, получая путь к нему. Пути заносить в массив, который соединить с массивом путей временных файлов загруженных по HTTP, и полученный массив обойти циклом.
Но есть некоторые проблемы связанные с tmpfile(), о которых можно
почитать тут, и заодно воспользоваться решением предложенным, если для вас это так принципиально.
О проверке на размер. Если файл будет обрабатываться графической библиотекой (GD и прочее), то нужно учитывать следующее. Если эта загрузка для себя и вы не враг себе, а также гарантируете, что ваш вход надежно защищен, то терпимо. Но если закинуть на сервер изображение 10000х10000, которое в формате JPEG может быть сжато и до смешного размера, то проверку на размер файла оно пройдет. Но для работы с этим файлов в GD под ресурс потребуется памяти 10000х10000Х32 = 3 200 000 000 байт (GD не будет спрашивать вас нужен ли вам альфа канал, он все равно под него отведет один байт). И у вас будут возникать фатальные ошибки.
Поэтому до открытия ресурса нужно узнать разрешение файла (getimagesize) и примерно посчитать память требуемую (полученную умножать на два, при операциях могут создаваться два ресурса), хватит ли ее.