連載第186回
2023年3月19日
ChatGPTに家庭教師をお願いして超簡単なアイキャッチ画像の割り当ての仕組みをfunction.phpに追加するまでの紆余曲折

ChatGPTのアカウントを作成したので、早速、その有能ぶりを試してみることにしました。以前、当サイトのアイキャッチ画像周りの動作をfunction.phpに追加したのですが、それをほんの少し拡張したい。…もう9年前の記事ですが。

WordPress(15)アイキャッチ画像のカテゴリー毎の使い回し

「拡張したい」と言っても大したことではなく、扱う画像の種類を1つ増やしたい、というだけ。上のサイト内記事を書いたあと、アイキャッチ画像は記事毎に毎回自作して貼り付けるタイプと(jpg・pngなど)、そこまでしなくてもいい雑談記事の場合は、カテゴリー毎に事前に作り置きしておいた専用のjpg画像を使い回すようにしました(上のリンク記事内ではPNGを扱うことにしていましたが、後日jpgに変更)。
が、しかし、使っていると、「このカテゴリーのデフォルトのアイキャッチ画像はpngで作りたいなあ…」という場面がたまにあり、ちょっと悩む事がありました。そこで、jpgでもpngでも好きな方で作成してフォルダに放り込んでおけば済むようにしたいと思いました。

改善したい内容

  1. 投稿記事専用のアイキャッチ画像が貼られていればそれを使用
  2. 通常、ほとんどの場合はこれです。例えば「僕はアップル様が嫌い」カテゴリーなら、記事毎にキャッチな画像を貼り付けている場合が多いです。しかし、この「VPS&WordPress引っ越しメモ」では、毎回目新しいキャッチ画像なんて思いつかない場合が多い…(なので富嶽三十六景のアイコンをデフォルトにしています)。そういう場合に、2番へ渡します。

  3. アイキャッチ画像が無い場合、記事のカテゴリーIDが振られたjpg画像を使用
  4. 例えばカテゴリーIDが「23」の記事であれば、使い回し用の「ICON_ID_23.jpg」を表示させます。それが無ければ次に3番へ。

  5. 上記jpg画像が無ければ記事のカテゴリーIDが振られたpng画像を使用
  6. jpg画像も無い場合は、「ICON_ID_23.png」を表示させます。
    ※僕が忘れずにしておくべきことは、ID番号を振ったカテゴリー専用画像をjpgかpngでアップロードしておく事で、うっかり忘れて該当する画像が無ければ空欄になります。

実は、数年前に自分でなんとか実現出来ないものだろうかと、あちこちググって調べながら試行錯誤してみたのですが、残念ながら挫折しました。

その時に試していたフローは、アイキャッチ画像が貼られていればそのまま使用するのは同じで、それが貼られていない場合、配列型の変数内に「imgフォルダ」内の画像ファイル名を全て格納して、そのファイル名の中から該当するjpgがあればそれを表示、無ければpng画像を表示。
と、まあ、上で書いてある通りです。
記憶を辿ると、glob関数とforeach関数を使い、if〜elseif〜elseの条件分岐を使った気がします。
当時、まずは画像の代わりにテスト用のファイル名を羅列し、それを読み込ませて相対パスとして記述する、というテストまで行けたのですが、実際にローカルで画像を表示させたりするところで全く意図通りに動作せず、その解決方法が見つからずに断念しました。
そして今回、その当時に試していたファイルを紛失してしまい、初心からのスタートとなりました。ChatGPTの評判を聞いてまずやってみたい!と思った事がこの案件です。

1回目の会話:それではまず最初に…と思っていたら、うっかりコードを丸投げしてしまった

いわゆる「改行しようとしてリターンキー押したら送信してしまった」案件です。

function post_icon () {
if( has_post_thumbnail() ) {

echo wp_get_attachment_url( get_post_thumbnail_id() );
} else {
$cat = get_the_category();
$cat_id = $cat[0];
echo ‘/WordPress/wp-content/themes/2023v1/img/ICON_ID_’.$cat_id->cat_ID.’.jpg’;
}
}

The code snippet you provided is a PHP function named `post_icon()`.

The purpose of the function is to retrieve the URL of the post thumbnail if it exists, or if it doesn’t exist, to retrieve the URL of a category icon specific to the first category of the post.

