13

これが私のコードです:

$language = $_GET['soundtype'];
$word = $_GET['sound'];
$word = urlencode($word);
if ($language == 'english') {
    $url = "<the first url>";
} else if ($language == 'chinese') {
    $url = "<the second url>";
}
$opts = array(
  'http'=>array(
    'method'=>"GET",
    'header'=>"User-Agent: <my user agent>"
  )
);
$context = stream_context_create($opts);
$page = file_get_contents($url, false, $context);
header('Content-Type: audio/mpeg');
echo $page;

しかし、これは非常に遅いことがわかりました。

最適化の可能な方法はありますか?

注: $urlはリモートURLです。

4

3 に答える 3

9

file_get_contents()ファイル全体をに読み込むため、処理が遅くなり$pageます。PHPは、ファイルが受信されるのを待ってからコンテンツを出力します。つまり、サーバー側でファイル全体をダウンロードし、それを単一の巨大な文字列として出力するということです。

file_get_contents()リモートファイルのストリーミングまたはグラブオフセットはサポートされていません。オプションとして、でrawソケットを作成fsockopen()し、HTTPリクエストを実行し、ループでレスポンスを読み取ります。各チャンクを読み取り、ブラウザに出力します。ファイルがストリーミングされるため、これはより高速になります。

マニュアルの例:

$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {

    header('Content-Type: audio/mpeg');

    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: www.example.com\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}

上記は、利用可能なコンテンツがまだある間ループしています。各反復で128バイトを読み取り、ブラウザに出力します。同じ原則があなたがしていることに有効です。生のリクエストを実行しているため、ヘッダーが含まれた生の応答を取得するため、最初の数行になる応答HTTPヘッダーを出力しないようにする必要があります。応答ヘッダーを出力すると、ファイルが破損することになります。

于 2012-12-03T09:09:26.100 に答える
2

@MrCodeで説明されているように、最初にファイルをサーバーにダウンロードしてからクライアントに渡すと、もちろんダウンロード時間が2倍になります。ファイルをクライアントに直接渡す場合は、を使用しますreadfile

または、クライアントがソースから直接ファイルを取得できるように、を使用してクライアントをファイルURLにリダイレクトできないかどうかを検討してください。header("Location: $url")

于 2012-12-03T09:17:41.937 に答える
2

出力する前にファイル全体をダウンロードする代わりに、次のようにストリーミングすることを検討してください。

$in = fopen($url, 'rb', false, $context);
$out = fopen('php://output', 'wb');

header('Content-Type: video/mpeg');
stream_copy_to_stream($in, $out);

大胆な場合は、試すこともできます(ただし、これは間違いなく実験的なものです)。

header('Content-Type: video/mpeg');
copy($url, 'php://output');

もう1つのオプションは、内部リダイレクトを使用して、Webサーバープロキシをリクエストにすることです。これにより、PHPは他のことをするために解放されます。X-Sendfileとその友達に関する私の投稿も参照してください。

于 2012-12-03T09:19:22.120 に答える