エックスサーバーのログ機能が改善されたので試しにエラーログを見てみたところ、AH01071: Got error ‘PHP message: PHP Warning: Attempt to read property “xxxx” on false in /xxx/xxx on line xx というエラーが出てました。
ログを詳細に見てみると多くの送信元IPで記録されていたので、不具合対応しました。
何とか解決できたのでエラーの原因と対処方法をまとめてみました。
1.AH01071: Got error ‘PHP message: PHP Warning: Attempt to read property… とは?
1-1. 事象の再現確認
私も遭遇したこと内エラーだったのでまず再現確認から実施しました。
ただ、どうやったらエラーになるのか際限の手順がよくわからなかったので、Copilotに質問してみたところ、「子カテゴリがある親カテゴリの値を存在しない値に書き換えた場合に起きる」と回答があったので試したところ、その通りでした。
正確には以下の手順で再現できました。
- 「https://bonjiri-blog.com/other/wordpress/」という正しいURLではなく「https://bonjiri-blog.com/hogehoge/wordpress/」といった存在しない親カテゴリを指定してアクセスする
- 本来であれば、404NotFound が出てくるはずが、「Warning: Attempt to read property…」といったようなエラーが出る
2.AH01071: Got error ‘PHP message: PHP Warning: Attempt to read property… エラーの原因
functions.php が対応できていませんでした。
エラーの原因は存在しないオブジェクトに対して term_id
プロパティを読むことに失敗してエラーとなっています。
今回、以下のようなエラー内容だったので、
AH01071: Got error 'PHP message: PHP Warning: Attempt to read property "term_id" on false in ~~/functions.php on line 26
term_id
というプロパティを読み込もうとしてエラーが発生しており、その場所は functions.php の中の 26 行目 ということが分かります。
このエラーに関する背景をもう少し深堀すると、カテゴリーページで404NotFoundが出てしまう、という以下の事象に対応したときのコードが良くなくて、今回のエラーを想定したコードになっていませんでした。
この部分のコードについては別のエラーも出ており、その際にも修正していたので、今回で2度目の修正となります。。
3.AH01071: Got error ‘PHP message: PHP Warning: Attempt to read property… エラーの対処方法
上記の該当箇所に対して以下2つのチェックを追加します。
$parent_category
が false ではないことを確認$parent_category
が WordPressのエラーオブジェクトではないことを確認
具体的には以下のようなif文を追加することで対処可能です。
if ($parent_category && !is_wp_error($parent_category)) {
・・・・
}
3-1-1.修正前のプログラム
一度修正前のコードを確認します。
ハイライトの処理部分でエラーが出ていました。(エラーの Line 26 はこの中では16行目)
$child_categories = get_categories('child_of='.$parent_category->term_id);
function category_link_custom( $query = array()) {
// カテゴリーのページ送りを修正して404を回避
if(isset($query['name']) && $query['name'] === 'page' && isset($query['page'])) {
$paged = $query['page'];
if(is_numeric($paged)) {
$query['paged'] = (int) $paged;
unset($query['name']);
unset($query['page']);
}
}
// 子カテゴリーの404を回避
if (isset($query['category_name']) && strpos($query['category_name'], '/') === false && isset($query['name'])) {
$parent_category = get_category_by_slug($query['category_name']);
$child_categories = get_categories('child_of='.$parent_category->term_id);
foreach ($child_categories as $child_category) {
if( isset($query['name']) ) {
if ($query['name'] === $child_category->category_nicename) {
$query['category_name'] = $query['category_name'].'/'.$query['name'];
unset($query['name']);
}
}
}
}
return $query;
}
add_filter('request', 'category_link_custom');
3-1-2.修正後のプログラム
修正後のプログラムです。
具体的には以下のif文を追加しています。
if ($parent_category && !is_wp_error($parent_category)) {
・・・・
}
function category_link_custom( $query = array()) {
// カテゴリーのページ送りを修正して404を回避
if(isset($query['name']) && $query['name'] === 'page' && isset($query['page'])) {
$paged = $query['page'];
if(is_numeric($paged)) {
$query['paged'] = (int) $paged;
unset($query['name']);
unset($query['page']);
}
}
// 子カテゴリーの404を回避
if (isset($query['category_name']) && strpos($query['category_name'], '/') === false && isset($query['name'])) {
$parent_category = get_category_by_slug($query['category_name']);
if ($parent_category && !is_wp_error($parent_category)) {
$child_categories = get_categories(['child_of' => $parent_category->term_id]);
foreach ($child_categories as $child_category) {
if ( isset($query['name']) ) {
if ($query['name'] === $child_category->category_nicename) {
$query['category_name'] = $query['category_name'].'/'.$query['name'];
unset($query['name']);
}
}
}
}
}
return $query;
}
add_filter('request', 'category_link_custom');