Here is a breakdown of the function:

1. The `has_post_thumbnail()` function checks if the post has a thumbnail image associated with it.
2. If a thumbnail exists, the `wp_get_attachment_url()` function retrieves the URL of the thumbnail image by passing the ID of the thumbnail to it.
3. If no thumbnail exists, the `get_the_category()` function retrieves an array of categories that the post belongs to. The first category in the array is then assigned to the `$cat_id` variable.
4. The category ID is used to construct a URL for the category icon image, which is then echoed.

It’s worth noting that the function assumes that the category icon images are located in the theme directory under `/WordPress/wp-content/themes/2023v1/img/` and that the images are named `ICON_ID_{category ID}.jpg`. If the image filenames or directory structure is different, the function would need to be modified accordingly.

まだChatGPTとの会話UIを把握しておらず、現時点で使っているコードをコピペした後に、改行して文章を整えようとリターンキーを押したらそのまま相手に投げてしまいました。
「間違えた!!」と思ったけれど、エラーや訂正を促す警告が出ることなく、何と秒速で返答が来ました、英語で。

次は冷静になって日本語で質問してみます。しかしまだ緊張していたせいか、要領を得ない、かなり漠然とした抽象的な質問を、またもやウッカリと投げてしてしまいました。AIを相手にする前に、人としてどうなのか。

jpeg画像とPNG画像が混在しているフォルダから抽出するコードに書き直せますか?

はい、JPEG画像とPNG画像が混在しているフォルダから、それぞれの画像を抽出するためのコードを書くことができます。
例えば、以下のようなコードで、JPEG画像を抽出することができます。

<?php
$dir = "/path/to/folder"; // 画像が保存されているフォルダのパス

if (is_dir($dir)) {
  if ($dh = opendir($dir)) {
    while (($file = readdir($dh)) !== false) {
      if (pathinfo($file, PATHINFO_EXTENSION) == 'jpg' || pathinfo($file, PATHINFO_EXTENSION) == 'jpeg') {
        // ここでJPEG画像を扱う処理を書く
        echo $file . "<br>";
      }
    }
    closedir($dh);
  }
}
?>

このコードでは、`readdir()`関数を使ってディレクトリ内のファイルを1つずつ取得し、`pathinfo()`関数を使ってファイルの拡張子を取得しています。jpgまたはjpegの拡張子を持つファイルの場合には、それをJPEG画像として扱う処理を行うことができます。この例では、`echo $file . “<br>”;`の部分で、ファイル名を表示していますが、ここにJPEG画像を扱うための処理を追加してください。

同様に、以下のようなコードで、PNG画像を抽出することができます。

<?php
$dir = "/path/to/folder"; // 画像が保存されているフォルダのパス

if (is_dir($dir)) {
  if ($dh = opendir($dir)) {
    while (($file = readdir($dh)) !== false) {
      if (pathinfo($file, PATHINFO_EXTENSION) == 'png') {
        // ここでPNG画像を扱う処理を書く
        echo $file . "<br>";
      }
    }
    closedir($dh);
  }
}
?>

こちらも、jpgやjpegではなくpngの拡張子を条件として指定することで、PNG画像を抽出しています。JPEG画像の例と同様に、ここにPNG画像を扱うための処理を追加してください。

滅茶苦茶ザックリとした質問をしてしまったのに、かなり斜め上の返答が来ました。人間なら「直せますよ(沈黙)」という素っ気ない回答で会話が終わってしまうところを、なんとChatGPTはコードを提示して、さらにその要素の解説までしてくれるという…なんだこのサービス、家庭教師かよ。と言うか、質問は漠然としていたにも関わらずここまで丁寧な回答を返してくると言うのは「会話の前後の流れ」をきちんと把握していることが窺える。凄い。

ただ、この回答だと、jpgとpngの画像それぞれに対して個別の対応となっていて、このサンプルを元にして一緒くたに混ざっている画像フォルダから抽出するコードに発展させることは、僕の低能力では難しいと感じました。そこでもう少し具体的な質問に変えてみました。

