PHP — Проверьте, действителен ли URL-адрес или нет

#php #url #curl #status

Вопрос:

Я проверяю url и возвращаю «действительный«, если код статуса URL «200» и «недействительный«, если он на «404«.,

URL-адреса-это ссылки, которые перенаправляют на определенную страницу (URL), и мне нужно проверить статус этой страницы (URL), чтобы определить, является ли она действительной или недействительной на основе ее кода статуса.

 <?php

// From URL to get redirected URL
$url = 'https://www.shareasale.com/m-pr.cfm?merchantID=83483amp;userID=1860618amp;productID=916465625';
  
// Initialize a CURL session.
$ch = curl_init();
  
// Grab URL and pass it to the variable.
curl_setopt($ch, CURLOPT_URL, $url);
  
// Catch output (do NOT print!)
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  
// Return follow location true
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
$html = curl_exec($ch);
  
// Getinfo or redirected URL from effective URL
$redirectedUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
  
// Close handle
curl_close($ch);
echo "Original URL:   " . $url . "<br/> </br>";
echo "Redirected URL: " . $redirectedUrl . "<br/>";

 function is_url_valid($url) {
  $handle = curl_init($url);
  curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($handle, CURLOPT_NOBODY, true);
  curl_exec($handle);
 
  $httpCode = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE));
  curl_close($handle);
 
  if ($httpCode == 200) {
    return 'valid link';
  }
  else {
    return 'invalid link';
  }
}

// 
echo "<br/>".is_url_valid($redirectedUrl)."<br/>";
 

Как вы можете видеть, приведенная выше ссылка имеет статус 400, но по-прежнему показывает «действительна».
Я использую приведенный выше код, какие-либо мысли или исправления ? для того, чтобы все работало так, как ожидалось ?
Похоже, что на сайте есть более одного перенаправленного URL-адреса, и скрипт проверяет только один, поэтому он отображается корректным.
есть какие-нибудь мысли, как это исправить ?

Вот ссылки, которые я проверяю

вопрос —

НАПРИМЕР — Если я проверю по этой ссылке https://www.shareasale.com/m-pr.cfm?merchantID=66802amp;userID=1860618amp;productID=1186005518 затем в браузере он переходит на «404», но в скрипте o/p его «200»

Комментарии:

1. Приведенная выше ссылка имеет код статуса: 302 и перенаправлена на новый URL с кодом статуса 200, я хочу проверить конечный URL (последний URL).

2. $httpCode = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE)); — просто на всякий случай убедитесь, что это целое число для вашего сравнения

3. Спасибо за комментарий и предложение, хотя я получаю 404 в качестве кода состояния в выводе

4. @devhs — Я не уверен, является ли это правильным решением или нет. Но я проверил некоторые из приведенных выше ссылок, они управляют пользовательской страницей для 404. В качестве быстрого решения вы можете получить содержимое URL-адреса с помощью «file_get_contents» и проверить «Заголовок страницы».

5. Под заголовком «Обновить» я имею header("Refresh:5; url=page2.php"); в виду, что в данном случае curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); не следует перенаправлениям, другим является заголовок http-equiv обновления мета и перенаправления javascript

Ответ №1:

Примечание: Мы использовали CURLOPT_NOBODY только для проверки соединения, а не для извлечения всего тела.

   $url = "Your URL";
  $curl = curl_init($url);
  curl_setopt($curl, CURLOPT_NOBODY, true);
  $result = curl_exec($curl);
 if ($result !== false)
 {
    $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);  
 if ($statusCode == 404)
 {
   echo "URL Not Exists"
 }
 else
 {
   echo "URL Exists";
  }
 }
else
{
  echo "URL not Exists";
}
 

Ответ №2:

Для этого я использую функцию get_headers (). Если я нашел статус 2xx в массиве, то URL-адрес в порядке.

 function urlExists($url){
  $headers = @get_headers($url);
  if($headers === false) return false;
  return preg_grep('~^HTTP/d .d s 2d{2}~',$headers) ? true : false;
}
 

Комментарии:

1. Спасибо за ответ, но что, если основной URL-адрес содержит перенаправления (несколько перенаправлений) ? Предположим, что этот URL — адрес- shareasale.com/…

2. Функция возвращает значение true для этого URL-адреса. Это нормально?

3. Нет, это не так, так как код статуса страницы 404 (не найден), поэтому он не должен возвращать значение true

4. Я не получаю рекламу, если Javascript отключен в моем браузере. Я думаю, что эта пересылка выполняется с помощью javascript. Эта проблема не может быть решена только с помощью PHP.

5. У меня нет быстрого решения.

Ответ №3:

