无法使用 PHP 将远程 mp3 文件下载到服务器

Unable to download remote mp3 file to server using PHP

我正在尝试使用服务器端 PHP 将发音文件(大约 8kb)下载到服务器。从许多讨论这个问题的线程中得到提示,我尝试了以下方法:

$numwrd = str_word_count($wrd);
    if($numwrd == 1){
        $html = file_get_html("http://www.dictionaryapi.com/api/v1/references/spanish/xml/" . rawurlencode($wrd) . "?key=" . rawurlencode('6d4d41f9-c28f-4544-9bb3-1b4708d1a4d1'));
        $sn = $html->find('sound');
        if($sn[0] != ""){
            $foldername = findsub($sn[0]->plaintext);
            $filename = explode(".", $sn[0], 2)[0];
            $audiofn = $foldername . $filename . '.mp3';
            $soundurl = 'http://media.merriam-webster.com/audio/prons/es/me/mp3/' . $foldername . '/' . $filename . '.mp3';
            $path = 'amit.mp3';
            $headers = getHeaders($soundurl);
            if ($headers['http_code'] === 200 and $headers['download_content_length'] < 1024*1024) {
              if (download($url, $path)){
                return $audiofn . " " . $soundurl; 
              }
            }
        }
        else { return "not found"; }
    }
    else { return "not found"; }
function getHeaders($url)
{
  $ch = curl_init($url);
  curl_setopt( $ch, CURLOPT_NOBODY, true );
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );
  curl_setopt( $ch, CURLOPT_HEADER, false );
  curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 3 );
  curl_exec( $ch );
  $headers = curl_getinfo( $ch );
  curl_close( $ch );

  return $headers;
}
function download($url, $path)
{
  # open file to write
  $fp = fopen ($path, 'w+');
  # start curl
  $ch = curl_init();
  curl_setopt( $ch, CURLOPT_URL, $url );
  # set return transfer to false
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );
  curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true );
  curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
  # increase timeout to download big file
  curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 10 );
  # write data to local file
  curl_setopt( $ch, CURLOPT_FILE, $fp );
  # execute curl
  curl_exec( $ch );
  # close curl
  curl_close( $ch );
  # close local file
  fclose( $fp );

  if (filesize($path) > 0) return true;
}

这没有用,所以我用 file_get_contents 再次尝试。但是,此方法仅创建文件但字节数为零。 $foldername$filename$audiofn$soundurl 中的值正在正确评估并且所有这些变量都已经过测试。我可以通过浏览到 URL、右键单击浏览器并单击 download file as... 来手动下载文件。是什么破坏了我的 PHP?

P.S.: 我刚刚尝试使用 cURL 修改函数,但也失败了:

function down($url, $target){//feeding it $soundurl and $path values
    set_time_limit(0);
    $file = fopen(dirname(__FILE__) . $target, 'w+');
    $curl = curl_init($url);
    curl_setopt_array($curl, [
        CURLOPT_URL            => $url,
        CURLOPT_BINARYTRANSFER => 1,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_FILE           => $file,
        CURLOPT_TIMEOUT        => 50,
        CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
    ]);
    $response = curl_exec($curl);

    if($response === false) {
        throw new \Exception('Curl error: ' . curl_error($curl));
    }
    $response;
}

终于成功了!这是修复它的方法(第 7 行):

$filename = explode(".", $sn[0]->plaintext, 2)[0];

我必须添加 ->plaintext 属性的原因是没有它,返回到 $filename 的值是一个xml 标签而不是该标签内的文本。由于以下代码行将此值作为输入,这破坏了正在调用下载的 URL:

$soundurl = 'http://media.merriam-webster.com/audio/prons/es/me/mp3/' . $foldername . '/' . $filename . '.mp3';

现在文件下载成功,因为 URL 格式正确。