フォルダの階層は
/WordPress/wp-content/themes/2023v1/img/
カテゴリーIDの数字を使った画像は、JPGかPNGのいずれか1枚しか保存していない状態です。
そこから、任意のカテゴリーIDの数字を使った、
ICON_ID_{category ID}.jpg or ICON_ID_{category ID}.png
を抽出するコードは作成できますか?

はい、カテゴリーIDの数字を使った画像がフォルダ内に1枚しか保存されていない場合、その画像を抽出するコードを作成することができます。
以下は、カテゴリーIDの数字を使った画像をフォルダから抽出するためのコード例です。

<?php
$dir = "/WordPress/wp-content/themes/2023v1/img/"; // 画像が保存されているフォルダのパス
$cat_id = 123; // 任意のカテゴリーIDの数字

// JPG画像の場合
$file_path = $dir . "ICON_ID_" . $cat_id . ".jpg";
if (file_exists($file_path)) {
  // 画像が存在する場合の処理
  echo $file_path . "<br>";
}

// PNG画像の場合
$file_path = $dir . "ICON_ID_" . $cat_id . ".png";
if (file_exists($file_path)) {
  // 画像が存在する場合の処理
  echo $file_path . "<br>";
}
?>

今回の回答は、前回よりもかなりシンプルになっていて分かりやすい…、っていうか、「file_exists」という関数って何だそれ…そんな単刀直入な名前の関数があったということを今ここで初めて知ったよ!
ここで感じたのは、質問者が知識不足と判断された場合(本当に相手のレベルを探っているのかどうかは分からないけど)、代替案などの「提案」をしてきたと言うこと。自動車のナビで通路を提案するのと同じか…。感動してお礼を言う。

ありがとう、

どういたしまして。何か他にご質問がありましたら、遠慮なくお聞きください。

参考になりました

良かったです!お役に立てたようで嬉しいです。

なんか、凄い事になっています。会話が成立していることに、言葉では言い表せない衝撃を受けました。ChatGPTの説明が丁寧過ぎて、とりあえず、僕の方も言葉使いには気を付けています。
とは言っても肝心の問題解決には全く至っていないので、ちょっと作戦を練ります。ここでモニターをじっと眺めながらコーヒーブレイク、もちろんブラックで。

2回目の会話:質問内容をさらに具体的に組み立ててつつ臨む

PHPによる画像ファイルの抽出コードを作成してください。
If,elseif,elseを使い、下記の条件を満たしてください。

1. 画像を格納しているフォルダの階層は
/WordPress/wp-content/themes/2023v1/img/
2. まず最初に、AAA.jpgが存在したら、それをechoする。
3. AAA.jpgが無い場合、BBB.jpgをechoする。
4. BBB.jpgが無い場合、BBB.pngをechoする。

以下は、PHPによる画像ファイルの抽出コードの例です。
条件に基づいて、if、elseif、elseステートメントを使用しています。

<?php
// 画像を格納しているフォルダのパス
$path = '/WordPress/wp-content/themes/2023v1/img/';

// AAA.jpgが存在するかどうかを確認
if (file_exists($path . 'AAA.jpg')) {
    echo '<img src="' . $path . 'AAA.jpg">';
}
// AAA.jpgが存在しない場合、BBB.jpgが存在するかどうかを確認
elseif (file_exists($path . 'BBB.jpg')) {
    echo '<img src="' . $path . 'BBB.jpg">';
}
// AAA.jpgとBBB.jpgが存在しない場合、BBB.pngを表示する
else {
    echo '<img src="' . $path . 'BBB.png">';
}
?>

このコードでは、まず「file_exists」関数を使用して、AAA.jpg、BBB.jpg、BBB.pngのいずれかが存在するかどうかを確認しています。条件に応じて、該当する画像ファイルのパスをHTML imgタグ内に設定し、echo文で出力しています。

これです!基本的なフローの脳内設定は!該当するファイルの有無を判断する「file_exists」関数のことは全く知らなかったのですが、それを利用すれば流れが非常にシンプルになりますね。
早速、実際に意図通り動作するのか、Mac miniのローカル内でテストをしてみました。

TEST1.php
<?php

$file_path = '/WordPress/wp-content/themes/2023v2/img/AAA.jpg';

if (file_exists($file_path)){
    print '存在する!AAA';
  }elseif (file_exists('BBB.jpg')){
    print '存在する!BBB';
  }else{
    print '存在する!CCC';
  }
  
  ?>