Это мой взгляд на этот вопрос. По сути, еда на вынос-это:

  1. Вам не нужно было делать больше одного запроса. Использование CURLOPT_FOLLOWLOCATION сделает всю работу за вас, и, в конце концов, код ответа http, который вы получите, является кодом последнего вызова в случае/некоторых перенаправлений.
  2. Поскольку вы используете CURLOPT_NOBODY , запрос будет использовать HEAD метод и ничего не вернет. По этой причине CURLOPT_RETURNTRANSFER бесполезно.
  3. Я взял на себя смелость использовать свой собственный стиль кодирования (без обид).
  4. Поскольку я запускал код из файла с нуля Phpstorm, я добавил несколько PHP_EOL в качестве разрывов строк для форматирования выходных данных. Не стесняйтесь их удалять.


 

 <?php

$linksToCheck = [
    'https://click.linksynergy.com/link?id=GsILx6E5APMamp;offerid=547531.5112amp;type=15amp;murl=https://www.peopletree.co.uk/women/dresses/anna-checked-dress',
    'https://click.linksynergy.com/link?id=GsILx6E5APMamp;offerid=330522.2335amp;type=15amp;murl=https://www.wearethought.com/agnetha-black-floral-print-bamboo-dress-midnight-navy/#92=1390&142=198',
    'https://click.linksynergy.com/link?id=GsILx6E5APMamp;offerid=330522.752amp;type=15amp;murl=https://www.wearethought.com/bernice-floral-tunic-dress/#92=1273&142=198',
    'https://click.linksynergy.com/link?id=GsILx6E5APMamp;offerid=330522.6863amp;type=15amp;murl=https://www.wearethought.com/josefa-smock-shift-dress-in-midnight-navy-hemp/#92=1390&142=208',
    'https://www.shareasale.com/m-pr.cfm?merchantID=16570amp;userID=1860618amp;productID=546729471',
    'https://www.shareasale.com/m-pr.cfm?merchantID=53661amp;userID=1860618amp;productID=680698793',
    'https://www.shareasale.com/m-pr.cfm?merchantID=66802amp;userID=1860618amp;productID=1186005518',
    'https://www.shareasale.com/m-pr.cfm?merchantID=83483amp;userID=1860618amp;productID=916465625',
];

function isValidUrl($url) {
    echo "Original URL:   " . $url . "<br/>n";

    $handle = curl_init($url);

    // Follow any redirection.
    curl_setopt($handle, CURLOPT_FOLLOWLOCATION, TRUE);

    // Use a HEAD request and do not return a body.
    curl_setopt($handle, CURLOPT_NOBODY, true);

    // Execute the request.
    curl_exec($handle);

    // Get the effective URL.
    $effectiveUrl = curl_getinfo($handle, CURLINFO_EFFECTIVE_URL);
    echo "Effective URL:   " . $effectiveUrl . "<br/> </br>";

    $httpResponseCode = (int) curl_getinfo($handle, CURLINFO_HTTP_CODE);

    // Close this request.
    curl_close($handle);

    if ($httpResponseCode == 200) {
        return '✅';
    }
    else {
        return '❌';
    }
}

foreach ($linksToCheck as $linkToCheck) {
    echo PHP_EOL . "Result: " . isValidUrl($linkToCheck) . PHP_EOL . PHP_EOL;
}
 

Комментарии:

1. ха-ха, классное использование utf8! к сожалению, я также хочу следить за перенаправлениями javascript , см. Мой ответ ниже для получения дополнительной информации 🙁

Ответ №4:

Приведенный ниже код работает хорошо, но когда я помещаю URL-адреса в массив и тестирую ту же функциональность, это не дает должных результатов ? Есть какие-нибудь мысли, почему ? Также, если какой-либо орган хотел бы обновить ответ, чтобы сделать его динамичным в этом смысле (следует проверять несколько URL-адресов одновременно, если указан массив URL-адресов).

   <?php
    
    // URL to check
    $url = 'https://www.shareasale.com/m-pr.cfm?merchantID=66802amp;userID=1860618amp;productID=1186005518';
      
    $ch = curl_init(); // Initialize a CURL session.
    curl_setopt($ch, CURLOPT_URL, $url); // Grab URL and pass it to the variable.
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // Catch output (do NOT print!)
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); // Return follow location true
    $html = curl_exec($ch);
    $redirectedUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); // Getinfo or redirected URL from effective URL
    curl_close($ch); // Close handle
    
    $get_final_url = get_final_url($redirectedUrl);
    if($get_final_url){
        echo is_url_valid($get_final_url);
    }else{
        echo $redirectedUrl ? is_url_valid($redirectedUrl) : is_url_valid($url);
    }
    
    function is_url_valid($url) {
      $handle = curl_init($url);
      curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($handle, CURLOPT_NOBODY, true);
      curl_exec($handle);
     
      $httpCode = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE));
      curl_close($handle);
      echo $httpCode;
      if ($httpCode == 200) {
        return '<b> Valid link </b>';
      }
      else {
        return '<b> Invalid link </b>';
      }
    }
    
    function get_final_url($url) {
            $ch = curl_init();
            if (!$ch) {
                return false;
            }
            $ret = curl_setopt($ch, CURLOPT_URL,            $url);
            $ret = curl_setopt($ch, CURLOPT_HEADER,         1);
            $ret = curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            $ret = curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            $ret = curl_setopt($ch, CURLOPT_TIMEOUT,        30);
            $ret = curl_exec($ch);
    
            if (!empty($ret)) {
                $info = curl_getinfo($ch);
                curl_close($ch);
                return false;
            if (empty($info['http_code'])) {
                return false;
            } else {
                preg_match('#(https:.*?)')#', $ret, $match);
                $final_url = stripslashes($match[1]);
                return stripslashes($match[1]);
            }
        }
    } 
 

