За последние 24 часа нас посетили 53940 программистов и 1802 робота. Сейчас ищут 936 программистов ...

Продажа mp3 на сайте

Тема в разделе "PHP для новичков", создана пользователем pascal, 28 янв 2008.

  1. pascal

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

    С нами с:
    22 апр 2006
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Москва
    Народ помогите плиз. Как можно реализовать продажу mp3 на сайте.

    Т.е. есть каталог mp3. Они как обычные товары кладутся в корзину. Чел заходит в корзину оформляет заказ, оплачивает его, а потом ему генерятся ссылки по которым он может скачивать mp3.

    1. Как сделать чтобы чел смог скачать mp3 только один раз.
    2. Чтобы кроме него никто не мог скачать эту mp3.

    Заранее огромное спасибо!
     
  2. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
    генерируешь ему временную ссылку и по ней через header() отдаёшь файл

    Как — в поиск
     
  3. TROODON

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

    С нами с:
    4 ноя 2007
    Сообщения:
    112
    Симпатии:
    0
    делаешь так чтобы качать могли только зарегистрированные потом при скачке (идёт не прямая ссыль а мудрённая через проверялки) проверячешь по БД если файл такой уже скачал значит больше скачивать его не даст
     
  4. Andrey5555

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

    С нами с:
    29 ноя 2007
    Сообщения:
    486
    Симпатии:
    0
    Адрес:
    Киев
    А на примере можно?
     
  5. Штаны

    Штаны Guest

    А что за mp3? Музон на который у тебя нет прав реализации? :)
    А с оплатой у тебя проблем нет? :)
    Короче, вышли пользователю mp3 на его е-маил и голову не морочь :)
     
  6. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Не забудь про предварительное прослушивание в плохом качестве (или в хорошем, но кусочек песни).
     
  7. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
    ты что! Тут у человека скоро вопросы про реализацию регистрации и корзины ещё будут, а ты про прослушивание…
     
  8. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    7 нот как в "Угадай мелодию" ))
     
  9. S.t.A.M.

    S.t.A.M. Активный пользователь

    С нами с:
    10 сен 2007
    Сообщения:
    1.041
    Симпатии:
    0
    А нафига когда есть jetune.ru, rmp.ru и другие бесплатные?
     
  10. RomanBush

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

    С нами с:
    5 дек 2007
    Сообщения:
    798
    Симпатии:
    0
    Адрес:
    200 км от Москвы
    патамушта нада свой бизнес делать! Давненько вы, мистер, не читали самоучители "как сделать бизнес в ентернетах". Они все с чего начинаются? С того, что "нада перестать работать на дядю и самому станавица ночальникам". А дальше объясняется, как песатель, вложив всего ??? рублей (цифры меняются от 100 до 1000), теперь "палучил настаящий стабильный бизнес, приносящий ??????? долларов в день" (цифры меняются от 30 баксов до бесконечности). Бизнес - как правило, либо продажа електронного контента (например, mp3), правда, в 99% самоучителей не уточняется, откуда взять этот контент, либо заманиловка в какую-нить рефералку по продаже такого же дерьма.
     
  11. pascal

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

    С нами с:
    22 апр 2006
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Москва
    вот как раз как реализовать мудреную ссылку на файл через проверялки.
    У меня идея была такая типа давать ссылку на скрипт, а потом каким то образом если все норм выдавать бинарный поток.

    Возможно ли это и если да то как?
     
  12. Ganzal

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

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    pascal
    как реализовать мудреную ссылку обсуждалось тут на моей памяти не один раз
    воспользуйся поиском. найдешь и теорию и практические реализации
    додумать проверку надеюсь сможешь сам
     
  13. pascal

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

    С нами с:
    22 апр 2006
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Москва
    Как в случае когда все правильно выдавать пользователю бинарный поток чтобы браузер воспринял его как файл и пользователь мог скачать этот файл?
     
  14. nimistar

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

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    pascal - Если идут подобные вопросы, то очень стоит задуматся - "может сделать сначала ЛИЧНЫЙ фотоальбом",
    после експерементов с работой над картинками вопросы обинарниках отвалятся сами!
    Выдача файла, ещё не самый сложный вопрос который возникнет на данном пути, например безопасность мп3 магазина должна быть на порядок выше чем магазана торгующего бытовой техникой или книгами (и HTTPS - не всегда решение),
    Оплата тоже намаленькая и простая задача ...

    собственно ответ на сам вопрос как выдать фаил :
    (скрипт для теста технологии фрагментарного лоадера)
    PHP:
    1.  
    2. <?php
    3. ignore_user_abort(true); // чтобы могли адекватно обработать порванный коннект
    4. error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING );
    5. $uniqID=uniqid(); // уникальный идентификатор текущего запуска скрипта
    6. header('Cache-Control: no-cache');
    7. $timeStart=microtime();
    8. $LOGS='';$LOGS.="Start at - ".$timeStart." ID[".$uniqID."] \r\n";
    9. ini_set("session.use_trans_sid",true);
    10. ini_set("session.use_only_cookies",false);
    11. session_name('sid');
    12. //Стартуем сессию дабы определить что именно этот клиент скачал именно этот фаил!
    13.  
    14.  
    15. // Определение констант
    16. define('SEGMENT',1024);                    // размер стандартного сегмента
    17. define('TIME_DELAY',1000);                // задержка обработки для понижения скорости (1 сек = 1 000 000 микросекунд)
    18. define('DIRECTORY',getcwd());            // текущая дериктория
    19. define('SESSION_SID',session_id());     // чтобы можно было закрыть сессию
    20. $mime_type='application/octet-stream';// универсальный тип для посылаемых данных ... всегда будет запрос на сохранение файлов, а не передача предустановленному обработчику
    21. // Определение переменных
    22. $NoErrors=true;
    23. $HashOfFile=htmlspecialchars($_GET['file']);
    24. $_file=DIRECTORY.'/FILES/'.$HashOfFile;
    25.  
    26. session_write_close(); // <-- ОБЯЗАТЕЛЬНО иначе повторные потоки нестартуют для данного пользователя! (искал 3 месяца)
    27.  
    28. function ParsArray($ARR,$amp){foreach ($ARR as $key => $value){@$R.= "\t".$amp."[".$key."] => $value<br>\n";if(is_array($value)) $R.= ParsArray($value,$amp."[".$key."]");}return $R;}
    29.  
    30. function CountSegments($fileofsegment){ // Подсчет размера отданной информации по сегментам
    31.   $F=@fopen($fileofsegment,"r") or  error_log('can\'t open log file of segments', 0);
    32.   if($F===false){error_log('can\'t read file of segments - '.$fileofsegment, 0);return 0;}
    33.   $R=array();
    34.   while(!feof($F)){
    35.     $t=explode("\t",fgets($F, 4096));
    36.     if(isset($t[1])){
    37.       $R[$t[0]]=((@(int)$R[$t[0]] < (int)$t[1]) ? $t[1] : $R[$t[0]]);
    38.     }
    39.   }
    40.   fclose($F);
    41.   ksort($R);    $LastS=0;$LastL=0;$totalSize=0;
    42.   foreach($R as $S => $length){
    43.     if(($LastS+$LastL) < ($S+$length)){
    44.       if(($LastS+$LastL) > $S){
    45.         $totalSize+=$length - $LastS - $LastL + $S;
    46.       }else{
    47.         $totalSize+=$length;
    48.       }
    49.       $LastS=$S;
    50.       $LastL=$length;
    51.     }
    52.   }
    53.   return $totalSize;
    54. }
    55.  
    56. function write_to($mess) {  // Логирование данных
    57.   global $_file,$_SERVER,$uniqID,$timeStart,$LOGS;
    58.   $LOGS.=date("d.m.y H:i:s").'('.(microtime()-$timeStart).') - '.$_SERVER['REMOTE_ADDR'].' - SID:'.SESSION_SID.' - ID['.$uniqID.'] - file('.$_file.') - '.$mess."\r\n";
    59. }
    60.  
    61. function shdn(){ // функция выполняемая по окончанию выброса сигмента
    62.   global $_file,$filesize,$_SERVER,$NoErrors,$LengthSend,$rlow,$HashOfFile,$LOGS,$RootDir;
    63.   write_to("shutdown function started");
    64.  
    65.   $file_segment=DIRECTORY.'/logs/'.SESSION_SID.".".$HashOfFile.".segment";
    66.   if(file_exists($file_segment)while(!is_writable($file_segment)){usleep(100);}
    67.   $FH=fopen($file_segment,'a') or  error_log('can\'t open segment file', 0);
    68.   if(fwrite($FH,$rlow."\t".$LengthSend."\n")===false){error_log('can\'t write segment file', 0);}fclose($FH);
    69.  
    70.  
    71.   $totalLoad=CountSegments(DIRECTORY.'/logs/'.SESSION_SID.".".$HashOfFile.".segment"); // Считаем все сигменты сегмент - для накопления!
    72.   write_to("Loaded Segmen [".$rlow."]=>".$LengthSend);
    73.   write_to("End Script: ".$totalLoad." ".(($totalLoad>=filesize($_file)) ? ">=" : "<")." total size: ".filesize($_file));
    74.     write_to("connection ".(connection_aborted() ? "aborted" : (connection_status()==2 ? "connection_timeout" : "???")));
    75.   } else {
    76.     write_to("valid connection shutdown");
    77.     if($totalLoad >= filesize($_file)){write_to("DOWNLOAD COMPLITE");}
    78.   }
    79.  
    80.   // записываем лог
    81.   if(file_exists(DIRECTORY.'/logs/downloaded_count-'.date("d_m_Y").'.txt'))while(!is_writable(DIRECTORY.'/logs/downloaded_count-'.date("d_m_Y").'.txt')){usleep(100);} // ждем пока освободится фаил
    82.   $FH=fopen(DIRECTORY.'/logs/downloaded_count-'.date("d_m_Y").'.txt','a') or  error_log('can\'t open log file', 0);
    83.   if(fwrite($FH,$LOGS)===false){error_log('can\'t write log file', 0);}fclose($FH);
    84. }
    85.  
    86. // обработка запрашиваемого заголовка на предмет фрагментарности
    87. if($_SERVER['REQUEST_METHOD']==='HEAD'){ // при запросе только заголовка расчитываем размеры .. но не передаем фаил (даже не пытаемся)
    88.   $onlyHead = true;$rhigh = 0;$rlow = 0;
    89. }else{
    90.   $onlyHead = false;
    91.   if (isset($_SERVER['HTTP_RANGE'])){ // если запрос фрагмента
    92.     preg_match_all('/bytes=([0-9]*)-([0-9]*)/',$_SERVER['HTTP_RANGE'],$out);
    93.     $rlow=$out[1][0];
    94.     $rhigh=$out[2][0];
    95.     write_to("Request Part (block:[$rlow]-[$rhigh] ) ");
    96.   }else{ // простая прямая выдача файла
    97.     write_to('Request without Part >>');
    98.   }
    99.   if(empty($rlow)){$rlow=0;}
    100. }
    101.  
    102.  
    103. $fileSize=filesize($_file);$LengthSend=0;$STRfilename=trim($_GET['file']);
    104. if($onlyHead){            // если от нас хотели только информацию о файле
    105.   header("Content-Length: $fileSize");
    106.   header("Content-Disposition: attachment; filename=\"$STRfilename\"");
    107. }else{                    // выдача запрошенного фрагмента
    108.   header("Content-Type: $mime_type");      // формирование заголовков
    109.   header('Accept-Ranges: bytes');
    110.   header('Connection: Keep-Alive');
    111.   header("Content-Disposition: attachment; filename=\"$STRfilename\"");
    112.   if (isset($_SERVER['HTTP_RANGE'])){        // заголовки для фрагмента
    113.     header('HTTP/1.1 206 Partial Content');
    114.     header('Content-Range: bytes '.$rlow.'-'.(!empty($rhigh) ? ($rhigh) : ($fileSize)).'/'.(!empty($rhigh) ? ($rhigh-$rlow) : ($fileSize-$rlow)));
    115.     header('Content-Length: '.(!empty($rhigh) ? ($rhigh-$rlow) : ($fileSize-$rlow)));
    116.   }else{
    117.     header("Content-Length: $fileSize");   // для прямого выброса
    118.   }
    119.   ob_flush();
    120.   for($i=$rlow;$i<=(!empty($rhigh) ? $rhigh : $fileSize);$i+=SEGMENT) {
    121.     if(connection_status()==0){
    122.       $OUT=file_get_contents($_file,false,NULL,$i,SEGMENT);
    123.       echo $OUT;
    124.       ob_flush();
    125.       usleep(TIME_DELAY);
    126.       if(connection_status()==0){ob_flush();$LengthSend+=strlen($OUT);}else{write_to('status ob: '.ParsArray(ob_get_status(true),'status'));}
    127.     }else{
    128.       write_to('Connection down');break;
    129.     }
    130.   }
    131. }
    132. shdn();// исключительно для ВИНДЫ - в ней несрабатывает зарегестрированная функция по окончанию работы скрипта ( register_shutdown_function) хотя последнее правильней
    133. ?>
    134.  
    Надеюсь гуру шапками незабросают ;-)
     
  15. RomanBush

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

    С нами с:
    5 дек 2007
    Сообщения:
    798
    Симпатии:
    0
    Адрес:
    200 км от Москвы
    Есть шанс, что "гуру" поленятся столько кода разбирать. :)
     
  16. pascal

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

    С нами с:
    22 апр 2006
    Сообщения:
    42
    Симпатии:
    0
    Адрес:
    Москва
    Спасибо всем огромное! :)))))) Буду разбираться!
     
  17. Andrey5555

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

    С нами с:
    29 ноя 2007
    Сообщения:
    486
    Симпатии:
    0
    Адрес:
    Киев
    Ну разбирайся, тебе же еще корзину на форуме мутить и регу))
     
  18. SashaSH

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

    С нами с:
    2 фев 2008
    Сообщения:
    4
    Симпатии:
    0
    здравстувуйте, очень полезный код, спасибо. попробовал разобраться и немного конечно же не понял:
    вот момент:

    $HashOfFile=htmlspecialchars($_GET['file']);
    $_file=DIRECTORY.'/FILES/'.$HashOfFile;

    а именно: $_GET['file'], от куда взять файл методом GEТ, из формы передать, зачем?

    как мне выкрутиться, вот у меня есть только файл в папке "DIRECTORY.'/FILES/track.mp3" и его имя в базе, можно избежать htmlspecialchars($_GET['file'])?
     
  19. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    А не проще ли передавать файлы через специальный протокол - фтп?
     
  20. SashaSH

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

    С нами с:
    2 фев 2008
    Сообщения:
    4
    Симпатии:
    0
    может и проще, но так возможностей больше
     
  21. SashaSH

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

    С нами с:
    2 фев 2008
    Сообщения:
    4
    Симпатии:
    0
    с предыдущим вопросом разобрался, возник новый, это вообще точно работает?
    у меня выдает файл 0 размером, вот логи:

    Start at - 0.16544600 1202055699 ID[]
    03.02.08 21:21:37(0.000337) - 127.0.0.1 - SID:8e540b7baa8ee79f00135817d3a528f5 - ID[] - file(z:\home\site.ru\www/mp3/track.mp3) - Request without Part >>
    03.02.08 21:21:37(0.274751) - 127.0.0.1 - SID:8e540b7baa8ee79f00135817d3a528f5 - ID[] - file(z:\home\site.ru\www/mp3/track.mp3) - shutdown function started
    03.02.08 21:21:37(0.275978) - 127.0.0.1 - SID:8e540b7baa8ee79f00135817d3a528f5 - ID[] - file(z:\home\site.ru\www/mp3/track.mp3) - Loaded Segmen [0]=>0
    03.02.08 21:21:37(0.279303) - 127.0.0.1 - SID:8e540b7baa8ee79f00135817d3a528f5 - ID[] - file(z:\home\site.ru\www/mp3/track.mp3) - End Script: 0 < total size: 17086464
    03.02.08 21:21:37(0.279354) - 127.0.0.1 - SID:8e540b7baa8ee79f00135817d3a528f5 - ID[] - file(z:\home\site.ru\www/mp3/track.mp3) - valid connection shutdown

    помогите
     
  22. nimistar

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

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    SashaSH - слеши тебя ненапрягли ? ("file(z:\home\site.ru\www/mp3/track.mp3)")

    я тока что проверил .. все работает!

    тока на 67 строке:
    Код (Text):
    1. if(file_exists($file_segment)
    надо заменить на:
    Код (Text):
    1. if(file_exists($file_segment))
    скобочка потерялася
    --------------------------------
    Мы в ответе за тех кого приручили
     
  23. SashaSH

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

    С нами с:
    2 фев 2008
    Сообщения:
    4
    Симпатии:
    0
    аха, это пройденно, дело в ф-ии file_get_contents()

    Список изменений


    Версия Описание
    5.0.0 Добавлена поддержка контекста.
    5.1.0 Добавлены аргументы offset и maxlen.