画像を格納している「img」フォルダに「AAA.jpg」1枚のみを置いて実行した、その結果。

何故だ!!?

正解は「存在する!AAA」じゃないのか!プログラムの流れをジーーーーーッと眺めてみても、どこをどう間違えているのかさっぱり分かりません。自分の知識では原因が分からないので、素直に単刀直入にChatGPTに聞いてみることにしました。

PHPのコードについて質問です。
■前提
/WordPress/wp-content/themes/2023v2/img/のディレクトリに、AAA.jpgという画像ファイルが存在します。他のファイルは存在しません。

その状態で、下記のコードを実行すると、結果は「存在する!CCC」を表示します。こちらの想定では「存在する!AAA」が表示されると考えます。原因は何でしょうか。

<?php

$file_path = '/WordPress/wp-content/themes/2023v2/img/AAA.jpg';

if (file_exists($file_path)){
	  print '存在する!AAA';
	}elseif (file_exists('BBB.jpg')){
	  print '存在する!BBB';
	}else{
	  print '存在する!CCC';
	}
	
?>

原因は、条件文の2つ目の`file_exists`関数の引数に`’BBB.jpg’`という文字列が直接指定されているためです。この場合、AAA.jpgが存在するにもかかわらず、条件文はfalseと評価され、次の条件文である`else if`に進みます。

正しいコードでは、次のようにファイルパスを指定する必要があります。

$file_path = '/WordPress/wp-content/themes/2023v2/img/';

if (file_exists($file_path.'AAA.jpg')) {
    print '存在する!AAA';
} elseif (file_exists($file_path.'BBB.jpg')) {
    print '存在する!BBB';
} else {
    print '存在する!CCC';
}

こうすることで、指定したフォルダ内に存在するAAA.jpgを正常に確認し、対応する条件文を実行することができます。

おお、これは自分のうっかりタイプミスが原因、恥ずかしい限りです。早速提示されたコードをそのままコピペして再びローカルでテストしてみます。
※本来ならここで、「AAA.jpg」は存在するのだから最初の条件分岐でOKと判定しないとダメなんじゃないの?という疑問を投げてみるべきでしたが、ど素人なので思い付きませんでした。

何故だ!!

前回は確かに自分のミスだったけれど、今回はジーーーーーーーッと眺めてみても、どこをどう間違えているのか分かりません。論の筋は通っているように思えるのですが、やはり何処かで自分の知識不足が原因になっているのかと考えます。AIが間違えるなんてことは無い(ハズである)。しかし全く分からない。

そこでまた少し軌道修正した質問を投げてみることにしました。ネットで見かけた「英訳して質問する」と言う方法です。しかし驚くのは、こちら側で事前に英訳するのではなく、英訳作業そのものからChatGPTに実行させると言う技です。これまでの常識を覆す手順、もし相手が人間なら躊躇われるやり取りです。絶交されるかもしれないレベル。

次の質問を英訳し、回答を考えてください。さらにその回答を日本語に翻訳し、提示してください。

PHPのコードについて質問です。
■前提
/WordPress/wp-content/themes/2023v2/img/のディレクトリに、AAA.jpgという画像ファイルが存在します。他のファイルは存在しません。

その状態で、下記のコードを実行すると、結果は「CCC」を表示します。こちらの想定では「AAA」が表示されると考えます。原因は何でしょうか。

<?php

$file_path = '/WordPress/wp-content/themes/2023v2/img/';

if (file_exists($file_path . 'AAA.jpg')) {
    print 'AAA';
} elseif (file_exists($file_path . 'BBB.jpg')) {
    print 'BBB';
} else {
    print 'CCC';
}
?>

原因は、条件文で使用されているファイルパスが正しくないためです。指定されたフォルダパス`/WordPress/wp-content/themes/2023v2/img/`は正しいですが、`file_exists`関数でチェックされるファイルパスが不足しています。

正しいファイルパスを使用するには、以下のように`file_exists`関数に渡す必要があります。

$file_path = '/WordPress/wp-content/themes/2023v2/img/AAA.jpg';

