За последние 24 часа нас посетили 70366 программистов и 5688 роботов. Сейчас ищут 1226 программистов ...

Загрузка файлов, убрать имена из массива?

Тема в разделе "PHP для новичков", создана пользователем AlexPebody, 14 сен 2022.

Метки:
  1. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    Всем привет, пожскажите пожалуйста, давно неписал на PHP. Есть массив загружаемых файлов, нужно выявить запрещенные имена по расширению и убрать из массива до загрузки файлов:

    PHP:
    1. file_put_contents('stopfiles.log', ''); foreach ($_FILES['xtt']['name'] as $filesname) {file_put_contents('stopfiles.log', $filesname.', ', FILE_APPEND);}
    есть массив запрещенных расширений: $denyftype = array('htm', 'html', 'shtml', 'xml', 'txt', 'sh', 'bash', 'pl', 'py', 'pyt', 'css', 'js', 'asp', 'jsp', 'cgi', 'php', 'vbs', 'cmd', 'bat', 'exe', 'dll', 'vxd', 'reg', 'ajax', 'script', 'htaccess', 'htpasswd');

    PHP:
    1. elseif (in_array(substr($_FILES['xtt']['name'][$i], strrpos($_FILES['xtt']['name'][$i], '.') + 1), $denyftype)) {exit ($GLOBALS["html_a"].'<table style="border-collapse: collapse" border="1" bordercolor="#FF0000" width="80%" height="60"><tr><td><p align="center"><font color="#FF0000">По соображениям безопасности, вы не можете загрузить файл(ы) *.'.$stop.'<br>ВНИМАНИЕ! По причине, указанной выше, Ваша загрузка не прошла!<br>Исключите из загрузки запрещенный файл(ы) и попробуйте еще раз.</font></td></tr></table>'.$GLOBALS["back"].$GLOBALS["html_b2"]);
    2. ...далее прочие условия
    Так вот загрузка останавливается по exit, на файлы с запрещенным расширением не даются ссылки, но они все равно загружаются. Задача лишь одна, я далее допишу, как из массива $_FILES['xtt']['name'] убрать имена файлов запрещенных расширений, не могу получить имена файлов слева от точки?

    Спасибо!
     
  2. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    Конкретизирую:

    Есть массив загружаемых файлов: $_FILES['xtt']['name']
    Есть массив запрещенных расширений файлов: $denyftype = array('htm', 'html', 'shtml', 'xml', 'txt', 'sh', 'bash', 'pl', 'py', 'pyt', 'css', 'js', 'asp', 'jsp', 'cgi', 'php', 'vbs', 'cmd', 'bat', 'exe', 'dll', 'vxd', 'reg', 'ajax', 'script', 'htaccess', 'htpasswd');

    Как исключить имена (поиск в массиве имени по расширению) этих файлов из массива $_FILES['xtt']['name'], показать сообщение и вывести эти имена, которые были запрещены и не будут загружены, затем идет процедура загрузки...
     
  3. Drunkenmunky

    Drunkenmunky Старожил

    С нами с:
    12 авг 2020
    Сообщения:
    1.511
    Симпатии:
    284
    "Затем" не получится. $_FILES уже содержит загруженное, есть вариант это принять, или не принять
    Как-то так
    PHP:
    1. <?php
    2. $denyftype = array('htm', 'html', 'shtml', 'xml', 'txt', 'sh', 'bash','pl', 'py',
    3.                    'pyt', 'css', 'js', 'asp', 'jsp', 'cgi', 'php', 'vbs', 'cmd',
    4.                    'bat', 'exe', 'dll', 'vxd', 'reg', 'ajax', 'script', 'htaccess', 'htpasswd');
    5.  
    6. foreach ($_FILES['xtt']['error'] as $key => $error)
    7. {
    8.     if ($error == UPLOAD_ERR_OK)
    9.     {
    10.       $tmp_name = $_FILES['xtt']['tmp_name'][$key];
    11.       $path_parts = pathinfo($_FILES['xtt']['name'][$key]);
    12.  
    13.        if(!in_array($path_parts['extension'], $denyftype))
    14.         {
    15.             move_uploaded_file($tmp_name, 'data/'.$path_parts['basename']);
    16.             echo $path_parts['basename']. ' загружен';
    17.         }
    18.         else
    19.         {
    20.            echo $path_parts['basename'] . ' не загружен';
    21.         }
    22.     }
    23. }
    24. ?>
    --- Добавлено ---
    Кстати, должен заметить, что логичнее было бы заполнить массив разрешенными расширениями.
    Кроме того, в коде выше, $path_parts['basename'] желательно обрабатывать, на предмет очистки от непечатаемых символов, а то и просто очистки от всего, что не латынь.
     
    AlexPebody нравится это.
  4. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    @Drunkenmunky спасибо большое, буду ковырять, да проекту лет 10, сейчас полез, запарился немного, параллельные вопросы... Еще раз спасибо!
     
  5. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    Drunkenmunky может все же есть вариант удалять имена файлов из массива по маске расширений? У меня проблема, как узнать имена ) несколько сложно будет переделать всю конструкцию, там в скрипте много наворочено и проверок и отправка почтой и много всяких плюшек, может есть вариант, файлы выбраны, они находятся в массиве $_FILES['xtt']['name'] есть массив запрещенных расширений extension array('htm', 'html', 'shtml', 'xml', 'txt', 'sh', 'bash', 'pl', 'py', 'pyt', 'css', 'js', 'asp', 'jsp', 'cgi', 'php', 'vbs', 'cmd', 'bat', 'exe', 'dll', 'vxd', 'reg', 'ajax', 'script', 'htaccess', 'htpasswd'); загрузка у меня идет в самом низу, тк имена файлов еще меняются по определенной схеме, так что загрузка в последнюю очередь, как к примеру, если в массиве, среди файлов были к примеру *.pl и *.sh, то их выкинуть из массива вместе с именами, перестроить массив, при этом показать имена, что они не будут загружены, а прочее просто далее пустить по скрипту? Те, те файлы что прошли, будут загружены как будто массив и не чистили? Если есть идеи, как получить имена этох файлов, зная расширения из массива ограничений? Заранее спасибо!!!
     
  6. Drunkenmunky

    Drunkenmunky Старожил

    С нами с:
    12 авг 2020
    Сообщения:
    1.511
    Симпатии:
    284
    Зайдем с другой стороны.
    Есть массивы $_POST и $_GET. Вы не можете из них ничего удалить. Потому, что не вы их отправляете.
    Вы можете проверить - есть ли некий параметр в этих запросах, и если есть, то извлечь его значение, например в переменную или прямо на страницу. При этом можно это значение сравнить с неким эталоном, или по маске.
    Единственное ограничение которое вы как-то можете контролировать, это размер запроса. Все лишнее будет отброшено. Точнее обрезано.
    Так вот - $_FILES это тот же $_POST
    Вы, зная имя некоего параметра(xtt), извлекаете из него содержащиеся в нем значение или их массив, как в вашем случае. Как вариант, вы можете их извлекать предварительно с чем-то сравнив, как в коде выше.
    Вот и все.
    То есть, если нужно как-то контролировать содержимое формы загрузки, то делать это нужно на стороне браузера. Но, само собой, такой способ так же небезопасен, как и аналогичное действие с обычной формой. Вам всё равно, на стороне обработчика, придется контролировать и расширение и имя загружаемого файла.
     
    #6 Drunkenmunky, 14 сен 2022
    Последнее редактирование: 14 сен 2022
    AlexPebody нравится это.
  7. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    Ок, мы же можем из $_FILES передать в статичный массив и из него убрать нужные значения? Например по маске:

    PHP:
    1. function poisk($mask){
    2.     $file_array = array("Пушкин", "Лермонтов", "Толстой");
    3.  
    4.     foreach($file_array as $item)
    5.     if(preg_match($mask,$item)){
    6.     echo $item;
    7.     };
    8. };
    9. echo poisk($mask = '/Пушк/');
    Я просто не знаю, как получить имя файла по расширению? Расширение я получаю так:
    PHP:
    1. $stop = substr($_FILES['xtt']['name'][$i], strrpos($_FILES['xtt']['name'][$i], '.') + 1);
    А как получить имена файлов? К примеру я загружаю 2 файла test.jpg и test.js, так вот мне нужно найти расширение, которое перечисено в массиве запрещенных расширений, далее, мне нужно как то найти имена файлов этих расширений, как это сделать? Далее я исключу эти имена из массива и перестрою массив, например так:

    PHP:
    1. $array = [0 => "a", 1 => "b", 2 => "c"];
    2. $array = array_diff($array, ["a", "c"]);
    Либо есть вот такой пример:

    PHP:
    1. $array = array ('фигня' , 'ботва' , 'ерунда') ; //Массив для примера
    2. $value_to_delete = 'фигня' ; //Элемент с этим значением нужно удалить
    3. $array = array_flip($array); //Меняем местами ключи и значения
    4. unset ($array[$value_to_delete]) ; //Удаляем элемент массива
    5. $array = array_flip($array); //Меняем местами ключи и значения
    6. print_r ($array) ; //Распечатываем массив
    Т.е. в массиве $_FILES['xtt']['name'] содержатся имена файлов, я получаю расширения и на этом фильтрую, какие файлы нельзя загружать, делая остановку die(); и далее пишу в лог и пр., так вот у меня получалось убрать файл если я явно укажу его имя, к примеру:

    PHP:
    1. $array = $_FILES['xtt']['name']; //Массив для примера
    2. $value_to_delete = 'test.js' ; //Элемент с этим значением нужно удалить
    3. $array = array_flip($array); //Меняем местами ключи и значения
    4. unset ($array[$value_to_delete]) ; //Удаляем элемент массива
    5. $array = array_flip($array); //Меняем местами ключи и значения
    6. print_r ($array) ; //Распечатываем массив
    И файла test.js не будет среди загружаемых файлов, так вот у меня возникла проблема, как подставить туда файлы, вместо статичного test.js, чтобы нашлись все файлы из запрещенных по расширению? Вот основная проблема, далее я справлюсь...

    Как создать условие, если среди загружаемых файлов есть запрещенное расширение из списка массива с запрещенными расширениями, найди все имена файлов с этими расширениями в массиве $_FILES['xtt']['name'] и далее удалить по примеру выше. Как найти имена файлов? )))

    Есть идеи любые формы? Спасибо!!

    Вот интересная тема по поиску имени файла:

    PHP:
    1. $file_name = 'gfg.html';
    2. $temp= explode('.',$file_name);
    3. $extension = reset($temp);
    4. echo $extension;
    Как теперь это связать с массивом запрещенных расширений? )
     
  8. Drunkenmunky

    Drunkenmunky Старожил

    С нами с:
    12 авг 2020
    Сообщения:
    1.511
    Симпатии:
    284
    Конечно, в коде выше все для этого есть, объявите новый массив и помещайте в него $tmp_name и $path_parts['basename'].
    Пока скрипт работает файлы никуда не денутся. Либо считывайте в строку $tmp_name и сохраняйте, хоть в базу данных, но это плохой метод. move_uploded_file() вполне достаточно.
     
  9. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    @Drunkenmunky плз дайте пример, мне надо взять массив $_FILES['xtt']['name'] чекнуть его на предмет запрещенных расширений из массива $denyftype = array('htm', 'html', 'shtml', 'xml', 'txt', 'sh', 'bash', 'pl', 'py', 'pyt', 'css', 'js', 'asp', 'jsp', 'cgi', 'php', 'vbs', 'cmd', 'bat', 'exe', 'dll', 'vxd', 'reg', 'ajax', 'script', 'htaccess', 'htpasswd'); если таковые будут найдены, получить имена файлов из массива, например как написал выше, далее удалить эти элементы из массива... я саму конструкцию не могу в голове сложить, как сюда прикрепить массив $denyftype?

    Говорю 10 лет не писал на PHP... ) стараюсь найти решения и придумать конструкцию... нужен пример. :(
     
  10. Drunkenmunky

    Drunkenmunky Старожил

    С нами с:
    12 авг 2020
    Сообщения:
    1.511
    Симпатии:
    284
    Так я же дал. Это полностью рабочий скрипт.
    Поместите его например в upload.php, рядом создайте папку data, ну и форму в html-файл рядом положите
    HTML:
    1.  
    2. <form action="upload.php" method="post" enctype="multipart/form-data">
    3. ваши файлы:<br>
    4. <input type="file" name="xtt[]" /><br>
    5. <input type="file" name="xtt[]" /><br>
    6. <input type="file" name="xtt[]" /><br>
    7. <input type="submit" value="Отправить" />
    8. </form>
    9.  
     
  11. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    Пробовал вот так найти имя файла:

    PHP:
    1. $userfile_name = $_FILES['xtt']['name'];
    2. $userfile_extn = substr($userfile_name, strrpos($userfile_name, '.')-1000);
    Тоже работает, но блин, как привязать это и сделать конструкцию с массивом $denyftype )) хз...
    --- Добавлено ---
    @Drunkenmunky не это не совсем то, что я прошу... Спасибо большое, что уделяете время!! Правда спасибо!! Как сделать конструкцию:

    $array = explode('.', $_FILES['image']['name']);
    $extension = reset($array);
    +
    Привязать проверку в массиве $denyftype

    Моя проблема, я не могу понять, как найти имена файлов в массиве по их расширению, перечисленным в массиве $denyftype и убрать эти имена файлов из массива $_FILES['xtt']['name']; Вот главная задача, можете пример дать, пожалуйста?

    Я получил имя файла: echo substr($_FILES['xtt']['name'][$i], strrpos($_FILES['xtt']['name'][$i], '.') - 1000);
     
  12. Drunkenmunky

    Drunkenmunky Старожил

    С нами с:
    12 авг 2020
    Сообщения:
    1.511
    Симпатии:
    284
    Вот эта часть кода в скрипте получает информацию об имени файла.
    Код (Text):
    1. $path_parts = pathinfo($_FILES['xtt']['name'][$key]);
    В виде ассоциативного.массива $path_parts В том числе расширение.

    А вот эта часть кода
    Код (Text):
    1. if(!in_array($path_parts['extension'], $denyftype))
    Проверяет есть ли в массиве $denyftype расширение $path_parts['extension'], и если нет, то перемещает файл в заданную папку, с заданным именем $path_parts['basename']
    То есть скрипт выполняет все заданные вами условия.
     
  13. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    СПАСИБО! Только пишу пример с этим же скриптом: if(!in_array($path_parts['extension'], $denyftype)) :)
    Все верно, но это только условие, если найдешь расширение из массива, то делай то что указано ниже, это как if 1=2 do something... а мне то надо: если найдешь расширение из запрещенного списка, найди все имена в массиве $_FILES['image']['name'] и удали их.

    КАК это сделать? )))))))) 18 часов голову ломаю... вот крутится пример, а реализовать не могу, видимо не хватает тяму... ((

    PHP:
    1. $ext = $_FILES['xtt']['name'];
    2. $ForbiddenExts = array("php", "html", "htm");
    3. if(!in_array($ext, $ForbiddenExts))
    4. {
    5. если нашлись в массиве $_FILES['xtt']['name'] расширения $ForbiddenExts, то найди все имена этих расширений в массиве $_FILES['image']['name'] и удали их.
    6. }
     
  14. Drunkenmunky

    Drunkenmunky Старожил

    С нами с:
    12 авг 2020
    Сообщения:
    1.511
    Симпатии:
    284
    То есть, если в присланном массиве файлов, есть хотя бы один с запрещенным расширением, то ни один файл, не загружаем, правильно?
     
  15. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    Нет, это было бы легко сделать, по примеру выше, просто если найдёшь то die и все и сообщение типа нельзя такое загружать. Весь смысл в том, чтобы удалить эти имена из массива, сообщить, что такое то файлы не загрузились, а те, что прошли, загрузить. Вот конкретная задача:

    1. $ext = $_FILES['xtt']['name'];
    2. $ForbiddenExts = array("php", "html", "htm");
    3. if(!in_array($ext, $ForbiddenExts))
    4. {
    5. если нашлись в массиве $_FILES['xtt']['name'] расширения $ForbiddenExts, то найди все имена этих расширений в массиве $_FILES['image']['name'] и удали их.
    6. }
    --- Добавлено ---
    пункт 5 не так прост, нужно по расширениям, найти все имена в массиве $_FILES['xtt']['name'], затем флипнуть массив, удалить эти имена, флипнуть еще раз и далее я уже смогу отправить массив на шифрование файлов и на загрузку... Далее без проблем. Самое сложное, как найти имена по расширению и удалить эти имена из $_FILES['xtt']['name']?
    --- Добавлено ---
    Вот такую конструкцию нашел:
    $path = "../pictures/";
    foreach ($names as $name) {
    foreach (glob($path . $name . '*') as $filename) {
    unlink(realpath($filename));
    }
    }
     
  16. Drunkenmunky

    Drunkenmunky Старожил

    С нами с:
    12 авг 2020
    Сообщения:
    1.511
    Симпатии:
    284
    Это, сделать довольно просто. Я просто не вижу в этом смысла, или я опять не понял..
    Но, если так уж хочется, то для удаления элемента массива есть unset(), для удаления самого файла есть unlink()
    Сначала нужно получить все ключи с неправильным содержимым в одном цикле, потом удалить их во втором цикле.
    Ну и окончательно еще раз пройти по $_FILES
     
  17. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    Именно ) как? Нужно 2 цикла, я вот конструкцию и не могу собрать... Нужен пример. :(
    --- Добавлено ---
    Вот что нарыл:
    <?php
    $arr=array("a"=>"red","b"=>"blue","c"=>"green");
    $val="blue";

    $key=array_search($val,$arr,true);
    if($key!==false){
    unset($arr[$key]);
    }

    echojson_encode($arr);

    /*
    Output: {"a":"red","c":"green"}
    */
    ?>
    Только нужно получить имена по их расширению, по сути... Те $val="blue"; должно быть равно всем элементам массива из запрещенного списка расширений и содержать эти имена массива $_FILES['xtt']['name'].
    --- Добавлено ---
    И вот такой на foreach цикле

    <?php
    $arr=[1,2,3,4,3,5];
    $val=3;

    foreach($arras$key=>$value){
    if($value==$val){
    //unset($arr[$key]);
    array_splice($arr,$key,1);
    }
    }

    echojson_encode($arr);

    /*
    Output: {"0":1,"1":2,"3":4,"5":5}
    */
    ?>
     
  18. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    Вот так возвращает имена и расширения и удаляет их же, как применить массив: $denyftype = array('htm', 'html', 'shtml', 'xml', 'txt', 'sh', 'bash', 'pl', 'py', 'pyt', 'css', 'js', 'asp', 'jsp', 'cgi', 'php', 'vbs', 'cmd', 'bat', 'exe', 'dll', 'vxd', 'reg', 'ajax', 'script', 'htaccess', 'htpasswd'); ???

    $arr = $_FILES['xtt']['name'];
    foreach ($arr as $file) {
    $name = pathinfo($file, PATHINFO_FILENAME).'.'.pathinfo($file, PATHINFO_EXTENSION);
    unset($arr[$name]);
    }
    --- Добавлено ---
    :D:Do_O

    PHP:
    1. $arr = $_FILES['xtt']['name'];
    2. $ext = array('htm', 'html', 'shtml', 'xml', 'txt', 'sh', 'bash', 'pl', 'py', 'pyt', 'css', 'js', 'asp', 'jsp', 'cgi', 'php', 'vbs', 'cmd', 'bat', 'exe', 'dll', 'vxd', 'reg', 'ajax', 'script', 'htaccess', 'htpasswd');
    3. foreach ($arr as $file) {
    4.  
    5. $name = pathinfo($file, PATHINFO_FILENAME).'.'.pathinfo($file, PATHINFO_EXTENSION);
    6.  
    7.   foreach ($ext as $extt) {
    8.  
    9.   if (pathinfo($file, PATHINFO_EXTENSION) == $extt) {
    10.   unset($arr[$extt]);
    11.   }
    12.  
    13. }}
     
  19. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    Что смог накидал )

    $arr = $_FILES['xtt']['name'];
    $deny = array('php');
    foreach ($arr as $file) {
    foreach ($deny as $ext) {
    echo 'файлы: '.$file.'<br>';
    echo 'расширения: '.pathinfo($file, PATHINFO_EXTENSION).'<br><br>';
    if (pathinfo($file, PATHINFO_EXTENSION) == $ext) {
    $del = pathinfo($file, PATHINFO_FILENAME).'.'.pathinfo($file, PATHINFO_EXTENSION);
    unset($arr[$del]);
    }}}
     
  20. AlexPebody

    AlexPebody Активный пользователь

    С нами с:
    14 янв 2007
    Сообщения:
    247
    Симпатии:
    0
    Решение:

    PHP:
    1. $denyftype = array('htm', 'html', 'shtml', 'xml', 'txt', 'sh', 'bash','pl', 'py', 'pyt', 'css', 'js', 'asp', 'jsp', 'cgi', 'php', 'vbs', 'cmd', 'bat', 'exe', 'dll', 'vxd', 'reg', 'ajax', 'script', 'htaccess', 'htpasswd');
    2.  
    3. foreach ($_FILES['xtt']['name'] as $key => $name)
    4. {
    5.   $tmp_name = $_FILES['xtt']['tmp_name'][$key];
    6.   $path_parts = pathinfo($_FILES['xtt']['name'][$key]);
    7.  
    8.    if(in_array($path_parts['extension'], $denyftype))
    9.     {
    10.       if(is_file($tmp_name))
    11.       {
    12.         if(unlink($tmp_name))
    13.         {
    14.           $errors[] = $_FILES['xtt']['name'][$key];
    15.           unset($_FILES['xtt']['name'][$key],
    16.                 $_FILES['xtt']['type'][$key],
    17.                 $_FILES['xtt']['tmp_name'][$key],
    18.                 $_FILES['xtt']['error'][$key],
    19.                 $_FILES['xtt']['size'][$key]);
    20.         }
    21.       }
    22.     }
    23. }
    24.  
    25. //echo '<b>OUT</b><br>';
    26. //print_r($_FILES);
    27.  
    28. echo 'Файлы '. join(', ',$errors). ' не были загружены, тк запрещены.';
     
  21. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    947
    Симпатии:
    147
    Что за болезнь unlink-то делать, всё равно они только до конца работы скрипта существуют.
     
  22. Drunkenmunky

    Drunkenmunky Старожил

    С нами с:
    12 авг 2020
    Сообщения:
    1.511
    Симпатии:
    284
    Там непростой код. Проще костыль вставить. Чтоб не переписывать.
     
  23. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    947
    Симпатии:
    147
    Другой термин )))
     
  24. Drunkenmunky

    Drunkenmunky Старожил

    С нами с:
    12 авг 2020
    Сообщения:
    1.511
    Симпатии:
    284
    У всех был такой непростой период. Работает, и ладно.
     
  25. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    947
    Симпатии:
    147
    Какой непростой период, array_filter() один раз применить, если так чешется, и всё )