icon
Let's create! WordPressサイト制作とメンテ/エラー対応から、PHP/CSS/javascriptプログラミング、動画・音・イラスト等制作まで扱うコラム

【PHPエラー対処】Typed property 〇〇 must not be accessed before initializationの対応

更新: 2024/09/09 3675文字

今回は、管理人が最近開発していたAIが自動投稿するssfナビゲーターブログで出てきた、PHPのエラー対応をします。メッセージを見た感じだと、AIは関係なくて、PHPオブジェクト型で、プロパティにアクセスできないみたいな様子。さっそく対処してみましょう。

エラー状況と構成ファイルなど

該当のdbConnectAndGetClass.phpと、ビュー部分archive.php

今回のエラーファイルの構成なんですけど、データベース接続やページネーションとかいろいろまとめたクラス『dbConnectAndGetClass』と、ビューになる『archive.php』を作っておきました。dbConnectAndGetClassは全部書くと長いので一部省略しています。エラーポイントになるとこだけ残しています。

■dbConnectAndGetClass.php
class dbConnectAndGetClass {
 const DSN = 〇〇;
 const USER = 〇〇;
 const PASSWORD = 〇〇;
 public int $postcount;

  function __construct() {
   接続などの処理
  }

  function getAutoPost($dbh) {
   $front_html =〇〇;
   $cat_slug = 〇〇;
   $imgpass = 〇〇;
   $sql = 〇〇;
   $statement = $dbh -> prepare($sql);
   $statement ->execute();
   $postcount = $statement -> rowCount();
   var_dump($postcount);
~中略~
  }

  function echoPagination() {
   $num = $this->postcount;
   if($num > 10){
ページネーション出力処理
   }
~中略~
  }

}

ビュー部分archive.phpは端折りましたが、基本的にはdbConnectAndGetClass.phpをロードしてインスタンス化、メソッド&プロパティアクセスという、よくある書き方です。メインの記事出力部分はnew dbConnectAndGetClassした段階で実行されます。

■archive.php
<div class=”autoblog-wrap” >
<ul id=”autoblog-archive”>
<?php
require_once('./controllers/dbConnectAndGetClass.php');
$inst =new dbConnectAndGetClass();
?>
</ul>
</div>
<?php echo $inst->postcount . '件';?>
~中略~
<?php $inst->echoPagination();?>

また、$inst->postcountというのは取得件数にアクセスしようとしています。

エラー発生例~件数のプロパティにアクセスできてないっぽい?

で、発生したエラーメッセージがこちら。$postcountでヒットした件数とって表示したり、ページネーション表示に使おうとしていますが、エラーになっていますね。

Fatal error: Uncaught Error:
Typed property dbConnectAndGetClass::$postcount must not be accessed before initialization in
C:xammpのパス\archive.php:40
Stack trace: #0 {main} thrown in C:xammpのパス\archive.php on line 40

スクショで見てみるとこんな感じ。上の方のトータル件数は、件数をメソッド内部でvar_dumpしていますが、そのまま出ています。

問題はここですねー。$instがdbConnectAndGetClassのインスタンスなんですけど、プロパティpostcountへのアクセスがダメです(Typed property must not be accessed before initialization)。この時点で処理は止まってるので、下の部分はもう出ません。ここら辺を修正してみましょうか。

対処法~$this->〇〇を追加してみる

ではコードを見ていきましょう。 件数をとるため、dbConnectAndGetClassのプロパティとして、$postcountを設定しています。クラス外のファイルからアクセスしているため『private property』にしてしまうと、エラーが出て動きませんでした。(アクセス修飾子がpublicだとokでした。privateでも大丈夫な書き方があるかもしれません)

で、アクセスできなかった原因はここかな、ということでコードを追加。 『$this->postcount = $postcount;』を追加しました。プロパティは宣言したけど、実際は値が入ってない、みたいなことがありますからね~。

念のため、件数でページネーションを出力するメソッドにも記載。

対応結果です。 今回のケースでは、値セットで初期化できたもようです。エラーで出なかった件数やページネーションも出るようになりました。

また、今回出たエラーの関連で、PHPマニュアルを確認しました。『型付きプロパティにアクセス』というところです。『型付きプロパティは、アクセスする前に初期化しなければいけません』とのことです。管理人は値セットで初期化しましたが、こういうのをやっていないでアクセスした場合『Typed property must not be accessed before initialization』となっているようです。

 

単純に初期値だとダメなケース~実際の値が入っていない

initializationていうくらいだから『単純に初期値を設定すればよいか』となりますが、『上記の初期値設定コードを書いただけで、$this->postcount = $postcount;のように実際の値をセットしない』のはダメでした。

この場合実際の値が入らないので、データベースから20件記事を取って20件表示していても、初期値のままで(1のまま)です。10件でページネーションみたいなのも機能しません。

あとがき・まとめ

  • 型付きプロパティに初期化しないでアクセスすると、Typed property must not be accessed before initializationエラーになる
  • 初期値をセットすれば上記のエラーは出ないが、実際の値がきちんとセットされないことで、想定した動作にならないことがある

まとめると、こんなところでしょうか。このエラーは初めて見ましたけど、対応できたようでよかったです。


【カテゴリ】- PHP
【タグ】-

関連記事