if (file_exists($file_path)) {
    print 'AAA';
} elseif (file_exists('/WordPress/wp-content/themes/2023v2/img/BBB.jpg')) {
    print 'BBB';
} else {
    print 'CCC';
}

これにより、フォルダ内に存在するAAA.jpgファイルを正常に確認し、対応する条件文を実行することができます。

得られた回答(ChatGPT側で英訳して考えてきて、そこからさらに日本語に翻訳して提示されたもの)をジーーーーーーーッと眺めてみます。

これは、マズイのではないか……。

何か、堂々巡りを始めた感じがしないでもない。とりあえずローカルで実行してみました。これまで通り、imgフォルダにはAAA.jpgしか存在しない状態なので、序盤の条件で合格して「AAA」と表示されるはずだと、こちらは密かに期待しています。

これはマズイな!!

雲行きが怪しくなってきました。突如出現した「AIの壁」をどこから切り崩していけば良いのか、すぐ思いつきません。また単刀直入に相談してみました。

画像ファイルの諸条件は変えないまま、提案されたコードを実行してみましたが、やはり結果は「CCC」と表示されてしまいます。原因は推測出来ますか?

提供されたコードを実行した場合、条件文で使用されるファイルパスは正しいため、問題は別のところにある可能性があります。以下の点を確認してください。

1. 画像ファイルの拡張子が.jpgであることを確認してください。.pngファイルが存在する場合、条件文で指定されているファイル名と異なるため、正しくファイルの存在を確認できません。
2. ファイルのパーミッションが正しく設定されているかどうかを確認してください。ファイルが読み込み可能でない場合、file_exists関数はファイルが存在しないと見なします。
3. ファイルパスが正しいディレクトリにあることを確認してください。ファイルパスに誤りがある場合、指定された場所にファイルが存在していても、正常にファイルの存在を確認できなくなる場合があります。

以上の点を確認して、問題の解決に向けて対応してください。

まじか。正論で返して来て、最後には「お前が頑張れよ」と婉曲的に言われてしまいました。笑えます。ここでグラノーラで昼飯。ブラックコーヒーで休憩。胃袋に染み渡る。

3回目の会話:さらにもっと具体的な前提条件を揃えて質問してみる

さて、窮地に追い込まれてきました。こちらが依頼主としてふさわしい一定レベルの知識を持ち合わせていなければ、正しく質問することが出来ません。現時点で出来ることと言えば、より実践的な状況を整え、そこで得られた判断材料を提示するしかありません。これまで使ってきたコードに「elseif」ブロックを挿入して、やはりダメだったのでそれを材料にします。

前提条件
■カテゴリーの番号は44
■サムネール画像は存在しない
■画像の保存ディレクトリは、/WordPress/wp-content/themes/2023v2/img/
■保存ディレクトリ内に存在する画像は、ICON_ID_44.jpg のみ

この時、下記のfunctionを実行すると、ICON_ID_44.jpg が表示されません。
ICON_ID_44.png を表示させようとします。
原因は何でしょうか?

function post_icon () {
  $cat = get_the_category();
  $cat_id = $cat[0];
  $dir = "/WordPress/wp-content/themes/2023v2/img/";
  $file_path = $dir . 'ICON_ID_' . $cat_id->cat_ID . '.jpg';
  
  if( has_post_thumbnail() ) {
    echo wp_get_attachment_url( get_post_thumbnail_id() );
  }

  elseif ( file_exists($file_path)) {
    echo $file_path;
  }

  else {
    echo $dir . 'ICON_ID_' . $cat_id->cat_ID . '.png';
  }  
}

この問題の原因は、以下の2つの条件によるものです。

1. カテゴリーの番号が44である場合、$cat_idには文字列型の’44’が代入されます。
2. ファイルの拡張子が.jpgである場合、file_exists()関数はファイルを見つけることができず、その結果としてelseブロックの中のpngファイルが選択されます。

したがって、カテゴリー番号を整数型に変換し、ファイル拡張子をjpgからpngに変更する必要があります。これらの変更を加えた修正版のコードは以下のようになります。

