自分のWordPressで学ぶPHP講座(AIの変更を判定する)

区分2 読むための最低限★★★

No.04 if・isset・foreach

「もし〜なら」の条件と、「一覧を1つずつ処理する」繰り返しを読めるようにする単元です。AIの差分の中で、危ない所が一番出やすい形なので、この回はしっかりやります。
目次
  1. 第0章 前提知識
  2. 第1章 比較と条件
  3. 第2章 isset と empty
  4. 第3章 foreach と static
  5. 確認問題

第0章 前提知識

① 条件 :「もし〜なら、これをする」

条件は、コードの中の分かれ道です。 たとえば「管理画面の中なら何もしない」「ログインしている時だけ表示する」のように、場合によって動きを変えます。

② 真偽 :条件の答えは「はい」か「いいえ」の2つだけ

条件の判定結果は、true(はい)か false(いいえ)のどちらかです。 if は、この結果が true の時だけ、中の処理を動かします。

③ 繰り返し :一覧を1件ずつ処理する

配列(No.03で扱った一覧)の中身を、先頭から1件ずつ取り出して、同じ処理をかけるのが繰り返しです。 事務所で言えば、「名簿の全員に、同じ封筒を作る」作業です。

第1章 比較と条件

① 比較の記号 必ず覚える

条件の中では、2つの値を比べる記号が使われます。

= が1つの時は代入、=== は比較です。この違いは、差分を読む時にとても大事です。

ゆるい比較 == は、'1' == 1 を true とします。 完全な比較 === は、'1' === 1 を false とします。文字の「1」と数字の 1 は別物だからです。 AIの出力では === が標準で、== が出てきたら理由を聞く価値があります。ただし、== があるだけで即NGではありません。

② if の形 必ず覚える

if ( 条件 ) {
  // 条件が true の時の処理
} elseif ( 別の条件 ) {
  // 別の条件が true の時の処理
} else {
  // どれでもない時の処理
}

( ) の中が条件で、{ } の中が処理です。elseif と else は、付けなくても構いません。

条件の中に = が1つだけ書かれていたら、赤信号です。 if ( $mode = 'on' ) は「$mode に 'on' を入れる」になってしまい、いつでも true になります。 書き間違いでよく起きるため、WordPressの書き方の決まりでは、'1' === $x のように値を左に置く書き方が多く使われます。もし = と書き間違えると、エラーですぐ気づけるからです。

③ 実物を読む:lk_look_enabled 必ず覚える

子テーマの functions.php にある、「新しい見た目を出すかどうか」を決める関数です。 10/8に足した差分の中心なので、少し長めに引用します。

function lk_look_enabled() {
  static $on = null;
  if ( null !== $on ) {
    return $on;
  }
  if ( is_admin() || wp_doing_ajax() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) {
    return $on = false;
  }
  if ( LOOK_FOR_ALL ) {
    return $on = true;
  }
  if ( isset( $_GET['look'] ) ) {
    $v = sanitize_key( wp_unslash( $_GET['look'] ) );
    if ( 'on' === $v ) {
      return $on = true;
    }
    if ( 'off' === $v ) {
      return $on = false;
    }
  }
  return $on = ( isset( $_COOKIE['look_preview'] ) && '1' === $_COOKIE['look_preview'] );
}

上から読んでいきます。

  1. static $on = null; と最初の if は、第3章で見ます。「前に答えを出していたら、それを返して終わり」という近道です
  2. 管理画面や裏側の通信(is_admin() など)の時は、false を返して終わり。新しい見た目は出さない
  3. if ( LOOK_FOR_ALL ) は、スイッチ(定数)が true なら true を返して終わり。全員に出す設定です
  4. 上のどれでもなく、URLに ?look= が付いている時は、中身が 'on' なら true、'off' なら false
  5. 最後は、cookie(ブラウザに残る小さな記録)に印があるかで決める

注目してほしいのは、3番の LOOK_FOR_ALL が true なら、4番の ?look= を見る前に答えが出る点です。 条件は上から順に調べられ、最初に当たった所で return して終わります。順番を入れ替えるだけで、動きが変わります。

$_GET['look'] や $_COOKIE[…] は、ブラウザから送られてきた値です。外から来る値なので、使う前に整える関数(sanitize_key)を通しています。この考え方はNo.07(後で出ます)で扱います。

第2章 isset と empty

