【PHP7から8へ切替】Warning: Undefined variableが表示された場合の修正方法

【PHP7から8へ切替】Warning: Undefined variableが表示された場合の修正方法セキュリティ
この記事は約13分で読めます。

こんにちは。IT解決コラム編集部です。

先日、当社では現在運用に携わっているサイトを「PHP8」にバージョンアップしました。これからバージョンアップを行うという方々も多い中、「PHP8にバージョンアップをしたらエラーまみれになった」のではないでしょうか?

実際にXで検索をしたところ、様々なユーザーがPHP8にバージョンアップしたことで、エラーコードに悩まされていることが分かりました。

PHP8ではたくさんの新機能が追加され、よりコーディングしやすい言語に仕様変更されています。しかし、下位互換性のない変更点もあったため、移行時に不具合が発生しないよう対応が必要になります。バージョンを上げる前に必ずテストするようにしましょう

今回はPHPのバージョンを7から8にアップデートした際の様々な不具合とその対処法を、備忘録としてまとめてご紹介します。

PHP8でエラーが出るようになった原因について

簡潔に言うと、PHP7では通知として許容されていたものが、バージョン8からは独立したエラーとして扱われるようになりました

「書き方がより厳しくなった」というほうが伝わりやすいかもしれません。すべての通知がエラーになるわけではありませんが、エラーとして扱われるものが増えました。

その他にもかなりのボリュームの変更点があります。下位互換性のない変更点は、PHPの公式サイトにまとめられているため参考にしてみてください。

PHP8へのバージョンアップに伴うエラーへの対応

WordPressで制作したテストサイトでPHP8へのバージョンアップを試してみたところ、複数のエラーが確認できました。

テストサイトの画面
テストサイトの画面

今回の修正内容は下記の通りです。

「Warning: Undefined variable」が出た場合の対処法

「Warning: Undefined variable」は、指定している変数が定義されていない場合に発生するエラーです。

例えば、以下のコード例では変数$html$category$tagが事前に定義されてないため、PHP8.0以降のバージョンでは「Warning: Undefined variable」のエラーが発生してしまいます。

コード例(修正前)