function post_icon () {
$cat = get_the_category();
$cat_id = intval($cat[0]->cat_ID); // カテゴリー番号を整数型に変換
$dir = "/WordPress/wp-content/themes/2023v2/img/";
$file_path = $dir . 'ICON_ID_' . $cat_id . '.png'; // ファイル拡張子をpngに変更

if( has_post_thumbnail() ) {
echo wp_get_attachment_url( get_post_thumbnail_id() );
}

elseif ( file_exists($file_path)) {
echo $file_path;
}

else {
echo $dir . 'ICON_ID_' . $cat_id . '.png';
}
}

回答は相変わらず秒速のスピードなのだけれど、その文章の内容に「?」となってしまいました。カテゴリーID番号を文字列として使用し、これまでエラー無く動作してきたので、「整数型に変更すべし」の意味がストンと腑に落ちません。さらに拡張子を「pngに変更すべし」と言っているのも、さっぱり訳が分かりませんでした。またコーヒーを飲みながらぼんやり画面を眺めます。
とりあえず言われた通りに書き換えて実行してみようと思い、Mac miniのローカルで試してみましたが、結果はダメでした。
しかし、この意味不明な提案の「意図」(意図があるとしたらですけど)が次の質問でぼんやりと分かってきました。

ICON_ID_44.jpgを表示させたいのですが、提案されたコードを実行しようとすると、elseブロックでの「ICON_ID_44.png」を表示させようと誤動作します。原因は何でしょうか?

提案されたコードを実行する場合、指定されたファイルパス `$dir . ‘ICON_ID_’ . $cat_id . ‘.png’` が存在しない場合は `else` ブロックが実行されます。この場合、`ICON_ID_44.png` が表示されます。

原因は、ファイルパスが間違っているためです。指定されたファイルパス `$dir . ‘ICON_ID_’ . $cat_id . ‘.jpg’` は、ファイルの拡張子が `.jpg` であるため、存在しないファイルとして判定され、`else` ブロックが実行されます。したがって、ファイル名を `ICON_ID_44.jpg` に変更する必要があります。

修正後のコードは以下のようになります。

function post_icon () {
  $cat = get_the_category();
  $cat_id = intval($cat[0]->cat_ID);
  $dir = "/WordPress/wp-content/themes/2023v2/img/";
  $file_path = $dir . 'ICON_ID_' . $cat_id . '.jpg'; // ファイル名を.jpgに変更
  
  if( has_post_thumbnail() ) {
    echo wp_get_attachment_url( get_post_thumbnail_id() );
  }

  elseif ( file_exists($file_path)) {
    echo $file_path;
  }

  else {
    echo $dir . 'ICON_ID_' . $cat_id . '.png';
  }  
}

さて…。これは強烈なループに嵌まり込んでしまいました。
いよいよAIの壁は聳え立ち、天上の雲を突き抜けました。この回答でChatGPTが振舞っている態度について僕に見えたのは次のような情景です。

こちらの動作検証における「(意図してない)ICON_ID_44.pngが表示されてしまう」と言う結果のゴールポストを動かさず、その検証時の行程での諸条件を「帰納的に」変更し、現時点での結果は正しいものとして代替案を提示してきた。

ちょっと戦慄しました。

分かりやすく別の状況でたとえるなら、

■前提
1. 素っ裸のオッサンが居ます。
2. 彼の目の前に小屋があります。
3. 小屋の中には警官の制服と、バレリーナの衣装があります。
4. 彼にはバレリーナの衣装を着て出てきてほしいのですが、どうしても警官の制服を着て出てきます。

Q: どうすれば良いですか?

A:小屋の中には警官の制服を1着しか置かないか、もしくは2着とも警官の制服にしておく。

伝わったでしょうか。もちろん、僕のような素人が見てもこの回答は間違っています。しかしそれは置いて、ChatGPTはきちんと文章の構造を把握し、文章構造のやり取りの中では破綻しないように返答を組み上げ取り繕っています。ちょっとこれは『2001年宇宙の旅』におけるHAL9000の「AE-35ユニットが故障したからお前ら交換してこい」案件に近い(え?)。もしかしたら、笑い話としての「とんち」を演じているのかもしれない。これが今、世間で言われている「真顔で嘘をつく」リアクションパターンの1つであるかもしれません。

