За последние 24 часа нас посетили 17506 программистов и 1730 роботов. Сейчас ищет 1061 программист ...

Прошу помочь в оптимизации и доработке скрипта

Тема в разделе "PHP для новичков", создана пользователем xDamneDx, 8 ноя 2011.

  1. xDamneDx

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

    С нами с:
    4 ноя 2011
    Сообщения:
    52
    Симпатии:
    0
    Адрес:
    Москва
    Всем привет. Я пишу эксплорер файлов(как я уже говорил, зачем он мне нужен я не знаю, мне просто захотелось его сделать).
    На данный момент реализовано следующее:
    Вывод файлов, с иконками под их расширение(или с иконкой unknown, если расширение нам неизвестно).
    Сортировка файлов и папок: сначала идут папки, а потом файлы*(если файлов и папок много - выполняется долго).
    Определение размера папок*(когда скрипт натыкается на папку с большим объёмом - выполняется долго).
    Корректное скачивание файлов.
    Рабочая кнопка "Вверх" - возврат к предыдущей директории :p
    Ну и симпатичный интерфейс :p

    *-требуется в оптимизации.

    Какие у меня мысли:
    Думаю скрипт ускорится если файловую систему связать с БД, и выполнять сортировку там, но всё время придется сверять с БД присутствие/отсутствие тех или иных файлов/директорий. Плюс этого метода в том что если какой-нибудь файл или папка будут отсутствовать или появятся новые - придется делать сортировку единожды, а не всё время.
    Как быть с определением размера папок - пока не придумал, но тоже что-то с БД буду делать(наверное).

    Ну многое из того что я хочу реализовать ещё, связано только с дизайном(красивое переименование файлов, создание папок, перемещение файлов etc.)

    А вот ещё, хочу сделать поиск файлов(и по-этому всё больше склоняюсь к БД =) ) ну всё остальное по пути...

    P.s. Я не прошу что-то делать за меня, а только подсказать, где-то указать на ошибки и т.д.
    Скрипт выкладывать? :roll:
     
  2. Михаил

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

    С нами с:
    12 июл 2009
    Сообщения:
    545
    Симпатии:
    0
    Адрес:
    Bielarus
    давай сюда код
     
  3. xDamneDx

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

    С нами с:
    4 ноя 2011
    Сообщения:
    52
    Симпатии:
    0
    Адрес:
    Москва
    Скрипт:
    PHP:
    1.  
    2. <?php
    3. /**
    4.  * Выполняет вывод всех файлов и каталогов из папки
    5.  *
    6.  * @param string $dirn
    7.  */
    8. $faili=array();
    9.  
    10. function read_dir($dirn){
    11.     global $faili;
    12.     $dir=@opendir($dirn);
    13.  
    14.  
    15.     while($f=@readdir($dir)){
    16.  
    17.         @array_push($faili,$f);
    18.  
    19.     }
    20. }
    21.  
    22. $sizes=0;
    23.  
    24. /**
    25.  * Получает расширение $filename
    26.  *
    27.  * @param string $filename
    28.  *
    29.  */
    30. function getExten($filename)
    31. {
    32.     return end(explode('.',$filename));
    33. }
    34.  
    35.  
    36. /**
    37.  * Вычисляет размер подкаталогов в каталоге
    38.  *
    39.  * @param string $dirn
    40.  */
    41. function size_dir($dirn){
    42.     global $sizes;
    43.     $fails=array();
    44.  
    45.     $dir=@opendir($dirn);
    46.  
    47.  
    48.     while($f=@readdir($dir)){
    49.  
    50.         @array_push($faili,$f);
    51.         if(($f==".")||($f=="..")){
    52.             continue;
    53.         }else {
    54.             if (is_file("$dirn/$f")){
    55.                 $sizes+=filesize("$dirn/$f");
    56.             }elseif (is_dir("$dirn/$f")){
    57.                 size_dir("$dirn/$f");
    58.             }
    59.         }
    60.  
    61.     }
    62.     @closedir($dir);
    63. }
    64.  
    65. /**
    66.  * Округляет размер файла
    67.  *
    68.  * @param int $size
    69.  * @return array
    70.  *
    71.  */
    72. function get_ext($size)
    73. {
    74.     $extencion=array('B', 'Kb', 'Mb', 'Gb', 'Tb');
    75.     $ext=array();
    76.     if (round($size/1125899906842624,2)>=1){
    77.         $ext[0]=round($size/1125899906842624,2);
    78.         $ext[1]=$extencion[4];
    79.     }elseif (round($size/1099511627776,2)>=1){
    80.         $ext[0]=round($size/1099511627776,2);
    81.         $ext[1]=$extencion[4];
    82.     }elseif (round($size/1073741824,2)>=1){
    83.         $ext[0]=round($size/1073741824,2);
    84.         $ext[1]=$extencion[3];
    85.     }elseif (round($size/1048576,2)>=1){
    86.         $ext[0]=round($size/1048576,2);
    87.         $ext[1]=$extencion[2];
    88.     }elseif (round($size/1024,2)>=1){
    89.         $ext[0]=round($size/1024,2);
    90.         $ext[1]=$extencion[1];
    91.     }elseif (round($size/1024,2)<1){
    92.         $ext[0]=round($size/1024,2);
    93.         $ext[1]=$extencion[1];
    94.     }
    95.     return $ext;
    96.  
    97. }
    98.  
    99.  
    100. $dirn=dirname (__FILE__);
    101.  
    102.  
    103. if (isset($_GET['dir'])){
    104.     $_GET['dir']=preg_replace("/\\\/","/",$_GET['dir']);
    105. /*  $_GET['dir']=preg_replace("#\//#i","/",$_GET['dir']);
    106.     $_GET['dir']=preg_replace("#C:/#i","L:/",$_GET['dir']);
    107.     $_GET['dir']=preg_replace("#K:/#i","L:/",$_GET['dir']);
    108.     $_GET['dir']=preg_replace("#E:/#i","L:/",$_GET['dir']);*/
    109.     $_GET['dir']=preg_replace("#WM ключи#","/",$_GET['dir']);
    110.  
    111.  
    112.     if (is_file($_GET['dir'])){
    113.         $ctl=strlen($_GET['dir']);
    114.         $ct=substr($_GET['dir'],$ctl-5,5);
    115.         $ct=str_replace(".","",$ct);
    116.         header('Content-type: application/'.$ct);
    117.         $ct=end(explode('/',$_GET['dir']));
    118.         header('Content-Disposition: attachment; filename="'.$ct.'"');
    119.  
    120.         echo file_get_contents($_GET[dir]);
    121.         exit();
    122.     }else {
    123.         $dirn=$_GET['dir'];
    124.  
    125.     }
    126. }
    127.  
    128. /**
    129.  * Получает строку $string урезает ее до $numsymbol начиная с $start
    130.  * и доставляет в конец строки $symbol
    131.  *
    132.  * @param string $string
    133.  * @param int[optional] $numsymbol
    134.  * @param string $symbol
    135.  * @param int[optional] $start
    136.  * @return string
    137.  */
    138. function strlengh($string, $numsymbol=7,$symbol=" ...",$start=0){
    139.     if (strlen($string)>$numsymbol)
    140.     {
    141.         $string=substr ($string, $start, $numsymbol)."$symbol";
    142.     }elseif (strlen($string)<$numsymbol)
    143.     {
    144.         $string=substr ($string, $start,$numsymbol);
    145.     }
    146.     return $string;
    147. }
    148.  
    149. $dirn=preg_replace("/\\\/","/",$dirn);
    150.  
    151. read_dir($dirn);
    152. $dirn=preg_replace("#\//#","/",$dirn);
    153.  
    154.  
    155. $vivod="";
    156.  
    157. /*
    158. Методом сортировки приводим к виду: "Сначала папки, потом файлы"
    159. */
    160. for ($j=0; $j<count($faili);$j++){
    161.     for ($i=0; $i<count($faili)-1;$i++){
    162.         if (is_dir($dirn.'/'.$faili[$i+1]))
    163.         {
    164.         $k=$faili[$i+1];
    165.         $faili[$i+1]=$faili[$i];
    166.         $faili[$i]=$k;
    167. //прекращаем сортировку если файлов и папок больше 100, дабы не зависать.
    168.         if ($i>100){
    169.             break;
    170.         }
    171.         }
    172.  
    173.     }
    174. }
    175.  
    176. for ($i=0; $i<count($faili);$i++){
    177. $sizes=0;
    178.  
    179.     if (preg_match("/^\.\.|\.$/",$faili[$i])){
    180. /*      $faili[$i]=preg_replace("/^\.\.$/","Назад",$faili[$i]);
    181.         $vivod.="<img src=http://i045.radikal.ru/0907/07/159b640fe36b.png>
    182.         <a href=\"explorer.php?dir=$dirn/..\"><font color=\"black\">$faili[$i]</font></a><br>" ;*/
    183.         continue;
    184.     }
    185.     if (is_dir($dirn.'/'.$faili[$i])){
    186. //временно убрано вычисление размеров папок
    187. /*      if(($faili[$i]!=".")){
    188.  
    189.             size_dir($dirn.'/'.$faili[$i]);
    190.             $sizes=get_ext($sizes);
    191.         }*/
    192.         $vivod.="<a href=\"explorer.php?dir=$dirn/$faili[$i]\" title=\"$faili[$i]\"><font color=\"black\"><div style=\"float : left; height : 75px;  width : 15%; border : solid 0px Aqua\"><img src=\"img/Extencions/Folder-close.png\" /><br>
    193.         ".strlengh($faili[$i],15,"...")."</font></a></div>" ;
    194.     }
    195.    
    196.     else{
    197.         $extfiles[$i]=$faili[$i];
    198.         $file_ext[$i]=getExten($extfiles[$i]);     
    199.         $sizes=get_ext(filesize("$dirn/$faili[$i]"));
    200.             if (is_file("img/Extencions/".$file_ext[$i].".png")){
    201.                 $vivod.="<a href=\"explorer.php?dir=$dirn/$faili[$i]\" title=\"$faili[$i]\"><font color=\"#6699cc\"><div style=\"float : left;  width : 15%; height : 75px; border : solid 0px Aqua\"><img src=\"img/Extencions/".$file_ext[$i].".png\" /><br>
    202.         ".strlengh($faili[$i],15,"...")."</font></a></div>" ;
    203.             }
    204.             else {
    205.                 $vivod.="<a href=\"explorer.php?dir=$dirn/$faili[$i]\" title=\"$faili[$i]\"><font color=\"#6699cc\"><div style=\"float : left;  width : 15%; height : 75px; border : solid 0px Aqua\"><img src=\"img/Extencions/unknown.png\" /><br>
    206.         ".strlengh($faili[$i],15,"...")."</font></a></div>" ;
    207.             }
    208.  
    209.        
    210.        
    211.     }
    212.    
    213. }
    214. $back=dirname($dirn);
    215.  
    216. $content=file_get_contents('index.htm');
    217. $content=preg_replace('/{FOLDER}/',$dirn,$content);
    218. $content=preg_replace('/{CONT}/',$vivod,$content);
    219. $content=preg_replace('/{GO_BACK}/',"explorer.php?dir=$back",$content);
    220. echo $content;
    221. ?>
    222.  
    Шаблон:
    HTML:
    1.  
    2.     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    3.     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    4.  
    5.  
    6.     <html xmlns="http://www.w3.org/1999/xhtml">
    7.     <head>
    8.         <title>Explorer</title>
    9.         <link href="css/main.css" type="text/css" rel="Stylesheet" />
    10.         <script type="text/javascript" src="jquery-1.3.2.min.js"></script>
    11.         <script type="text/javascript">
    12.         var showing="hidden";
    13.         function show_menu(id){
    14.             if (showing == "hidden") {
    15.                 $('#' + id).fadeTo(250, 1);
    16.                 showing = "show";
    17.             }else
    18.             if(showing=="show"){
    19.                 $('#' + id).fadeTo(250, 0);
    20.                 showing='hidden';
    21.             }
    22.         }
    23.         function hide_menu(id){
    24.             $('#'+id).fadeTo(250,0);
    25.             showing='hidden';
    26.         }
    27.     </head>
    28.     <body>
    29.         <div class="wrapper">
    30.             <div class="title">
    31.                 <img src="img/siteElements/header/folder_icon.png" />
    32.                 {FOLDER}
    33.             </div>
    34.             <div class="icon_panel_top">
    35.                
    36.             </div>
    37.             <hr class="hr_divider" />
    38.             <div class="icon_panel_bottom">
    39.                 <a href="javascript:void(0)" class="a_img"><img src="img/siteElements/header/arrow_back.png" /></a>
    40.                 <a href="javascript:void(0)" class="a_img"><img src="img/siteElements/header/arrow_forward.png" /></a>
    41.               <img src="img/siteElements/header/panel_divider.png" />
    42.                 <a href="{GO_BACK}" class="a_img"><img src="img/siteElements/header/folder_up.png" /></a>
    43.                 <a href="javascript:show_menu('block1')" class="a_img"><img src="img/siteElements/header/search.png" /></a>
    44.                 <a href="javascript:void(0)" class="a_img"><img src="img/siteElements/header/folders.png" /></a>
    45.             </div>
    46.             <hr class="hr_divider" />          
    47.             <div class="adress_bar">
    48.                 <form>
    49.                     Адрес:
    50.                     <select class="text_adress_bar">
    51.                         <option>1</option>
    52.                     </select>
    53.                      <a href="javascript:void(0)" class="a_img"><img src="img/siteElements/header/goto.png" /></a>
    54.                 </form>                
    55.             </div>            
    56.             <hr class="hr_divider" />
    57.             <div class="left_panel">
    58.            
    59.             <div id="block1" class="l_block">
    60.             <div class="h_blocks" >Поиск&nbsp;<span style="cursor: pointer;" onclick="hide_menu('block1')">[X]</span></div>
    61.             <div class="ic_cblock"><br>
    62.            
    63.             <input type="hidden" id="patch" value="{PATCH}">
    64.             <form action="" method="POST" id="search">
    65.             <input type="text" id="keywords">&nbsp;<input type="button" value="Поиск">
    66.              
    67.              </form><br>  
    68.                    
    69.             </div>          
    70.             </div>
    71.             </div>
    72.             <div class="right_panel">{CONT}</div>                        
    73.         </div>
    74.     </body>
    75.     </html>
    76.  
     
  4. xDamneDx

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

    С нами с:
    4 ноя 2011
    Сообщения:
    52
    Симпатии:
    0
    Адрес:
    Москва
    ААААААААААААААААААААП!
     
  5. topas

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

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    xDamneDx
    А в чём вопрос?
     
  6. xDamneDx

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

    С нами с:
    4 ноя 2011
    Сообщения:
    52
    Симпатии:
    0
    Адрес:
    Москва
    Вопрос в следующем: стОит ли связывать фс с бд, и возможно ли ещё оптимизировать мой код в некоторых моментах. Да и вообще интересно было послушать от "дедов" какую-нибудь критику, или предложения =)
     
  7. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    xDamneDx
    у тебя что-то конкретное не работает?
     
  8. xDamneDx

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

    С нами с:
    4 ноя 2011
    Сообщения:
    52
    Симпатии:
    0
    Адрес:
    Москва
    PHP:
    1.  
    2. <?
    3.  for ($j=0; $j<count($faili);$j++){
    4.      for ($i=0; $i<count($faili)-1;$i++){
    5.          if (is_dir($dirn.'/'.$faili[$i+1]))
    6.          {
    7.          $k=$faili[$i+1];
    8.          $faili[$i+1]=$faili[$i];
    9.          $faili[$i]=$k;
    10.  //прекращаем сортировку если файлов и папок больше 100, дабы не зависать.
    11.          if ($i>100){
    12.              break;
    13.          }
    14.          }
    15.  
    16.      }
    17.  }
    18. ?>
    19.  
    Сортировка проходит очень долго если файлов много (много это не 1000000000+ файлов, а хотябы 400)


    PHP:
    1.  
    2. <?
    3. function size_dir($dirn){
    4.      global $sizes;
    5.      $fails=array();
    6.  
    7.      $dir=@opendir($dirn);
    8.  
    9.  
    10.      while($f=@readdir($dir)){
    11.  
    12.          @array_push($faili,$f);
    13.          if(($f==".")||($f=="..")){
    14.              continue;
    15.          }else {
    16.              if (is_file("$dirn/$f")){
    17.                  $sizes+=filesize("$dirn/$f");
    18.              }elseif (is_dir("$dirn/$f")){
    19.                  size_dir("$dirn/$f");
    20.              }
    21.          }
    22.  
    23.      }
    24.      @closedir($dir);
    25.  }
    26. ?>
    27.  
    аналогичная ситуация, если файлов в папке много, то грузится очень-очень долго. есть варианты как можно оптимизировать?
     
  9. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    xDamneDx
    Сортировка проходит очень долго
    постарайся привести код к использованию готовых функций пхп для сортировки массивов. Они написаны на сях и работают быстро. А что ты там делаешь - это конечно смерть всему живому.

    xDamneDx
    есть варианты как можно оптимизировать?
    вроде как есть. смотри в гугле по "php file listing" или типа того
     
  10. xDamneDx

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

    С нами с:
    4 ноя 2011
    Сообщения:
    52
    Симпатии:
    0
    Адрес:
    Москва
    ага, спасибо. пойду дальше копать =)
     
  11. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
  12. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    обрати внимание на натуральную сортировку
     
  13. xDamneDx

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

    С нами с:
    4 ноя 2011
    Сообщения:
    52
    Симпатии:
    0
    Адрес:
    Москва
    я сразу на неё наткнулся, и уже читаю))
     
  14. krow7

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

    С нами с:
    12 авг 2009
    Сообщения:
    398
    Симпатии:
    0
    Адрес:
    из Азии
    glob(), не?
     
  15. xDamneDx

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

    С нами с:
    4 ноя 2011
    Сообщения:
    52
    Симпатии:
    0
    Адрес:
    Москва
    нууу, не думаю.

    мне вот какая мысль пришла в голову, а что если просто в самой функции:

    PHP:
    1.  
    2. <?
    3. function read_dir($dirn){
    4.      global $faili;
    5.      $dir=@opendir($dirn);
    6.  
    7.  
    8.      while($f=@readdir($dir)){
    9.  
    10.          @array_push($faili,$f);
    11.  
    12.      }
    13.  }
    14. ?>
    15.  
    сделать две разных переменные для файлов и папок? а потом просто выводить их, так по-моему даже будет лучше, наааамного лучше.
     
  16. xDamneDx

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

    С нами с:
    4 ноя 2011
    Сообщения:
    52
    Симпатии:
    0
    Адрес:
    Москва
    ну как я и говорил, только что проверил всё верно выводит =) ура =)
    а вот с размером директорий как быть теперьче...
     
  17. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Чем тебе глоб не приглянулся?
     
  18. xDamneDx

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

    С нами с:
    4 ноя 2011
    Сообщения:
    52
    Симпатии:
    0
    Адрес:
    Москва
    незнаю, мне показалось что разумнее будет если в самой функции просто разбить на две переменные, дальше будет легче работать(имхо) с папками и файлами отдельно
     
  19. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Вместо opendir и потом readdir в цикле можешь один раз вызвать scandir() и потом в цикле перебирать простой php-массив, который вернёт эта функция.
    Рекурсивный обход всех вложенных поддиректорий - это полюбому будет сравнительно долго, если их много. Придётся дёргать ФС сервера для просмотра каждой поддиректории и всех её "потомков".
     
  20. Apple

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

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    xDamneDx
    Если тебе нужен Эксплорер, а НЕ СКРИПТ эксплорера, то без индексов далеко не уедешь, поверь.
    Храни контрольные суммы, индексируй вторичные ноды бинарных деревьев и не сортируй всё каждый раз, так же как и не делай листиг. Хотя если тебе только скрипт написать, который не имеет практического применения, то можно и не думать об этом.
     
  21. xDamneDx

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

    С нами с:
    4 ноя 2011
    Сообщения:
    52
    Симпатии:
    0
    Адрес:
    Москва
    В принципе, мне нужна просто практика, вот и начал реализовывать задумку.

    Как много новых слов :О
    хранить контрольные суммы ещё более или менее понятно. (Хранить в БД?)
    Индексировать вторичные ноды бинарных деревьев...(???тут по-подробней, пожалуйста. Нагуглить мало чего получилось)
    Не сортировать всё каждый раз(это реализовывается опять же с помощью БД? или я что-то не так понимаю?)

    З.ы. может я для практики не очень хорошую задумку выбрал? =))))
     
  22. xDamneDx

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

    С нами с:
    4 ноя 2011
    Сообщения:
    52
    Симпатии:
    0
    Адрес:
    Москва
    кстати говоря, сейчас у меня всё происходит так:

    PHP:
    1.  
    2. <?
    3. function read_dir($dirn){
    4.     global $faili;
    5.     global $dirs;
    6.     $dir=@opendir($dirn);
    7.  
    8.  
    9.     while($f=@readdir($dir)){
    10.         if (is_file("$dirn/$f"))
    11.         {
    12.         array_push($faili,$f); 
    13.         }
    14.         else
    15.         {
    16.         array_push($dirs,$f);  
    17.         }
    18.        
    19.     }
    20. }
    21. ?>
    То бишь, я взял две разных переменные и соответственно раскидал папки и файлы в них. Далее двумя циклами последовательно вывожу сначала папки, а потом файлы.