function hoge(){
  global $post;
  $html .= '<ul>';
  // The Query

  $args = array(
    'post_type'       => 'post',
    'posts_per_page'     => '3',
    'post_status'      => 'publish',
    'category_name'    =>$category,
    'tag'    =>$tag
  );

このエラーを解消するためには、未定義の変数を初期化する必要があります。

コード例(修正後)

function hoge()
{
  global $post;
  $html = '';
  $html .= '<ul>';
  // The Query

  $args = array(
    'post_type'       => 'post',
    'posts_per_page'     => '3',
    'post_status'      => 'publish',
  );
  if (isset($category)) {
    $args['category_name'] = $category;
}

if (isset($tag)) {
    $args['tag'] = $tag;
}

このように修正すると、エラーが解消されました。

ちなみに、このような書き方をしても現在のPHP7のバージョンではエラーは起きませんでした。しかし、未定義の変数を使用すると予期しない動作やバグの原因となる可能性があるため、できるだけ初期化宣言をする慣習をつけていくことが推奨されています

「Warning: Trying to access array offset」が出た場合の対処法

上記のエラー以外にも、もう1つ「Warning: Trying to access array offset on value of type null」というエラーが発生しています。そちらについても以下でご紹介します。

「Warning: Trying to access array offset」が出た場合の対処法

「Warning: Trying to access array offset」は、「null」や「bool型(true, false)」「数値型」の変数に配列として取得しようとした際に発生するエラーです。

このエラーには以下のようなバリエーションがあります。

  • Warning: Trying to access array offset on value of type null in~
    警告:null型の値の配列オフセットにアクセスしようとしています
  • Warning: Trying to access array offset on value of type bool in~
    警告:bool型の値の配列オフセットにアクセスしようとしています
  • Warning: Trying to access array offset on value of type int in~
    警告:int型の値の配列オフセットにアクセスしようとしています

例えば、以下のようなコードの場合にもエラーが発生していました。

コード例(修正前)

function hoge()
{
  global $post;
  $tag = '';

  if ($atts['tag']) {
    $tag = $atts['tag'];
  }

  $html .= '<div class="swiper-wrapper">';
  // The Query
  $args = array(
    'post_type'       => 'post',
    'posts_per_page'     => '10',
    'post_status'      => 'publish',
    'tag'           => 'pickup',
  );

こちらの改善点としては下記の通りです。

コード例(修正後)

function hoge($atts = array()) // $atts を関数の引数として受け取る
{
  global $post;
  $tag = '';
  $html = ''; // $html を初期化

  if (isset($atts['tag'])) { // $atts['tag'] がセットされているか確認
    $tag = $atts['tag'];
  }

  $html .= '<div class="swiper-wrapper">';
  // The Query
  $args = array(
    'post_type'       => 'post',
    'posts_per_page'  => '10',
    'post_status'     => 'publish',
    'tag'             => 'pickup',
  );

  // ... 以降のコード
}

これらの変数は、定義も初期化もされていませんでした。PHP7ではこれが許容されていましたが、新しいバージョンではより厳格なルールが適用されています。

ローディング画面で固まり、エラーコードが表示されない事例も

ローディング画面で固まり、エラーコードが表示されない事例も
ローディング画面で固まり、画面全体が表示されなくなる状態に。

1つ目の事例とは異なり、エラーコードすら表示されなかったため困惑しました。しかし、ソースコードを確認したところ、以下のようになっていました。

エラーコード

専門的な知識をお持ちの方ならすぐに気付くかもしれませんが、上記キャプチャの「116行目(最後の行)」を確認すると、PHP8にアップデートした後、ここでコードが途中で終了していることが確認できます。

これらの問題の原因とその解決方法については以下の通りです。

コード例(修正前)

<h1><a href="<?php bloginfo(url); ?>"><img src="<?php bloginfo(url); ?>/wp-content/themes/mje/images/logo.png" alt="MJEロゴ" class="default-logo"><img src="<?php bloginfo(url); ?>/wp-content/themes/mje/images/scroll-logo.png" alt="MJEロゴ" class="scroll-logo"></a></h1>

コード例(修正後)

<h1><a href="<?php echo esc_url(get_bloginfo('url')); ?>"><img src="<?php echo esc_url(get_bloginfo('url') . '/wp-content/themes/mje/images/logo.png'); ?>" alt="MJEロゴ" class="default-logo"><img src="<?php echo esc_url(get_bloginfo('url') . '/wp-content/themes/mje/images/scroll-logo.png'); ?>" alt="MJEロゴ" class="scroll-logo"></a></h1>

原因を詳しく探るために、さらに深く分析していきます。

bloginfo(url)の使用をやめる

bloginfo(‘url’) は、サイトのホームURLを表示するための関数で、この関数は直接URLを出力します。

しかし、PHP8ではURLを取得する場合、get_bloginfo(‘url’)を使用することが推奨され、この部分の取り扱いがさらに厳格になったことが伺えます。

これらの修正を行ったにも関わらず、サイトはまだ正常に動作しなかったため、原因をさらに調査しました。

ページネーションの書き方にも変更点あり

ページネーションの「前のページへ戻る」「次のページへ進む」の書き方にも変更がありました。

修正前のコード

<a href="<?php echo $prev_post->guid ?>" class="page-nation__icon"><i class="fas fa-arrow-left"></i></a>

<a href="<?php echo $next_post->guid ?>" class="page-nation__icon"><i class="fas fa-arrow-right"></i></a>

修正後のコード

<a href="<?php echo get_permalink($prev_post->ID); ?>" class="page-nation__icon"><i class="fas fa-arrow-left"></i></a>

<a href="<?php echo get_permalink($next_post->ID); ?>" class="page-nation__icon"><i class="fas fa-arrow-right"></i></a>

$prev_post->guid $next_post->guidの使用が原因であり、WordPressのguidは、一般的には公開URLとして使用するべきではありません。
代わりに、get_permalink() 関数を使用して、正確なURLを取得することをおすすめします。

以上の修正を行った結果、サイトは正常に動作するようになりました。

2023年以降はPHPのバージョンは「8.1.22」が推奨に

PHPのバージョンは「8.1.22」が推奨に

「いつかPHP8にバージョンアップしなければ」と考えていて、まだ実行されていない企業のご担当者も多いのではないでしょうか?

こちらはエックスサーバーの管理画面になりますが、管理画面上では、2023年の夏まではPHPのバージョン「7.4.33」が推奨されていました。しかしながら2023年の夏から秋にかけて非推奨となりました。本記事を書いているのは2024年になりますが、今後は8.x.xxや9シリーズが主流になっていくことが確実です。

PHPにもリリースライフサイクルが2年に1回ある

他のソフトウェアと同様、PHPにもリリースライフサイクルがあり、これを遵守することで、さらなる進化と改善を繰り返すことができています。

PHPの各メジャーリリースは、通常、リリース後の2年間サポートされます。この間、バグやセキュリティの問題が定期的に修正され、パッチが適用されます。

このような大規模なバージョンアップは数年単位で発生するため避けては通れませんが、想像以上に大変な作業でした。今回の作業の中で発生したエラーへの対処は学びになりました。

PHP8へのバージョンアップのメリット

PHP8へのバージョンアップのメリット

PHP7以前のバージョンを使用している場合は、新しい機能追加やパフォーマンス向上といったバージョンアップによる恩恵を受けられないだけでなく、セキュリティ面でも問題があります
そういった意味でも、最新のバージョンを維持することが大切です

また、「PHP」のバージョンが古いために以下のような問題が起こる可能性もあります。

  • ホームページの動作が遅い
  • ホームページがハッキングされた
  • WordPressがアップデートできない

バージョンが上がるごとにセキュリティの向上やスピードアップなどの恩恵が増えるため、PHP8へのアップデートはおすすめです。

Webサイト制作はMJEにお任せ!

株式会社MJEのWEBサイトテンプレート
制作事例

最後になりますが、当社では今回ご紹介したようなPHPで動的なWebサイト制作(WordPressメイン)を行っております。
貴社が伝えたい内容をわかりやすく伝えられるよう、経験豊富なクリエイターがヒアリングからデザイン・制作、そして保守・メンテナンスまで一貫した制作体制でサポートいたします。

≫ 株式会社MJEのWebデザインのテンプレート一覧はこちら
※制作イメージをご確認いただけます。

「新しくホームページを作りたい」や「リニューアルしたい」「WordPressで簡単に更新をしたい」とお考えの方は、ぜひ一度以下のお問い合わせフォームからご相談ください!

    お問い合わせ
    弊社のプライバシーポリシーにご同意いただくものとします。事業者様向けのフォームとなっておりますので、一般の方からのお問い合わせはご遠慮ください。
    MJE@最高のオフィスづくり
    MJE@最高のオフィスづくり

    オフィス機器やネットワークに関する情報を発信します。オフィスのあらゆる課題を解決する株式会社MJE(エム・ジェイ・イー)のコラム記事です。

    MJE@最高のオフィスづくりをフォローする

    ※ 記載されている会社名および商品名は各社の商標もしくは登録商標です。
    ※ 掲載している情報は記事更新時点のものです。

    資料ダウンロード
    セキュリティ
    この記事をシェアする
    MJE@最高のオフィスづくりをフォローする
    中小企業のためのIT解決コラム
    タイトルとURLをコピーしました