Настройка apache для обслуживания PHP при запросе файла MP3 - PullRequest
10 голосов
/ 04 октября 2009

Я работаю над способом обслуживания файлов MP3 через PHP, и после некоторой помощи из массива я получил его на работу здесь

Однако этот пример не работает, когда я использую его в качестве источника в аудиотеге, подобном этому

<html>
    <head>
        <title>Audio Tag Experiment</title>
    </head>
    <body>

    <audio id='audio-element' src="music/mp3.php" autoplay controls>
    Your browser does not support the audio element.
    </audio>

    </body>
</html>

а вот и PHP

<?php

$track = "lilly.mp3";

if(file_exists($track))
{
header("Content-Transfer-Encoding: binary"); 
header("Content-Type: audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3");
header('Content-length: ' . filesize($track));
header('Content-Disposition: filename="lilly.mp3"');
header('X-Pad: avoid browser bug');
Header('Cache-Control: no-cache');

readfile($track);
}else{
    echo "no file";
}

Так что я думаю (и это может быть очень плохой идеей, скажете вы), что я мог бы настроить Apache для обслуживания файла PHP, когда кто-то запрашивает .MP3.

Итак, у меня три вопроса

  1. Будет ли это работать
  2. Хорошая идея / плохая идея?
  3. Что мне нужно сделать? Поместит ли это «AddType application / x-httpd-php .mp3» в httpd conf?

Ответы [ 4 ]

17 голосов
/ 04 октября 2009

В вашем коде есть ошибки:

  • Ресурс может иметь только одно значение Content-Type . Таким образом, вы должны решить, какой тип носителя вы хотите использовать. Я предлагаю audio/mpeg.
  • Вы забыли указать расположение в Content-Disposition . Если вы просто хотите указать имя файла и не хотите менять расположение, используйте значение по умолчанию inline.

Остальное выглядит хорошо. Но я бы также отправил код состояния 404. Если файл не найден.

$track = "lilly.mp3";

if (file_exists($track)) {
    header("Content-Type: audio/mpeg");
    header('Content-Length: ' . filesize($track));
    header('Content-Disposition: inline; filename="lilly.mp3"');
    header('X-Pad: avoid browser bug');
    header('Cache-Control: no-cache');
    readfile($track);
    exit;
} else {
    header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found', true, 404);
    echo "no file";
}
4 голосов
/ 04 октября 2009

Вы можете просто сделать так, чтобы у вас было правило mod_rewrite для запуска каждого запроса музыки / *. Mp3 через ваш файл mp3.php.

Например, что-то вроде этого

RewriteEngine on
RewriteRule ^/music/(.*\.mp3)    /music/mp3.php?file=$1 [L]

mp3.php может затем взять запрошенный файл из $ _GET ['file'], но если вы используете этот подход, я рекомендую вам проверить правильность имени файла, чтобы убедиться, что он ссылается только на файл в нужном каталоге.

//ensure filename just uses alphanumerics and underscore
if (preg_match('/^[a-z0-9_]+\.mp3$/i', $_GET['file']))
{
    //check file exists and serve it

    $track=$_SERVER['DOCUMENT_ROOT'].'/music/'.$_GET['file'];
    if(file_exists($track))
    {
        header("Content-Type: audio/mpeg");
        header('Content-length: ' . filesize($track));
        //insert any other required headers...

        //send data
        readfile($track);
    }
    else
    {
        //filename OK, but just not here
        header("HTTP/1.0 404 Not Found");
    }

}
else
{
    //bad request
    header("HTTP/1.0 400 Forbidden");
}
2 голосов
/ 04 октября 2009

Используйте заголовочный x-sendfile вместо readfile для лучшей производительности.

http://john.guen.in/past/2007/4/17/send_files_faster_with_xsendfile/

0 голосов
/ 06 октября 2009

Это работает для меня (в .htaccess):

<FilesMatch "mp3$">
    SetHandler application/x-httpd-php5
</FilesMatch>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...