PHP: Обнаружение и исправление исходящих ссылок в HTML

Мне нужна функция, которая исправляет ВСЕ исходящие ссылки в заданном HTML-тексте и добавляет к ссылке атрибут "rel=nofollow". Только исходящие ссылки должны быть исправлены.

Пример: Мой домен — www.laptops.com.

$myDomain = "www.laptops.com";

$html = 
 "Hello World have a look at <a href="www.laptops.com/apple">Apple Laptops</a>. 
  For more ino go to <a href="www.apple.com">Apple.com</a> 
  or to <a href="www.appleblog.com">Appleblog.com</a>";

function correct($html,$myDomain){ 
    //get all links by filtering '<a ... href="{$link}" .....>' and 
    //check with isOutgoing($href,$myDomain )
}

$newHTML = correct($html,$myDomain);

echo $newHTML;

//Hello World have a look at <a href="www.laptops.com/apple">Apple Laptops</a>. 
//For more ino go to <a rel="nofollow" href="www.apple.com">Apple.com</a> 
//or to <a rel="nofollow" href="www.appleblog.com">Appleblog.com</a> 

Пока у меня есть функция "isOutgoing($link)", которая может определить, является ли ссылка исходящей или нет, но обнаружение ВСЕХ "‹ a... href="{$link}" ..... > " части HTML-текста и фильтрация {$link} создает проблемы. Я знаю, что это возможно с помощью preg_match(), но я понятия не имею, как это решить.


person jb7AN    schedule 13.07.2018    source источник
comment
Я знаю, что это возможно с помощью preg_match() .... не делай этого ...даже не думай, он тебя услышит!   -  person CD001    schedule 13.07.2018
comment
это должно быть PHP? Это безумно просто в jQuery   -  person delboy1978uk    schedule 13.07.2018


Ответы (2)


Вам следует избегать использования регулярных выражений, вместо этого вы должны использовать DOMDocument и DOMXPath.

<?php
$dom = new DOMDocument();

$dom->loadHtml('
Hello World have a look at <a href="www.laptops.com/apple">Apple Laptops</a>. 
  For more ino go to <a href="www.apple.com">Apple.com</a> 
  or to <a href="www.appleblog.com">Appleblog.com</a>
', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$xpath = new DOMXPath($dom);

foreach ($xpath->query("//a") as $link) {
    $href = $link->getAttribute('href');

    // link does not have a www.laptops.com in it, add rel attribute
    if (strpos($href, 'www.laptops.com') === false) {
        $link->setAttribute("rel", "nofollow noopener");
    }
}

echo $dom->saveHTML();

Результат:

<p>Hello World have a look at <a href="www.laptops.com/apple">Apple Laptops</a>. 
  For more ino go to <a href="www.apple.com" rel="nofollow noopener">Apple.com</a> 
  or to <a href="www.appleblog.com" rel="nofollow noopener">Appleblog.com</a>
</p>

https://3v4l.org/DseDi

person Lawrence Cherone    schedule 13.07.2018
comment
Этот. Если это ДОЛЖНО быть в PHP! Классы ДОМ рулят! - person delboy1978uk; 13.07.2018
comment
Спасибо, сработало для меня. Необходимо добавить код для UTF-8 и подавления ошибок: $sHTML = mb_convert_encoding($sRawValue, 'HTML-ENTITIES', 'UTF-8'); $libxml_previous_state = libxml_use_internal_errors(true); $oDom-›loadHtml($sHTML, LIBXML_HTML_NODEFDTD | LIBXML_NOERROR | LIBXML_NOWARNING); // обработка ошибок libxml_clear_errors(); // восстановить libxml_use_internal_errors($libxml_previous_state); - person jb7AN; 18.07.2018

Это было бы намного проще с небольшим количеством jQuery.

<script type="text/javascript">
$(document).ready(function(){
    $('a').each(function(){
        let href = $(this).prop('href');
        if (!href.search('laptops.com')) {
            $(this).prop('rel', 'nofollow');
        }
    });
});
</script>
person delboy1978uk    schedule 13.07.2018