実現したいこと
クラスの拡張に際して生じたエラーの原因を理解し、正しい実装を知りたいです。
前提
該当のソースコードの main.php を実行すると、CommentGetter.php の 20行目でエラーメッセージが出るのですが、理由がわかりません。
エラーメッセージ
PHP Fatal error: Declaration of CommentGetter::getRows(): array must be compatible with ItemGetter::getRows($sql_info): array in /test/CommentGetter.php on line 20
該当のソースコード
php
1<?php 2/* 3main.php 4*/ 5$sql_arg = ['comment'=>'hello']; 6$instance = new CommentGetter($sql_arg); 7$comments = $instance->getRows(); 8$count = $instance->getCount(); 9var_dump($comments); 10var_dump($count);
php
1<?php 2/* 3Database.php 4*/ 5class Database 6{ 7 // データベース接続 8}
php
1<?php 2/* 3CommentGetter.php 4*/ 5 6class CommentGetter extends ItemGetter 7{ 8 private array $sql_arg; 9 private ?string $page_name; 10 private array $sql_info; 11 12 public function __construct(array $sql_arg, string $page_name = null) 13 { 14 $this->sql_arg = $sql_arg; 15 $this->page_name = $page_name; 16 $this->sql_info = $this->get_sql_info(); 17 } 18 19 // アイテムの取得 20 public function getRows(): array 21 { 22 $rows = parent::getRows($this->sql_info); 23 return array_map('set_tags_to_row', $rows); 24 } 25 26 // 件数の取得 27 public function getCount(): int 28 { 29 return parent::getCount($this->sql_info); 30 } 31 32 // $sql_arg からクエリ生成情報( $sql_info ) を取得 33 private function get_sql_info(): array 34 { 35 // 例としてこのような返り値です 36 return [ 37 // アイテムの取得で使うクエリと置換値の情報 38 'sql' => 'SELECT...', 39 'bind_info' => ['comment'=>'hello', 'limit'=>20], 40 // 件数の取得で使うクエリと置換値の情報 41 'sql_count' => 'SELECT COUNT(*)...', 42 'bind_info_count' => ['comment'=>'hello', 'limit'=>20] 43 ]; 44 } 45}
php
1<?php 2/* 3ItemGetter.php 4*/ 5 6class ItemGetter 7{ 8 private $db; 9 10 public function __construct() 11 { 12 $this->db = Database::getInstance('db1'); 13 } 14 15 // アイテムの取得 16 public function getRows($sql_info): array 17 { 18 try { 19 $stmt = $this->$db->prepare($sql_info['sql']); 20 foreach ($sql_info['bind_info'] as $key => $val) 21 $stmt->bindValue(':' . $key, $val, get_pdo_type($val)); 22 $stmt->execute(); 23 return $stmt->fetchAll(); 24 } catch (Exception $e) { 25 var_dump($e); 26 var_dump($stmt); 27 } 28 } 29 30 // 件数の取得 31 public function getCount($sql_info): int 32 { 33 try { 34 $stmt = $this->$db->prepare($sql_info['sql_count']); 35 foreach ($sql_info['bind_info_count'] as $key => $val) 36 $stmt->bindValue(':' . $key, $val, get_pdo_type($val)); 37 $stmt->execute(); 38 return (int)$stmt->fetchColumn(); 39 } catch (Exception $e) { 40 var_dump($e); 41 var_dump($stmt); 42 } 43 } 44 45}
PHP
1<?php 2/* 3functions.php 4*/ 5 6// bindValue の第三引数の取得 7function get_pdo_type($val) 8{ 9 if (is_int($val)) return PDO::PARAM_INT; 10 else if (is_bool($val)) return PDO::PARAM_BOOL; 11 else if (is_null($val)) return PDO::PARAM_NULL; 12 else if (is_string($val)) return PDO::PARAM_STR; 13 else return false; 14} 15 16// DBからの取得をコメント情報として整形 17function row_to_comment(array $row) 18{ 19 return $row; 20}
試したこと ~その1~
エラーを参考にして、次のように getRows() と getCount() に $sql_arg を持たせました。
そして main.php での実行に際しても $sql_arg の引数を渡しました。
するとエラーはなくなりました。
PHP
1<?php 2/* 3CommentGetter.php 4*/ 5 6class CommentGetter extends ItemGetter 7{ 8 // 略 9 10 // アイテムの取得 11 public function getRows($sql_arg): array 12 { 13 // 略 14 } 15 16 // 件数の取得 17 public function getCount($sql_arg): int 18 { 19 // 略 20 } 21 22 // 略 23}
PHP
1<?php 2/* 3main.php 4*/ 5$sql_arg = ['id'=>1]; 6$instance = new CommentGetter($sql_arg); 7$comments = $instance->getRows($sql_arg); 8$count = $instance->getCount($sql_arg); 9var_dump($comments); 10var_dump($count);
試したこと ~その2~
また、CommentGetter{} 内の関数を別名にすることでもエラーはなくなりました。
つまり getRows() を getRows2() にし、getCount() を getCount2() にするという次の修正です。
この場合 main.php は当初ままでできました。
PHP
1<?php 2/* 3CommentGetter.php 4*/ 5 6class CommentGetter extends ItemGetter 7{ 8 // 略 9 10 // アイテムの取得 11 public function getRows2(): array 12 { 13 // 略 14 } 15 16 // 件数の取得 17 public function getCount2(): int 18 { 19 // 略 20 } 21 22 // 略 23}
以上、試したことの2つはいずれでもエラーをなくせばのですが、そもそもなぜ当初、該当のソースコードでエラーが出たのかがよく理解できません。
私の理解はこうです。
CommentGetter{} 内の getRows() には引数がないのだから、main.php での $comments = $instance->getRows(); に際してだって引数は不要はなず。
そして CommentGetter{} 内の getRows() 内の parent::getRows($this->sql_info); で引数を渡しているのですから、ItemGetter 内の getRows() は引数がなくて困ることもないはず。
と、このような理解なので、なぜ当初、該当のソースコードでエラーが出たのか?がよく理解できません。
もちろん、試したことの2つがこのエラーをどう乗り越えたのか?も理解できません。
結局ベストな解決方法は?という点もです。
改めまして、これらの3点についてどなたかご教示頂けませんでしょうか?
よろしくお願い致します。
補足情報(FW/ツールのバージョンなど)
PHP 8.1.9 です。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/05/16 03:44