「外部リンクをSNSのように表示させたい」
「簡単できれいに外部リンクを表示させたい」
こんな悩みがある人に向けて書いた記事です。
- PHPを使って指定したURLからOGPを取得、表示する方法
この記事では以上のことがわかります。
指定したURLからOGPを取得、表示する方法
サンプルコード
関数にして使いまわしがしやすいようにしています。
WordPressを前提にした場合、以下のコードをfunctions.phpにコピペします。
function get_ogp( $url ){ $ch = curl_init($url);// urlは対象のページ curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);// exec時に出力させない curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);// リダイレクト許可 curl_setopt($ch, CURLOPT_MAXREDIRS, 5);// 最大リダイレクト数 $html = curl_exec($ch); $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); //リンク先がないとき(404のとき)は処理しない if( $status_code !== 404 ): $dom_document = new \DOMDocument(); $from_encoding = mb_detect_encoding($html, ['ASCII', 'ISO-2022-JP', 'UTF-8', 'EUC-JP', 'SJIS'], true); if ( ! $from_encoding) { $from_encoding = 'SJIS'; } @$dom_document->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', $from_encoding)); $xml_object = simplexml_import_dom($dom_document); $ogp = []; //title if( $xml_object->xpath('//meta[@property="og:title"]/@content')[0] ): $ogp["title"][] = (string)$xml_object->xpath('//meta[@property="og:title"]/@content')[0]; elseif( $xml_object->xpath('//title')[0] ): $ogp["title"][] = (string)$xml_object->xpath('//title')[0]; endif; //description if( $xml_object->xpath('//meta[@property="og:description"]/@content')[0] ): $ogp["description"][] = (string)$xml_object->xpath('//meta[@property="og:description"]/@content')[0]; elseif( $xml_object->xpath('//meta[@name="description"]/@content')[0] ): $ogp["description"][] = (string)$xml_object->xpath('//meta[@name="description"]/@content')[0]; endif; //thumbnail if( $xml_object->xpath('//meta[@property="og:image"]/@content')[0] ): $ogp["thumbnail"][] = (string)$xml_object->xpath('//meta[@property="og:image"]/@content')[0]; elseif( $xml_object->xpath('//meta[@name="thumbnail"]/@content')[0] ): $ogp["thumbnail"][] = (string)$xml_object->xpath('//meta[@name="thumbnail"]/@content')[0]; else: $ogp["thumbnail"][] = get_template_directory_uri() . "/images⁄noimage.jpg"; endif; $out = ' <div class="box-item box-item2"> <div> <a href="' . esc_url( $url ) . '" target="_blank"> <img class="ofi-cover" src="' . esc_url( $ogp["thumbnail"][0] ) . '" width="200" height="200" alt="' . esc_attr( $ogp["title"][0] ) . '"> </a> </div> <div> <p> <a class="link-external" href="' . esc_url( $url ) . '" target="_blank">' . $ogp["title"][0] . '</a> </p> <p class="description">' . esc_html( $ogp["description"][0] ) . '</p> </div> </div> '; endif; return $out; }
以下を表示させたい場所にコピペして、「●●●」のところをリンクしたいURLにします。
これでタイトル、説明、画像を表示させることができます。
<?php echo get_ogp( "●●●"); ?>
- POINT
- 指定したWebサイトに情報が入っていない場合は表示されません。
タイトルはほぼ入っていると思いますが、画像や説明は入っていない可能性もあると思います。
解説
ここからは解説です。
cURL
PHPで外部サイトから情報を取得するときは今まで「file_get_contents」を使っていましたが、今回はじめて「cURL」というものを使ってみました。
$ch = curl_init($url);// urlは対象のページ curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);// exec時に出力させない curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);// リダイレクト許可 curl_setopt($ch, CURLOPT_MAXREDIRS, 5);// 最大リダイレクト数 $html = curl_exec($ch); $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
サンプルコードの関数の中で「cURL」の処理をして外部サイトの情報を取得しています。
この時点で$htmlにHTMLソースが格納されています。
以下のサイトを参考にさせていただきました。
PHPのfile_get_contentsをcURLへ置き換える
PHPのfile_get_contents関数ってチョー手軽でチョー便利ですよね。 $html = file_get_contents('test.txt'); こんな風にファイル名を指定するだけ
simplexml_import_dom
「simplexml_import_dom」でHTMLをオブジェクトにして返します。
$xml_object = simplexml_import_dom($dom_document);
xpath
xpathを使うとオブジェクトを取得し、OGP情報を配列で格納します。
ogpが指定されていない場合は、titleやdescriptionを格納します。
ogp画像がない場合は、指定したnoimageを表示させます。
$ogp = []; //title if( $xml_object->xpath('//meta[@property="og:title"]/@content')[0] ): $ogp["title"][] = (string)$xml_object->xpath('//meta[@property="og:title"]/@content')[0]; elseif( $xml_object->xpath('//title')[0] ): $ogp["title"][] = (string)$xml_object->xpath('//title')[0]; endif; //description if( $xml_object->xpath('//meta[@property="og:description"]/@content')[0] ): $ogp["description"][] = (string)$xml_object->xpath('//meta[@property="og:description"]/@content')[0]; elseif( $xml_object->xpath('//meta[@name="description"]/@content')[0] ): $ogp["description"][] = (string)$xml_object->xpath('//meta[@name="description"]/@content')[0]; endif; //thumbnail if( $xml_object->xpath('//meta[@property="og:image"]/@content')[0] ): $ogp["thumbnail"][] = (string)$xml_object->xpath('//meta[@property="og:image"]/@content')[0]; elseif( $xml_object->xpath('//meta[@name="thumbnail"]/@content')[0] ): $ogp["thumbnail"][] = (string)$xml_object->xpath('//meta[@name="thumbnail"]/@content')[0]; else: $ogp["thumbnail"][] = get_template_directory_uri() . "/images⁄noimage.jpg"; endif;
格納した配列を出力する
$outに出力するHTMLタグを格納します。
ここは好きなデザインに調整してください。
$out = ' <div class="box-item box-item2"> <div> <a href="' . esc_url( $url ) . '" target="_blank"> <img class="ofi-cover" src="' . esc_url( $ogp["thumbnail"][0] ) . '" width="200" height="200" alt="' . esc_attr( $ogp["title"][0] ) . '"> </a> </div> <div> <p> <a class="link-external" href="' . esc_url( $url ) . '" target="_blank">' . $ogp["title"][0] . '</a> </p> <p class="description">' . esc_html( $ogp["description"][0] ) . '</p> </div> </div> ';
まとめ
指定したURLからOGPを取得、表示する方法を紹介しました。
このページで参照している外部サイトでこの関数を使っています。
- 参考サイト
-
OGPに括るとライブラリがあるようですのでそちらを使った方が良いかもしれません。おてがるにOGPのチェッカーを作る - Qiitaよく使うのでメモcurl例ch …