ニケッチャニッキ

はてなブログ・WordPressカスタマイズ・Androidプログラミング

コピペでOK!WordPress本文中に広告を自動挿入する方法-PHPの解説付き

f:id:niketcha:20190707173948j:plain

プラグインなしでWordPressの本文に広告を自動挿入する方法です。

最初のh2タグの前に1つ挿入する方法と、複数のh2タグの前に挿入する方法を紹介します。

コードの説明もしてますが、カスタマイズが不要な方は説明ふっとばしてコードコピペして使ってください。

初めのh2タグの前に1つ挿入

function.phpに次のコードをコピペし、※ここに広告コード※の部分を広告コードに書き換えてください。

// 広告
function insert_ad($the_content) {
// 投稿のみに適用
if (!is_single()) {
    return $the_content;
}
$ad = <<< EOF
※ここに広告コード※
EOF;
$pattern = '/<h2/i';
if ( preg_match( $pattern, $the_content, $h2s )) {
    $the_content = preg_replace($pattern, $ad.$h2s[0], $the_content, 1);
}
return $the_content;
}
add_filter('the_content','insert_ad');

preg_match関数

preg_match関数を使ってh2タグを検索しています。preg_match関数は正規表現で指定したパターンを、特定の文字列から検索する関数です。

第1引数に正規表現、第2引数に検索対象の文字列を指定します。第3引数に配列を指定すると、検索結果がその配列格納されます。

正規表現に当てはまる文字列が見つかった時点で検索を終了します。検索した結果マッチした場合はTrue、マッチしなかった場合はFalseが返ってきます。

正規表現とは

正規表現という言葉を聞いたことがない人はちょっと難しく聞こえるかもしれません。とりあえず、検索をするためのパターンを記号やアルファベットで指定するものだと思ってください。言葉で説明するより実際の使い方を見ていった方がわかりやすいと思います。

正規表現の書き方

正規表現はパターンを/で囲みます。パターンの後にフラグというものを指定できます。

今回の場合<h2がパターンでiがフラグです。フラグiは大文字小文字を区別せずに検索したいときに指定します。これで<h2もしくは<H2がマッチするようになります。

preg_replace関数

preg_replace関数は正規表現を用いて置換するための関数です。第1引数に正規表現、第2引数に置換後の文字列、第3引数に置換対象の文字列を指定します。第4引数には置換する回数を指定できます。デフォルトは-1(無制限)です。今回は初めのh2タグだけ置換したいので、1を指定しています。

最初と最後のh2の前に広告を挿入

最初のh2タグの前と、h2タグが3つ以上ある場合は最後のh2タグの前にも広告を挿入する方法です。

function insert_ad($the_content) {
// 投稿のみに適用
    if (!is_single()) {
        return $the_content;
    }
$ad = <<< EOF
※ここに広告コード※
EOF;
$pattern = $pattern = '/<h2.+?\/h2>/i';
if ( preg_match_all( $pattern, $the_content, $h2s )) {
    $the_content = str_replace($h2s[0][0], $ad.$h2s[0][0], $the_content);
    $cnt=count($h2s[0]);
    if ($cnt>=3) {
        $the_content = str_replace($h2s[0][$cnt-1], $ad.$h2s[0][$cnt-1], $the_content);
    }
}
return $the_content;
}
add_filter('the_content','insert_ad');

preg_match_all関数

先ほどはpreg_match関数を使いましたが、今回はpreg_match_allを使っています。preg_matchとの違いは、検索パターンにマッチする文字列が見つかっても検索を終了せず、最後まで検索を続ける点です。

第1引数に正規表現、第2引数に検索対象の文字列、第3引数に結果を格納する配列を指定するという点はpreg_match関数と変わりません。

