file_get_contents и url без протокола

152
17 декабря 2018, 07:30

На вход file_get_contents подается урл на файл без протокола. Например //example.com/file.txt. Но он не хочет жрать такой урл и возвращает false. Можно ли что-то с этим сделать? Может тогда есть какая-то функция которая обработает урл и добавит ему протокол? Я имею ввиду не просто 'http:' + $url, а наилучший протокол - как это делает браузер. Если есть https - то пусть будет https, если нет то http. Ведь именно поэтому у урла и убран протокол...

P.S. Правда заранее не известно будет подан урл или реальный путь...

Answer 1

//example.com/file.txt - это не "выбор наилучшего протокола". Это protocol relative url.

Protocol Relative означает "тот же протокол, что у текущей страницы".

Простая аналогия - просто relative url вида /file.txt означает "тот же протокол, хост и порт, что у текущей страницы". Нельзя отдать file_get_contents ссылку вида /file.txt и ожидать, что метод сам угадает наилучший хост.

То же самое с Protocol Relative - нельзя отдать //example.com/file.txtи ожидать что file_get_contents угадает протокол.

Answer 2

Если есть https - то пусть будет https, если нет то http.

$str = 'https://example.com/file.txt';
echo get_protocol($str) . "\n"; # https://example.com/file.txt
$str = 'http://example.com/file.txt';
echo get_protocol($str) . "\n"; # http://example.com/file.txt
$str = '//example.com/file.txt';
echo get_protocol($str) . "\n"; # http://example.com/file.txt

function get_protocol($str) {
    if (preg_match('~^//\S+~', $str, $url)) {
        $str = "http:$url[0]";
    }
    return $str;
}
Answer 3

file_get_contents('http:' . $url)

лучше работайте по http, если нет ценной информаций, которую могу воровать по сети

http быстрее https

а ещё лучше используйте curl, либо можете отправить ping сначало по одному протоколу, и после по другому, чтобы узнать какой будет работать можно ещё такую проверку сделать:

$reg_exUrl = "/(?i)\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))/";
if(preg_match($reg_exUrl, $string, $url)) {
        if(strpos( $url[0], ":" ) === false){
            $link = 'https://'.$url[0];
        }else{
            $link = $url[0];
        }
        $res = file_get_contents($link);
}
READ ALSO
Почему не работает цель на кнопке

Почему не работает цель на кнопке

Не работает цель на JavaScript событии Яндекс Метрики Вот код кнопки и вставленная туда цель :

187
Определение границ изображения

Определение границ изображения

Имеется растровое изображение (без фона) некоторого объекта, который загружается в QGraphicsSceneНужно определить его границы как QPainterPath для того,...

146
Целочисленное деление с округлением вверх

Целочисленное деление с округлением вверх

Есть ли оператор целочисленного деления с округлением вверх? Чтобы было так:

141
C++ и API OpenMP переменная среды

C++ и API OpenMP переменная среды

начал изучать параллельное программирование, подключил API OpenMP в проект C++Добавлением кода

142