Комментарии:

1. просто идея: запросы из вашего сценария поступают по шаблону, который хост обнаруживает, а затем противодействует вашим намерениям. или, как вы, возможно, выразились бы: почему этот хозяин подрывает мои ожидания? это их сервер, вы можете только отправлять запросы, и вы должны жить с ответом (ответом) 😉

Ответ №5:

видите ли, проблема здесь в том, что вы хотите следовать перенаправлениям JAVASCRIPT , URL-адрес, на который вы жалуетесь https://www.shareasale.com/m-pr.cfm?merchantID=66802amp;userID=1860618amp;productID=1186005518 , перенаправляет на отвечающий URL HTTP 200 OK -адрес, и эта страница содержит javascript

 <script LANGUAGE="JavaScript1.2">
                window.location.replace('https://www.tenthousandvillages.com/bicycle-statue?sscid=71k5_4yt9r ')
                </script>
 

таким образом, ваш браузер, который понимает javascript, следует перенаправлению javascript, и это перенаправление js на страницу 404.. к сожалению, хорошего способа сделать это с помощью PHP нет, вашим лучшим выбором, вероятно, был бы веб-браузер без головы, например PhantomJS, кукловод или Селен или что-то в этом роде.

тем не менее, вы можете как бы взломать регулярное выражение-поиск перенаправления javascript и надеяться на лучшее, например

 <?php
function is_url_valid(string $url):bool{
    if(0!==strncasecmp($url,"http",strlen("http"))){
        // file:///etc/passwd and stuff like that aren't considered valid urls right?
        return false;
    }
    $ch=curl_init();
    if(!curl_setopt_array($ch,array(
        CURLOPT_URL=>$url,
        CURLOPT_FOLLOWLOCATION=>1,
        CURLOPT_RETURNTRANSFER=>1
    ))){
        // best guess: the url is so malformed that even CURLOPT_URL didn't accept it.
        return false;
    }
    $resp= curl_exec($ch);
    if(false===$resp){
        return false;
    }
    if(curl_getinfo($ch,CURLINFO_RESPONSE_CODE) != 200){
        // only HTTP 200 OK is accepted
        return false;
    }
    // attempt to detect javascript redirects... sigh
    // window.location.replace('https://www.tenthousandvillages.com/bicycle-statue?sscid=71k5_4yt9r ')
    $rex = '/location.replaces*(s*(?<redirect>(?:'|")[sS]*?(?:'|"))/';
    if(!preg_match($rex, $resp, $matches)){
        // no javascript redirects detected..
        return true;
    }else{
        // javascript redirect detected..
        $url = trim($matches["redirect"]);
        // javascript allows both ' and " for strings, but json only allows " for strings
        $url = str_replace("'",'"',$url);
        $url = json_decode($url, true,512,JSON_THROW_ON_ERROR); // we extracted it from javascript, need json decoding.. (well, strictly speaking, it needs javascript decoding, but json decoding is probably sufficient, and we only have a json decoder nearby)
        curl_close($ch);
        return is_url_valid($url);
    }
}
var_dump(

    is_url_valid('https://www.shareasale.com/m-pr.cfm?merchantID=66802amp;userID=1860618amp;productID=1186005518'),
    is_url_valid('http://example.org'),
    is_url_valid('http://example12k34jr43r5ehjegeesfmwefdc.org'),
    
);
 

но это, мягко говоря, хитрое банальное решение..

Комментарии:

1. Спасибо за ответ, позвольте мне проверить, будет ли он работать с несколькими URL-адресами одновременно, например, если я создам массив URL-адресов, опубликованных в методе вопросов и вызовов «is_url_valid» в цикле

2. @devhs не должно быть проблемой, кстати, я только что заметил, что у этого подхода есть еще одна существенная слабость: он не обрабатывает бесконечные перенаправления. например , если страница 1 перенаправляет на страницу 2, перенаправляет на страницу 1, перенаправляет на страницу 2…., этот скрипт будет просто следовать перенаправлениям вечно, пока не будет достигнуто время php max_execution_time или пока стек вызовов не будет исчерпан. (хотя это можно исправить)

3. Спасибо, я проверю это, я только что проверил это здесь — paiza.io/projects/N3m4E11HZAmq5uTb8gLjcg но ii, похоже, не работает.

4. @devhs этот url возвращает bool(true) для меня , если обязательно измените его на paiza.io https://paiza.io , что вы получите?

5. Когда вы переходите по этой ссылке, это компилятор, в котором я проверил ваш код paiza.io/projects/N3m4E11HZAmq5uTb8gLjcg