① isset :「その値は、ある?」 必ず覚える

isset( $_GET['look'] ) は、「URLに look が付いているか」を調べます。 値がある(かつ null でない)時に true を返します。

存在しない箱を、確かめずにいきなり使うと、エラーや警告が出ます。 そこで、使う前に isset で確かめるのが定番の形です。

② empty :「その値は、空?」 必ず覚える

if ( ! empty( $c['note'] ) ) {
  // 小さいリンクを出す
}

empty は、「空っぽか」を調べます。次の値は、すべて「空」と数えられます。

この関数では、設定で 'note' => array() と書けば「リンクを出さない」になります。 !(否定)が前に付いているので、! empty(…) は「空でなければ」の意味です。

③ isset と empty の使い分け

たとえば値が 0 の時、isset は true ですが、empty も true です。 どちらを使うかで結果が変わるため、AIが isset を empty に書き換えた差分は、意図を聞きます。

第3章 foreach と static

① foreach :一覧を1件ずつ処理する 必ず覚える

foreach ( $c['ctas'] as $b ) {
  echo '<a class="' . esc_attr( $b['class'] ) . '" href="' . esc_url( lk_look_url( $b['url'] ) ) . '">'
     . esc_html( $b['label'] ) . '</a>';
}

foreach ( 一覧 as 1件の名前 ) は、一覧の先頭から1件ずつ取り出し、{ } の中を1回ずつ動かします。 ここでは、ボタンの設定が3つ並んだ配列を、1つずつ取り出して、リンクの部品(<a …>)を画面に出しています。

echo は、「画面に出す」命令です。. は文字をつなぐ記号でした(No.03)。 esc_attr などの関数は、出す文字を安全にするためのものです(No.07)。

キーと値の両方を使いたい時は、foreach ( $c as $key => $value ) と書きます。 => の読み方は、配列の時と同じです。

② static :1回の訪問の間だけ、値を覚える さらっと

function lk_look_front_hero() {
  static $done = false;
  if ( $done || ! lk_look_enabled() || ! is_front_page() || is_paged() ) {
    return;
  }
  $done = true;

関数の中の普通の変数は、関数が終わると消えます。 static を付けた変数だけは、同じ訪問(リクエスト)の間なら、次に関数が呼ばれた時も値が残ります。

この関数は、トップページの帯を出します。 同じ関数が2か所から呼ばれる作りで、$done に印を付けておけば、2回目は何も出さずに終われます。 static $on = null; の方は、「判定結果を覚えておいて、2回目からは調べ直さない」ために使われています。

なお、if の条件には ||(または)が並んでいます。 どれか1つでも当てはまれば return(ここで終わり)という意味で、「帯を出さない場面」を並べています。

○ よくある勘違い:「isset は値が空でないか調べる」→ ×。あるかを調べます。空かどうかは empty
○ 差分で気をつける形:条件に = が1つ/== が増えた/isset や empty が消えた/条件の順番が入れ替わった。どれも「判定が変わった」合図です
○ 関係する単元:No.03(配列・関数)/No.05(フック)/No.07(外から来る値)

=== は比較、= は代入。条件は上から調べ、最初に当たった所で終わる。isset は「ある?」、empty は「空?」。foreach は一覧を1件ずつ。

確認問題

問1 AIの差分に if ( $mode = 'on' ) { … } と書かれていました。何が問題ですか?

問2 子テーマの lk_look_enabled で、定数 LOOK_FOR_ALL が true の時、URLに ?look=off が付いていたら、どうなりますか?

問3 設定で 'note' => array() としたとき、! empty( $c['note'] ) の結果は?

問4 関数の中の static $done = false; は何のために付けられていますか?

出典:PHP公式マニュアル「if」(https://www.php.net/manual/ja/control-structures.if.php)/「比較演算子」(https://www.php.net/manual/ja/language.operators.comparison.php)/「論理演算子」(https://www.php.net/manual/ja/language.operators.logical.php)/「isset」(https://www.php.net/manual/ja/function.isset.php)/「empty」(https://www.php.net/manual/ja/function.empty.php)/「foreach」(https://www.php.net/manual/ja/control-structures.foreach.php)/「変数のスコープ(static)」(https://www.php.net/manual/ja/language.variables.scope.php)/WordPress コーディング規約 PHP(Yoda 条件)/あなたの子テーマ内 functions.php。