ただ、ちょっと見方の角度を変えると、相談者の提供した結果は正しい(とする)ので、その結果は変えずに相談者に「寄り添い」もしくは「忖度」して、あるいは「気遣いを見せて」、途中の条件を変えてあげれば、結果は正しいものとして確定し受け入れてもらえる、と言う優しさとも捉えることが出来ます。状況によれば、ですけど。だがしかし、もし人命に関わる相談の場合、そんな事は言ってられない、恐怖です。

もう一度試してみました。

下記のコードのelseifブロックが無視されてしまいます。原因は何でしょうか?

function post_icon () {
  $cat = get_the_category();
  $cat_id = $cat[0];
  $dir = "/WordPress/wp-content/themes/2023v2/img/";
  $file_path = $dir.'ICON_ID_'.$cat_id->cat_ID.'.jpg';
  if( has_post_thumbnail() ) {
    echo wp_get_attachment_url( get_post_thumbnail_id() );
  }
  elseif (file_exists($dir.'ICON_ID_'.$cat_id->cat_ID.'.jpg')) {
    echo $dir.'ICON_ID_'.$cat_id->cat_ID.'.jpg';
  }
  else {
    echo $dir.'ICON_ID_'.$cat_id->cat_ID.'.png';
  }
}

$cat[0]でカテゴリーのオブジェクトを取得した場合、$cat_idにはカテゴリーIDではなく、カテゴリーオブジェクトが代入されてしまいます。そのため、$cat_id->cat_IDとするとエラーが発生し、elseifブロックが無視されてしまいます。修正するには、$cat_idに直接カテゴリーIDを代入するか、$cat[0]->cat_IDとしてカテゴリーIDを取得する必要があります。

返答の文章内にボールドで強調されたものが無く、もう「お前に教える気が失せてきた」と言うニュアンスを勝手に感じ取ったりします。もしかしたら連続の質問の後半では普通の口調で会話しているような空気を出しているのかもしれません。それはさておき、解決策の内容を変えては来たのですが、じっくりと読んではみたものの「いやChatGPT、それは違うよ…」と途方に暮れてしまいました。

4回目の会話:相談内容の材料をもう少し具体的なものに差し替えて、再度質問してみる

今回の会話の中盤で提示された、file_exists関数を用いた「if 〜 elseif 〜 else」の流れで問題なさそうに思うのですが、もう一度Mac miniのローカルで、変数などを極力排してベタベタな記述に修正してから挙動を確認し、やはり結果はダメだったので、使用したそれらの材料を提出してみました。

コードに間違いがあれば指摘してください。
下記のコードを実行すると、AAA.jpg BBB.jpgが存在するにも関わらず、最後のelse
ブロックが実行されてCCC.pngが表示されてしまいます。原因は何でしょうか?

前提
■画像フォルダパス /WordPress/wp-content/themes/2023v2/img/
■3つの画像ファイル AAA.jpg BBB.jpg CCC.png が存在

<?php

function post_icon () {

$file_path = '/WordPress/wp-content/themes/2023v2/img/AAA.jpg';
$file2_path = '/WordPress/wp-content/themes/2023v2/img/BBB.jpg';

if (file_exists($file_path)) {
  echo '/WordPress/wp-content/themes/2023v2/img/AAA.jpg';
} elseif (file_exists($file2_path)) {
  echo '/WordPress/wp-content/themes/2023v2/img/BBB.jpg';
} else {
  echo '/WordPress/wp-content/themes/2023v2/img/CCC.png';
}
}

?>

コードには特に構文的な間違いは見当たりません。しかし、ファイルパスに誤りがあるため、正しいファイルを参照できない可能性があります。

指定されたファイルパスは、絶対パスである必要があります。現在のコードでは、絶対パスではなく、相対パスが使用されています。これは、サイトのルートディレクトリを基準として、パスを設定しているためです。しかし、絶対パスを使用することで、ファイルの位置に関係なく、ファイルを正しく参照できます。

したがって、ファイルパスを以下のように修正することをお勧めします。

$file_path = $_SERVER['DOCUMENT_ROOT'] . '/WordPress/wp-content/themes/2023v2/img/AAA.jpg';
$file2_path = $_SERVER['DOCUMENT_ROOT'] . '/WordPress/wp-content/themes/2023v2/img/BBB.jpg';

こうすることで、ファイルの絶対パスが取得され、正しいファイルを参照できます。

