Naota(はんぺん)

BLOG

2021年10月16日 17時55分

PHP でテキスト内の外部リンクに target="_blank" と rel 属性を追加する方法

すでに HTML になっているリンクの中でリンク先に応じて属性を変更する方法を紹介します。

リンク先が外部かを判定

$url = "https://example.com/";

if( is_valid_url($url, true) === false ) {
    // リンクでない(ページ内のアンカーの可能性はある)
}
$urlParsed = parse_url($url);
if( $urlParsed['host'] !== $_SERVER['SERVER_NAME'] ) {
    // 外部
}else{
    // 内部
}

// URL のバリデーション関数
function is_valid_url( $url, $webOnly = false )
{
    if( $webOnly === false ) {
        return false !== filter_var($url, FILTER_VALIDATE_URL);
    }else{
        return false !== filter_var($url, FILTER_VALIDATE_URL) && preg_match('@^https?+://@i', $url);
    }
}


HTML から A タグを抜き出して判定

function linkConvert($html) {
    return preg_replace_callback('/<a[^>]*>/', function($matches) {
        preg_match('/href="(.*)"/', $matches[0], $link);
        if( is_valid_url($link[1], true) === false ) {
            // URL でない (そのまま)
            return '<a href="' . $link[1] . '">';
        }
        $url = parse_url($link[1]);
        $addAttr = ""; // 追加する属性
        if( $url['host'] !== $_SERVER['SERVER_NAME'] ) {
            $addAttr .= ' target="_blank" rel="noopener noreferrer external nofollow"';
        }
        return '<a href="' . $link[1] . '"$addAttr>';
    }, $html);
}

// URL のバリデーション関数
function is_valid_url( $url, $webOnly = false )
{
    if( $webOnly === false ) {
        return false !== filter_var($url, FILTER_VALIDATE_URL);
    }else{
        return false !== filter_var($url, FILTER_VALIDATE_URL) && preg_match('@^https?+://@i', $url);
    }
}


実行結果

自分のドメイン:example.com

  • https://example.com/: そのまま(同じドメイン)
  • http://example.com/: そのまま(同じドメイン)
  • mailto:email@example.com: そのまま(URL でない)
  • https://www.example.com/: 新規タブで開く
  • https://subdomain.example.com/: 新規タブで開く


問題点

  • 通常、www.example.com と example.com とでは同じリソースにアクセスできます。しかし、このコードは考慮されておらず、それぞれが別のタブで開いてしまいます。


言語

言語を選択してください。

日本語
English