микрофайлообменник Php

Discussion in 'Статьи' started by Talisman, 23 Mar 2007.

  1. Talisman

    Talisman Elder - Старейшина

    Joined:
    22 Apr 2006
    Messages:
    400
    Likes Received:
    151
    Reputations:
    80
    Привет! Сейчас я покажу микроурок мастерства ) ну.. конечно, я не исключаю косяки в своей проге, но все же претендую на безопасность
    Писать будем не сайт, а файлообменник для мобилы - минимум диза, максимум простоты и удобства админу.
    Итак, мы напишем скрипт, который будет брать файлы из директорий, выводить их листинг и еще кое что, приступим
    PHP:
      function scan_dir($dirname)
      {
        GLOBAL 
    $text$retext;
        
    $dir opendir($dirname);
        while ((
    $file readdir($dir)) !== false)
        {
          if(
    $file != "." && $file != "..")
          {
          if(
    is_file($dirname."/".$file))
            {
                  echo 
    '<a href="/s/'.$dirname.$file.'">'.$file.'</a><br />';
            }
            if(
    is_dir($dirname."/".$file))
            {
                  echo 
    '<a href="/s/'.$dirname.''.$file.'/"><font color="red"><img src="/s/folder.ico">'.$file.'</font></a><br />';
            }
          }
        }
        
    closedir($dir);
      }
    Это функция рекурсивного обхода директории, которая при обнаружении файла (if_file) выводит его имя и линк на него, при обнаружении же диры, выводит картинку и ссылку на диру.
    Вот так будем давать линк на диру:
    http://demo.my/s/f/soft/
    где http://demo.my/s/f/ - коренвая папка с файлами. а на файлы будем давать линки вроде: http://demo.my/s/f/kaleostra.txt - т.е. как обычный веб сервер, только прикол в том, что обрабатывать все это будет наш скрипт, для чего занесем в штаксесс файл следующие строчки:
    первой строчкой мы запускаем модуль апача для ЧПУ, второй приказываем использовать относительные переходы по каталогу веб-сервера, а третьей задаем правило - все запросы ниже папки f/ передавать скрипту scan.php:
    НО для начала поясню, что делается в этом файле - для простоты будем только сканить директорию, если юзер послал запрос на диру, или выдавать файл, занося данные в лог скачки файлов, примерно следующего содержания:
    где до двоеточия стоит имя файла, а после - сколько раз его скачали
    PHP:
    <?php
    // echo($_SERVER["REDIRECT_URL"]); - стррока запроса пользователя вида: /s/f/file.txt или /s/f/folder/

    //// фильтруем эту входящую строчку, точнее срезаем начальные /s (т.к. скрипт лежит у нас не в корне сайта, а папке 's') (хотя впринципе можно сменить рабочую директорию :) )
    $URL=substr($_SERVER["REDIRECT_URL"],3); // срезаем первые 2 символа, т.е. копируем строку с третьего, и превращаем ее в вида: /f/some flood :)

    if(is_file($URL))  //// это файл, отдаем пользователю.
    {
          
    ///отдаем пользователю
          
    header('Content-type: */*'); // посылаем заголовки
          
    header('Content-Disposition: attachment; filename="'.$URL.'"'); // имя файла
          
    readfile($URL); // и сам файл :)
          ///заносим данные в лог скачек
          
    $log=file('log.txt'); // заносим файл в массив
          
    $f=fopen('log.txt','w'); // открываем его для перезаписи
          
    $c=false// устанавливаем флаг в false (зачем он - поймете дальше)
          
    foreach($log as $log_line // - разбиваем лог файл на строчки
          
    {
           if(
    strlen($log_line)>3// откидываем заведомо пустые строчки (просто перестраховка)
           
    {  
             list(
    $filename,$count)=split(':',$log_line); // разбиваем их по двоеточию
             
    if($filename==$URL// если имя запрошенного файла совпадает с этой строчкой до двоеточия, то
             
    {
               
    $count=$count+1// увеличиваем счетчик загрузок на 1
               
    fwrite($f,$URL.':'.$count."\r\n"); // записываем новые данные в файл лога скачки
               
    $c=true// устанавливаем флаг, т.е. файл уже есть в логе!
             
    }else
             {
                     
    fwrite($f,$log_line); // остальные стрчоки переписываем без изменений
             
    }
           }
          }
          if(
    $c==false// если ни один файл не увеличил свой счетчик, значит этот файл был скачан впервые, добавим его к логу
          
    {
              
    fwrite($f,$URL.":1\r\n");    
          }
              
    fclose($f); // закрыли файл лога
              
    exit;  // убили скрипт :)

    }
      function 
    scan_dir($dirname)  // наша "рекурсия"
      
    {
        GLOBAL 
    $text$retext;
        
    $dir opendir($dirname);
        while ((
    $file readdir($dir)) !== false)
        {
          if(
    $file != "." && $file != "..")
          {
          if(
    is_file($dirname."/".$file))
            {
                  echo 
    '<a href="/s/'.$dirname.$file.'">'.$file.'</a><br />';
            }
            if(
    is_dir($dirname."/".$file))
            {
                  echo 
    '<a href="/s/'.$dirname.''.$file.'/"><font color="red"><img src="/s/folder.ico">'.$file.'</font></a><br />';
            }
          }
        }
        
    closedir($dir);
      }
    if(
    is_dir($URL)) // если запросили диру - выводим ее листинг
    {
      
    scan_dir($URL);
    }else 
    // посылаем нафиг, т.к. случай файла рассматривали выше :)
    {
      echo 
    'we are sorry... :(';
      exit;
    }
      echo 
    '<a href="/s/f/"><font color="red">-home-</font></a>'// выводим линк на главную пагу обменника
    ?>
    Наверно вы скажете, что если ввел адрес вида: http://demo.my/s/f/soft/../../../../../etc.passwd то думаете получити файл паролей? фиг вам! ведь это урл, а не параметры, переходящие в файл, поэтому апач вам выдаст главную пагу сайта (смотря как глубоко опуститесь, но глубже маинпаги никак )
    Впервые подобный скриптик я писал года 2 назад, для сайта по мобилам, естессно, функций было больше правда реврайтэнжине я тогда не умел использовать, и приходилось производить очень много фильтраций ))) а совсем недавно создал аналогичный файлообменник для себя. (ЗЫ линк не дам, мейби тока скрины, т.к. его адрес не всем согласен дать... ))
    ЗЫ задолбался постить такие вещи в статьи, но в разделе о веб-кодинге нет соответствующего подкаталога, например уроки, а не хочется, чтобы твой труд утонул среди вопросов.
     
    1 person likes this.
  2. Sn@k3

    Sn@k3 Elder - Старейшина

    Joined:
    13 Apr 2006
    Messages:
    1,000
    Likes Received:
    438
    Reputations:
    90
    урок мастерства? ты се льстишь...
     
  3. Darkweider

    Darkweider Elder - Старейшина

    Joined:
    8 Feb 2007
    Messages:
    142
    Likes Received:
    13
    Reputations:
    0
    Да не вроде норм, тока я через мобильник в инет не захожу...
     
  4. Talisman

    Talisman Elder - Старейшина

    Joined:
    22 Apr 2006
    Messages:
    400
    Likes Received:
    151
    Reputations:
    80
    читай конец про недостающий раздел ))) в маленьких объемах самолесть поднимает настроение :)))