これはもしや!?来たー!!!

実は、Mac miniのローカルでテストを繰り返していた中で、自分でもパスを相対パスにしたり絶対パスにしたりしてみた何らかのタイミングで、求める画像が表示された瞬間があったのです。その時は「上手く行った!」と思ったのですが、本番で使いたいように記述を変えていたらまたダメになってしまう…と言うことを幾度も繰り返していました。
今回、ようやく光が見えた、と思い、まずはローカルでサンプル画像(AAA.jpg、BBB.jpg、CCC.png)を用意して、imgフォルダに置く条件を変えたり、elseifブロックでは絶対、elseブロックでは相対、など条件を変えてテストをしてみました。エラーになる場合と上手く行く場合の状況が把握出来て次第に安定してきました。

もう一つ気付いたのは、ブラウザでテストする際のキャッシュクリアするタイミングです。SafariやFirefoxでキャッシュクリアを行なっても、変更がすぐ反映されない時があり、その場合にこちらは「試してみたけどダメだった、修正するか」とすぐ別の方法に切り替えてしまうため、本来なら正解なのにタイミングのずれで機を逃してしまったことが、ここまでの作業工程内で多々あった気がします。

ここからは独り人力作業、その結果

まあ、大袈裟な見出しですが5行追加しただけです。このフェーズでの詰めは、いちいちChatGPTに質問していたら余計に時間がかかると予想されたので、チマチマと試行錯誤しながら自分でコードを整理して行きました。うまく動作する条件は把握できていて、出口は見えていたので人力手作業が楽しかったです。

これまでのコード
function post_icon () {
    if( has_post_thumbnail() ) {
  
      echo wp_get_attachment_url( get_post_thumbnail_id() );
    } else {
  	  $cat = get_the_category();
  	  $cat_id = $cat[0];
      echo '/WordPress/wp-content/themes/2023v2/img/ICON_ID_'.$cat_id->cat_ID.'.jpg';
    }
  }

これまで使って来た上のコードを基にして、ChatGPTで提案された諸々のヒントを加味しつつ、6回くらい試行錯誤して書き直し(上手く行かなくて、半角スペースを入れてみたら動作した、とか色々。キャッシュのせいかもしれませんが)、整理してみたものが下記です。後日、記憶力が衰えた自分の為に可読性を優先しました。

新しいコード
function post_icon () {
  
  $cat = get_the_category();
  $cat_id = $cat[0];
  $file_path = '/WordPress/wp-content/themes/2023v2/img/ICON_ID_'.$cat_id->cat_ID;
  $file2_path = $_SERVER['DOCUMENT_ROOT'] . $file_path . '.jpg';

  if( has_post_thumbnail() ) {
    echo wp_get_attachment_url( get_post_thumbnail_id() );
  } elseif (file_exists( $file2_path )) {
    echo $file_path . '.jpg';
  } else {
    echo $file_path . '.png';
  }
  }

10行目:$file2_pathの前後に半角スペースを入れないと動作しなかったのですが、そういうものなのでしょうか。一度も指摘されなかったけれど。

5回目の会話:感謝の意を伝える

解決しました。

良かったです!解決できて何よりです。他に何か問題があれば、いつでもお知らせください。

どうもありがとう!

どういたしまして!お役に立てて嬉しいです。何か他に質問があれば、遠慮なくお尋ねください。

ファーストコンタクトを終えて所感

今回、初めて会う未知の存在と、ある課題を解決するために協働して目標を達成した感覚というのは、それはそれはここ20年くらい味わったことのない気持ち良さがありました。バンドで音を鳴らしてみて、すべてのフィーリング、グルーヴがうまく噛み合いつつ少しデチューンして心地良い広がりを見た時のような感じ。少し誇張してますけど。

■どれだけ質問してもChatGPTは怒ったりしない■
■予想もしなかった提案をしてくる場合がある■
■ググることでは解決に辿り着けなかった■
■やたら言葉遣いが丁寧■

そして素人丸出しの超簡単なコードをアップロードして、本番でも無事動作することを確認し、コーヒーを飲みながら脱力しつつ気付いたことがありました。この爽快感の一番大きな要因。

■作業中一度も「広告」に思考を遮られることが無かった■