Скачиваем файлы через file_get_contents (file_get_contents, urlencode и .рф домены)

Не секрет, что самым простым способом получить содержимое файл в PHP из сети является функция file_get_contents().

Но те, кто попробовали ее использовать, сталкиваются с двумя насущными проблемами:

  1. Функция отказывается работать, если в адресе есть пробел
  2. Функция отказывается работать с адресами в зоне .рф

Первая проблема решается очень просто, достаточно закодировать эти пробелы функцией urlencode. Но опять же, в лоб закодировать весь url не выйдет, потому что слэши кодировать нельзя. Придется написать отдельную функцию, которая будет разбивать url на части, кодировать, и склеивать закодированные кусочки обратно

Вторая проблема решается сложнее. Думаю, все видели адреса вида xn--d1acufc5f.xn--p1ai. Это есть Punycode, специальный алгоритм кодирования символов не стандартных символов в доменном имени. Браузер умеет это делать автоматически, а вот функция file_get_contents не такая умная, поэтому нам придется делать это за нее. Кстати, в php нет инструментов кодирования в этот самый Punycode, потому вам придется скачать специальный класс. Мне лично подошел https://github.com/true/php-punycode

А теперь финальный вариант нашей функции:

/**
* Кодировать url для file_get_contents
* @param $url
* @return string
*/
function file_url($url){
$parts = parse_url($url);
$path_parts = array_map('rawurldecode', explode('/', $parts['path']));
$puny = new Punycode();
return
$parts['scheme'] . '://' .
$puny->encode($parts['host']) .
implode('/', array_map('rawurlencode', $path_parts))
;
}

Не забудьте подключить класс с помощью require или в вашем autoloader’e. В классе используется namespace, но я его удалил, потому у меня просто Punycode вместо TrueBV\Punycode

Оставить комментарий