検索結果が格納される配列は多次元配列で、第4引数で指定する形式によって格納順が変わります。この配列についてかみ砕いた説明がしてある情報が見つからなかったので私もよく理解できてないのですが、第4引数で何も指定していない場合は[0][0]に1つ目の検索結果、[0][1]に2目、[0][2]に3つ目…ということだけ知っていれば今回は大丈夫です。

count($h2s[0]);で配列$h2s[0]の要素数をカウントします。配列のインデックスは0から始まるので、最後のh2タグはカウントの結果から1引いた値を指定します。

今回の正規表現

今回使った正規表現は/<h2.+?\/h2>/iです。1つだけ広告を挿入するコードとは変えています。

.改行以外の任意の1文字
+?直前の文字の1つ以上の連続を、可能な限り短い範囲で検索する
\正規表現のパターンで使用する特殊文字そのものを指定したい場合は\と組み合わせて使います。今回/h2を検索したいのですが、/だけ記述すると正規表現のパターンの終了と判断されてしまいます。\/とすると/そのものを検索できます。

したがって<h2.+?\/h2>は<h2から次に出現する/h2>までを探します。

str_replace関数

str_replace関数は正規表現を用いない単純な置換です。正規表現での置換では複数のh2それぞれの区別が付かないので、preg_replaceではなくstr_replaceを使います。

注意事項

今回のコードは同名見出しを考慮していません。

正規表現の^を使って行頭かどうかを判断し、既に広告が挿入されている見出しを除外しているコードを載せているサイトがあったのですが、うまく動作しませんでした。(preg_match_allで検索するときに行頭かどうか判断しても、str_replaceで置換するときには判断をしていないので)

同名見出しに対応する方法を色々検討してみたのですが、今のところいい方法が見つかっていません。

奇数番目のh2タグの前に広告を挿入

次のコードは1番目、3番目、5番目…というように、奇数番目のh2タグの前に広告を挿入するための例です。

h2タグの数だけループさせてるので、h2タグがいくつあっても対応可能。本文が短い場合は広告の割合が多くなってしまうので注意です。

// 広告
function insert_ad($the_content) {

// 投稿のみに適用
if (!is_single()) {
    return $the_content;
}
$ad = <<< EOF
※ここに広告コード※
EOF;
$pattern = '/<h2.+?\/h2>/i';
if ( preg_match_all( $pattern, $the_content, $h2s )) {
    $i=1;
    foreach( $h2s[0] as $h2){
        if($i%2<>0){
            $the_content = str_replace($h2, $ad.$h2, $the_content);
        }
        $i++;
    }
}
return $the_content;
}
add_filter('the_content','insert_ad');

今回のコードではforeachで$h2s[0]の要素を$h2に格納しているので、ループ1回目で$h2に入っているのは$h2s[0][0]の内容、2回目で入っているのは$h2s[0][1]の内容です。

広告の挿入位置

$iという変数でループ回数をカウントしていて、$i%2<>0の部分で奇数かどうか判断しています。%は余りを計算するための演算子で、2で割った時の余りが0でないなら処理が実行されます。

if文の条件を変えることで、任意の位置に広告を挿入できます。

位置をベタ書き指定して広告を挿入

広告を挿入したい場所が固定で決まっている場合、ループせずに下記のようにベタ書きする方法もあります。コードの見た目は汚いですが。

次の例は2つ目と3つ目のh2タグの前に広告を挿入するコードです。

// 広告
function insert_ad($the_content) {

// 投稿のみに適用
if (!is_single()) {
    return $the_content;
}
$ad = <<< EOF
※ここに広告コード※
EOF;
if ( preg_match_all( $pattern, $the_content, $h2s )) {
    if($h2s[0][1]){ 
        $the_content = str_replace($h2s[0][1], $ad.$h2s[0][1], $the_content);
    }
    if($h2s[0][2]){
        $the_content = str_replace($h2s[0][2], $ad.$h2s[0][2], $the_content);
    }
}
return $the_content;
}
add_filter('the_content','insert_ad');