Народ помогите плиз. Как можно реализовать продажу mp3 на сайте. Т.е. есть каталог mp3. Они как обычные товары кладутся в корзину. Чел заходит в корзину оформляет заказ, оплачивает его, а потом ему генерятся ссылки по которым он может скачивать mp3. 1. Как сделать чтобы чел смог скачать mp3 только один раз. 2. Чтобы кроме него никто не мог скачать эту mp3. Заранее огромное спасибо!
делаешь так чтобы качать могли только зарегистрированные потом при скачке (идёт не прямая ссыль а мудрённая через проверялки) проверячешь по БД если файл такой уже скачал значит больше скачивать его не даст
А что за mp3? Музон на который у тебя нет прав реализации? А с оплатой у тебя проблем нет? Короче, вышли пользователю mp3 на его е-маил и голову не морочь
ты что! Тут у человека скоро вопросы про реализацию регистрации и корзины ещё будут, а ты про прослушивание…
патамушта нада свой бизнес делать! Давненько вы, мистер, не читали самоучители "как сделать бизнес в ентернетах". Они все с чего начинаются? С того, что "нада перестать работать на дядю и самому станавица ночальникам". А дальше объясняется, как песатель, вложив всего ??? рублей (цифры меняются от 100 до 1000), теперь "палучил настаящий стабильный бизнес, приносящий ??????? долларов в день" (цифры меняются от 30 баксов до бесконечности). Бизнес - как правило, либо продажа електронного контента (например, mp3), правда, в 99% самоучителей не уточняется, откуда взять этот контент, либо заманиловка в какую-нить рефералку по продаже такого же дерьма.
вот как раз как реализовать мудреную ссылку на файл через проверялки. У меня идея была такая типа давать ссылку на скрипт, а потом каким то образом если все норм выдавать бинарный поток. Возможно ли это и если да то как?
pascal как реализовать мудреную ссылку обсуждалось тут на моей памяти не один раз воспользуйся поиском. найдешь и теорию и практические реализации додумать проверку надеюсь сможешь сам
Как в случае когда все правильно выдавать пользователю бинарный поток чтобы браузер воспринял его как файл и пользователь мог скачать этот файл?
pascal - Если идут подобные вопросы, то очень стоит задуматся - "может сделать сначала ЛИЧНЫЙ фотоальбом", после експерементов с работой над картинками вопросы обинарниках отвалятся сами! Выдача файла, ещё не самый сложный вопрос который возникнет на данном пути, например безопасность мп3 магазина должна быть на порядок выше чем магазана торгующего бытовой техникой или книгами (и HTTPS - не всегда решение), Оплата тоже намаленькая и простая задача ... собственно ответ на сам вопрос как выдать фаил : (скрипт для теста технологии фрагментарного лоадера) PHP: <?php ignore_user_abort(true); // чтобы могли адекватно обработать порванный коннект error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING ); $uniqID=uniqid(); // уникальный идентификатор текущего запуска скрипта header('Cache-Control: no-cache'); $timeStart=microtime(); $LOGS='';$LOGS.="Start at - ".$timeStart." ID[".$uniqID."] \r\n"; ini_set("session.use_trans_sid",true); ini_set("session.use_only_cookies",false); session_name('sid'); session_start(); //Стартуем сессию дабы определить что именно этот клиент скачал именно этот фаил! set_time_limit(0); // Определение констант define('SEGMENT',1024); // размер стандартного сегмента define('TIME_DELAY',1000); // задержка обработки для понижения скорости (1 сек = 1 000 000 микросекунд) define('DIRECTORY',getcwd()); // текущая дериктория define('SESSION_SID',session_id()); // чтобы можно было закрыть сессию $mime_type='application/octet-stream';// универсальный тип для посылаемых данных ... всегда будет запрос на сохранение файлов, а не передача предустановленному обработчику // Определение переменных $NoErrors=true; $HashOfFile=htmlspecialchars($_GET['file']); $_file=DIRECTORY.'/FILES/'.$HashOfFile; session_write_close(); // <-- ОБЯЗАТЕЛЬНО иначе повторные потоки нестартуют для данного пользователя! (искал 3 месяца) 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;} function CountSegments($fileofsegment){ // Подсчет размера отданной информации по сегментам $F=@fopen($fileofsegment,"r") or error_log('can\'t open log file of segments', 0); if($F===false){error_log('can\'t read file of segments - '.$fileofsegment, 0);return 0;} $R=array(); while(!feof($F)){ $t=explode("\t",fgets($F, 4096)); if(isset($t[1])){ $R[$t[0]]=((@(int)$R[$t[0]] < (int)$t[1]) ? $t[1] : $R[$t[0]]); } } fclose($F); ksort($R); $LastS=0;$LastL=0;$totalSize=0; foreach($R as $S => $length){ if(($LastS+$LastL) < ($S+$length)){ if(($LastS+$LastL) > $S){ $totalSize+=$length - $LastS - $LastL + $S; }else{ $totalSize+=$length; } $LastS=$S; $LastL=$length; } } return $totalSize; } function write_to($mess) { // Логирование данных global $_file,$_SERVER,$uniqID,$timeStart,$LOGS; $LOGS.=date("d.m.y H:i:s").'('.(microtime()-$timeStart).') - '.$_SERVER['REMOTE_ADDR'].' - SID:'.SESSION_SID.' - ID['.$uniqID.'] - file('.$_file.') - '.$mess."\r\n"; } function shdn(){ // функция выполняемая по окончанию выброса сигмента global $_file,$filesize,$_SERVER,$NoErrors,$LengthSend,$rlow,$HashOfFile,$LOGS,$RootDir; write_to("shutdown function started"); $file_segment=DIRECTORY.'/logs/'.SESSION_SID.".".$HashOfFile.".segment"; if(file_exists($file_segment)while(!is_writable($file_segment)){usleep(100);} $FH=fopen($file_segment,'a') or error_log('can\'t open segment file', 0); if(fwrite($FH,$rlow."\t".$LengthSend."\n")===false){error_log('can\'t write segment file', 0);}fclose($FH); $totalLoad=CountSegments(DIRECTORY.'/logs/'.SESSION_SID.".".$HashOfFile.".segment"); // Считаем все сигменты сегмент - для накопления! write_to("Loaded Segmen [".$rlow."]=>".$LengthSend); write_to("End Script: ".$totalLoad." ".(($totalLoad>=filesize($_file)) ? ">=" : "<")." total size: ".filesize($_file)); if((connection_aborted())||(connection_status()==2)){ write_to("connection ".(connection_aborted() ? "aborted" : (connection_status()==2 ? "connection_timeout" : "???"))); } else { write_to("valid connection shutdown"); if($totalLoad >= filesize($_file)){write_to("DOWNLOAD COMPLITE");} } // записываем лог 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);} // ждем пока освободится фаил $FH=fopen(DIRECTORY.'/logs/downloaded_count-'.date("d_m_Y").'.txt','a') or error_log('can\'t open log file', 0); if(fwrite($FH,$LOGS)===false){error_log('can\'t write log file', 0);}fclose($FH); } // обработка запрашиваемого заголовка на предмет фрагментарности if($_SERVER['REQUEST_METHOD']==='HEAD'){ // при запросе только заголовка расчитываем размеры .. но не передаем фаил (даже не пытаемся) $onlyHead = true;$rhigh = 0;$rlow = 0; }else{ $onlyHead = false; if (isset($_SERVER['HTTP_RANGE'])){ // если запрос фрагмента preg_match_all('/bytes=([0-9]*)-([0-9]*)/',$_SERVER['HTTP_RANGE'],$out); $rlow=$out[1][0]; $rhigh=$out[2][0]; write_to("Request Part (block:[$rlow]-[$rhigh] ) "); }else{ // простая прямая выдача файла write_to('Request without Part >>'); } if(empty($rlow)){$rlow=0;} } $fileSize=filesize($_file);$LengthSend=0;$STRfilename=trim($_GET['file']); ob_start(); if($onlyHead){ // если от нас хотели только информацию о файле header("Content-Length: $fileSize"); header("Content-Disposition: attachment; filename=\"$STRfilename\""); }else{ // выдача запрошенного фрагмента header("Content-Type: $mime_type"); // формирование заголовков header('Accept-Ranges: bytes'); header('Connection: Keep-Alive'); header("Content-Disposition: attachment; filename=\"$STRfilename\""); if (isset($_SERVER['HTTP_RANGE'])){ // заголовки для фрагмента header('HTTP/1.1 206 Partial Content'); header('Content-Range: bytes '.$rlow.'-'.(!empty($rhigh) ? ($rhigh) : ($fileSize)).'/'.(!empty($rhigh) ? ($rhigh-$rlow) : ($fileSize-$rlow))); header('Content-Length: '.(!empty($rhigh) ? ($rhigh-$rlow) : ($fileSize-$rlow))); }else{ header("Content-Length: $fileSize"); // для прямого выброса } ob_flush(); for($i=$rlow;$i<=(!empty($rhigh) ? $rhigh : $fileSize);$i+=SEGMENT) { if(connection_status()==0){ $OUT=file_get_contents($_file,false,NULL,$i,SEGMENT); echo $OUT; ob_flush(); usleep(TIME_DELAY); if(connection_status()==0){ob_flush();$LengthSend+=strlen($OUT);}else{write_to('status ob: '.ParsArray(ob_get_status(true),'status'));} }else{ write_to('Connection down');break; } } } ob_end_flush(); shdn();// исключительно для ВИНДЫ - в ней несрабатывает зарегестрированная функция по окончанию работы скрипта ( register_shutdown_function) хотя последнее правильней set_time_limit(30); ?> Надеюсь гуру шапками незабросают ;-)
здравстувуйте, очень полезный код, спасибо. попробовал разобраться и немного конечно же не понял: вот момент: $HashOfFile=htmlspecialchars($_GET['file']); $_file=DIRECTORY.'/FILES/'.$HashOfFile; а именно: $_GET['file'], от куда взять файл методом GEТ, из формы передать, зачем? как мне выкрутиться, вот у меня есть только файл в папке "DIRECTORY.'/FILES/track.mp3" и его имя в базе, можно избежать htmlspecialchars($_GET['file'])?
с предыдущим вопросом разобрался, возник новый, это вообще точно работает? у меня выдает файл 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 помогите
SashaSH - слеши тебя ненапрягли ? ("file(z:\home\site.ru\www/mp3/track.mp3)") я тока что проверил .. все работает! тока на 67 строке: Код (Text): if(file_exists($file_segment) надо заменить на: Код (Text): if(file_exists($file_segment)) скобочка потерялася -------------------------------- Мы в ответе за тех кого приручили
аха, это пройденно, дело в ф-ии file_get_contents() Список изменений Версия Описание 5.0.0 Добавлена поддержка контекста. 5.1.0 Добавлены аргументы offset и maxlen.