当サイトのリンクにはアフィリエイト広告が含まれています

PHP(WordPress)でAMP対応ページかどうか判別する方法。

先日、またまたteratail(テラテイル)を利用しました。質問内容は「現在表示されているページがAMPページかどうかの判別方法」について。

参考https://teratail.com/questions/87735

プログラミング初心者のteratail(テラテイル)の使い方は? Fantastech!! もっと見る

正直、あまり必要になるケースもないんですが、AMPページにはこのコードを、通常ページにはこのコードを…のようにサンプルコードを紹介するのが難しかったんです。

例えば、WordPressのAMPプラグインを使う場合はis_amp_endpointという関数で条件分岐できるようですが、プラグインを使わずにAMP対応している人もいるので、その関数は使えません。

また、プラグインを使わずにAMPに対応する方法もいくつかあるので、 結局は「そのページがAMPページかどうか」で条件分岐するしかありません。

ただ、これが意外と難しく、良いアイディアは浮かんだものの、それを再現することができずにteratailで質問したというわけです。



AMPページかどうかの条件分岐の関数

こちらが今回完成させたコードです。これをfunctions.php(子テーマでもOK)にコピペすれば、条件分岐に使えます。(解説は後で)

function amp_check_4536() {
 $amp_check = false;
 $html = get_the_permalink();
 $html = file_get_contents($html, NULL, NULL, 0, 100);
 $html = htmlspecialchars($html);
 $pattern = '/html amp|html ⚡/i';
 if(preg_match($pattern,$html,$matches) === 1){
 $amp_check = true;
 }
 return $amp_check;
}

WordPress以外のサイトで使う場合は、get_the_permalink関数の部分を任意の文字列や関数に変更する必要があります。

ちなみに、ローカル環境だと上手くいかなかったので、確かめる時はget_the_permalinkではなく、直に入力してみてください。

活用例

こちらは、「AMPページ用のコード」と「通常ページ用のコード」を条件分岐してショートコード化した例です。

function amp_test() {
 if( amp_check_4536() ) {
 $adsense_code = '<amp-ad layout="responsive" width=336 height=280 type="adsense" data-ad-client="ca-pub-***" data-ad-slot="***"></amp-ad>'; //AMPページ用のアドセンス
 } else {
 $adsense_code = '***'; //通常ページ用のアドセンス
 }
 return '<div class="ad-wrapper clearfix">'.$adsense_code.'</div>';
}
add_shortcode('adsense', 'amp_test');

これで、本文中には[[adsense]]と書くだけで、それぞれのページ用の広告が表示されます。

アドセンス広告をショートコードにして記事内に挿入する方法。 Fantastech!! もっと見る

解説

回答をもらって気づいたんですが、実は、teratailで質問した時のコードが非常に惜しかったんです…!

function amp_check() {
 $amp_check = false;
 $html = file_get_contents ( 'example.com' );
 $html = htmlspecialchars($html);
 $pattern = '/<html amp'; //
 if(preg_match($pattern,$html,$matches) === 1){
 $amp_check = true;
 }
 return $amp_check;
}

やりたかったことは、ページを読み込んでソースコード化し、<html amp、もしくは、<html ⚡で始まる場合はAMPページ、それ以外なら通常のページ…という条件分岐の関数を定義すること。

このコードでダメだったのは、文字列にする量を制限していなかったこと。

file_get_contents関数はオプションを指定しない場合、ページの情報をすべて文字列にしてしまいます。目に見えるものも、メタ情報のような目に見えないものも全部です。

これの何が問題かというと、例えば、「プラグインなしでAMPに対応する方法」のようなテーマで記事を書いた場合、記事で紹介されているソースコードまで文字列になり、それが正規表現の検索対象になってしまいます。

つまり、「AMPのことを紹介しているだけの通常ページ」がAMPページとして扱われるわけです。

そこで教えていただいたのが、file_get_contents関数で文字列にする量を制限する方法。こちらの回答をベストアンサーにしました。

$html = file_get_contents($html, NULL, NULL, 0, 100);

<html ampも<html ⚡も、ほとんどの場合ソースコードの先頭にあるはずなので、シンプルですごく良い方法だなと思って取り入れましたが、上手くいきました。

上限を100にした理由は、meta情報を検索対象にしたくなかったからです。var_dumpして確認しましたが、それくらいでいいかなと。

懸念点

teratailでも指摘がありましたが、先述の通り、AMPは人によって対応方法が違うので、この条件分岐は万能ではない可能性があります。

ただ、僕が確認したところ、

  • AMPプロジェクトの公式サイト
  • WordPressのAMPプラグインで生成されたAMPページ
  • ネットでよく見かけるAMP対応方法で生成されたAMPページ

など、ほとんどのサイトが同じような構成のHTMLだったので、そこまで心配になる必要もないかと思います。

より精度の高い条件分岐方法

どうしても不安な場合、さらに条件分岐の精度を高める方法もあります。

それは、AMPBench(アンプベンチ)のAPIを使うこと。別の回答者からの情報なんですが、普通に便利なツールでした。

ただ、APIの使い方がいまいちわからずに断念。

  1. file_get_contents関数で文字列化
  2. 「”status”: “PASS”」でマッチング

でいけるかなと思ったですが、ダメでした。

また、一旦別のページを経由するからか、動作が重くなるのも使わなかった理由の1つです。

参考としてコード載せておきます。トンチンカンなことしてたらご指摘ください〜

function amp_check_4536() {
 $amp_check = false;
 $html = 'https://ampbench.appspot.com/api2?url='.get_the_permalink();
 $html = file_get_contents($html, NULL, NULL, 0, 100);
 $html = htmlspecialchars($html);
 $pattern = '/"status": "PASS"';
 if(preg_match($pattern,$html,$matches) === 1){
 $amp_check = true;
 }
 return $amp_check;
}

まとめ

相手がどのようにAMPに対応しているかわかる場合は別ですが、ブログなどで不特定多数の人にコードを紹介する場合は、今回の関数はなかなか便利ではないでしょうか?

ぜひ、お試しあれ!(๑•̀ㅂ•́)و✧

(改善点やもう少し上手いやり方があれば教えてくださいっ!)


カテゴリー:カスタマイズ

シェフ

このサイト「Fantastech」を運営している人