URL包含长破折号(–)时,通过file_get_contents下载MP3

时间:2018-07-25 17:19:46

标签: php

我正在尝试将一组MP3文件下载到ZIP文件夹中。所有MP3都托管在S3上。我的程序运行正常,除非URL包含如下所示的长破折号:https://s3.amazonaws.com/publicverses/2Corinthians11verse24–33_user400_56.mp3

请注意,2433之间的长划线。此文件和其他类似文件显示在ZIP空文件中(即0kb)。我该如何解决?

foreach ($files as $file) {
      $download_file = file_get_contents($file);
      $zip->addFromString(basename($file), $download_file);
  }

2 个答案:

答案 0 :(得分:1)

如果文件名包含任何高阶字符(例如此Unicode破折号),则需要urlencode()文件名或路径的任何部分。作为记录,为了方便用户,Web浏览器在后台执行此操作。

在构建URL之前,最简单的方法是 ,但是,如果您遇到这样的问题而陷入了预先形成的URL中,那么您需要将其拆开并仅处理您需要更改的部分。例如:

// from: http://php.net/manual/en/function.parse-url.php#106731
function unparse_url($parsed_url) {
  $scheme   = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
  $host     = isset($parsed_url['host']) ? $parsed_url['host'] : '';
  $port     = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
  $user     = isset($parsed_url['user']) ? $parsed_url['user'] : '';
  $pass     = isset($parsed_url['pass']) ? ':' . $parsed_url['pass']  : '';
  $pass     = ($user || $pass) ? "$pass@" : '';
  $path     = isset($parsed_url['path']) ? $parsed_url['path'] : '';
  $query    = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
  $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
  return "$scheme$user$pass$host$port$path$query$fragment";
}

// this function assumes that *nothing* is encoded, otherwise it will
// double-encode the data and likely break it.
function url_encode_parts($url) {
    $parts = parse_url($url);
    // eg: UTF hostnames are encoded differently
    $parts['host'] = idn_to_ascii($parts['host']);
    $parts['path'] = implode('/', array_map('urlencode', explode('/', $parts['path'])));
    return unparse_url($parts);
}

$url = 'https://s3.amazonaws.com/publicverses/2Corinthians11verse24–33_user400_56.mp3';

var_dump(url_encode_parts($url));

// output:
// string(85) "https://s3.amazonaws.com/publicverses/2Corinthians11verse24%E2%80%9333_user400_56.mp3"

参考:

答案 1 :(得分:0)

感谢大家的建议。在这种情况下,我发现最简单的解决方案是更新程序,以便在URL结构中将所有长破折号()转换为常规破折号(-)。换句话说,我决定完全避免使用特殊字符,而不是处理编码问题。