Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Форма для загрузки файла по ссылке (https://javascript.ru/forum/misc/72601-forma-dlya-zagruzki-fajjla-po-ssylke.html)

laimas 15.02.2018 20:47

Цитата:

Сообщение от kupidon
Вообще проверку убрать?

isset($_POST) - это просто глупо, ибо всегда будет true, даже если этот массив пуст. А вот если ссылки на сетевые файлы передаются под именем file, то isset($_POST['file']) определит есть ли такое, но не определяется пусты ли они.

Вы же добавленному товару добавляете фото, а значит обязательным должна быть проверка наличия поля с ID товара, и не просто наличие, а возвращает число и запрос по этому id в базу возвращает истину, то есть:

if($id = (int)$_POST['id'] AND query('SELECT 1 FROM table WHERE id='.$id)) {
     //это товар - загрузка
}


При отключенных нотайсах достаточно, и isset(...) не обязателен. А с $_SERVER["REQUEST_METHOD"] == "POST", то при запросе к скрипту выполняющему исключительно задачу загрузки, лучше в самом его начале прописать:

if($_SERVER["REQUEST_METHOD"] == "GET") exit;


О $_FILES['file']['name'] забыть, оно вам не нужно, это товары а не галерея в Instagram.

laimas 15.02.2018 20:56

Цитата:

Сообщение от kupidon
$file_name = basename('https://www.google.ru/images/srpr/logo11w.png');

Какие basename, зачем? Именуйте файлы генерируя их имена как хеш UID.
Цитата:

Сообщение от kupidon
И как из этого примера потом получить ссылку на временный файл?

Нет тут никакого временного файла - файл загрузить в переменную сначала надо и это будет в памяти. Затем проверить по всем условиям этот файл - картинка ли и т.д. Затем отдать в функцию на обработку (если это есть, читайте выше), эта функция его и сохранит. Никаких file_put_contents.

kupidon 16.02.2018 12:09

Цитата:

Сообщение от laimas
файл загрузить в переменную сначала надо и это будет в памяти.

:cray: Я не знаю как его загрузить

kupidon 16.02.2018 12:24

Нашел вот такой код:
<?php
  $link = "http://myrusakov.ru/images/site.jpg";
  $file = file_get_contents($link);
  file_put_contents("site.jpg", $file);
?>


ссылку на внешний файл я смогу получить в обработчике. смогу ли я таким способом закачать файл в свою временную папку?

laimas 16.02.2018 13:38

Цитата:

Сообщение от 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) и примерно посчитать память требуемую (полученную умножать на два, при операциях могут создаваться два ресурса), хватит ли ее.

laimas 16.02.2018 13:39

Цитата:

Сообщение от kupidon
Нашел вот такой код

Не собирайте мусора, думайте. ;)

laimas 16.02.2018 13:42

Цитата:

Сообщение от kupidon
смогу ли я таким способом закачать файл в свою временную папку?

Либо забудьте об этом термине в контексте сетевых файлов, либо читайте то, что по ссылке.

Для того чтобы загрузить обработать сетевой файл никакой временной папки в общем то и не нужно, как не обязательно файлы загруженных формой перемещать из временного каталога в какой либо, только для того, чтобы их обработать.

kupidon 16.02.2018 14:58

Спасибо большое за столь огромный ответ. Сегодня буду его переваривать. Обязательно отпишусь о результате, надеюсь он все-таки будет.

kupidon 16.02.2018 15:06

Цитата:

Сообщение от laimas
Сообщение от kupidon
смогу ли я таким способом закачать файл в свою временную папку?

Либо забудьте об этом термине в контексте сетевых файлов, либо читайте то, что по ссылке.

Хочу добавит к вышенаписанному. Вы почти в каждом сообщении мне делаете акцент на проверку ид товара. Я же хочу обратить внимание, что я сделал загрузку и вывод из локальных файлов. Все отлично работает. Я для этого использовал и ид товара и проверку преобразование размера и генерирование уникального имени. То есть это у меня уже есть. Также я загружаю фото из карточки УЖЕ созданного товара, а следовательно не надо проверять есть он в БД или нет. Он есть 100%. Размер и формат - согласен.
Что касается временной папки, то она мне нужна в любом случае. В нее я загружаю временный файл, а уже оттуда манипулирую обработкой изображения, потом сам удаляю оттуда его.
Я понимаю что уровень ваших знаний вразы больше моего и у вас есть куча оптимальных вариантов и ответов на мой вопрос, но на данном этапе мне хочется проще. Я сам порою открывая свои творения 2-х годичной давности посмеиваюсь. Понимаю что и вам такого, но увы , учимся на ошибках ))

laimas 16.02.2018 15:16

Цитата:

Сообщение от kupidon
Также я загружаю фото из карточки УЖЕ созданного товара, а следовательно не надо проверять есть он в БД или нет.

Это как? :)
Цитата:

Сообщение от kupidon
Что касается временной папки, то она мне нужна в любом случае. В нее я загружаю временный файл, а уже оттуда манипулирую обработкой изображения, потом сам удаляю оттуда его.

Зачем? У вас лично ее вообще не должно быть, временная папка определяется настройками сервера и забота очищать ее от мусора возложена на сборщика мусора. Именно в эту временную папку, а не вашу, загружаются файлы от формы. Ваша задача их обработать, удаляться они из папки и без вашего участия.

А вот куда-то закачивать сетевые файлы, потом их брать от туда для обработки, это вообще глупо, ибо file_get_contents уже вам возвращает файл - обработайте его и уже результат обработки помещайте на хранение.

Что касается id и прочего, это для последовательности указано, есть и хорошо.

Цитата:

Сообщение от kupidon
но на данном этапе мне хочется проще.

А что я такого сложно написал? Главное в написанном, это не грузить на сервер мусор, чего вы своей простотой и делаете, и это очень плохо.


Часовой пояс GMT +3, время: 04:35.