@mickie1230

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

PHP7からPHP8への移行(2)

Q&A

Closed

解決したいこと

mysqlとPHP7にてデータベースを作成していましたが、PHP8への対応作業を始めています。
この過程においてエラーが発生しました。
PHP7では動作していたのですがPHP8では動作しません。いくつか原因があるようですが特定できず困っています。
類似したケースで解決したことがあり、その事例を参考にできるかと思ったのですが、それも叶わず。

おそらく根本的なミスだとは思うのですが、どうかご教示いただけますと幸いです。

発生している問題・エラー


Warning: Undefined array key 
Warning: Attempt to read property

該当するソースコード

if (isset($_POST['公演ID'])) {
try {
// UPDATE文を発行
$kouenID = $_POST['公演ID']; // UPDATEするレコードのID
$liveID = $_POST['ライブID']; // UPDATEするレコードのID
$tourID = $_POST['ツアーID']; // UPDATEするレコードのID
$Bkubun = $_POST['大区分']; // UPDATEするレコードのID
$Mkubun = $_POST['中区分']; // UPDATEするレコードのID
$tourtitle = $_POST['ツアータイトル']; // UPDATEするレコードのID
$subtitle = $_POST['サブタイトル']; // UPDATEするレコードのID

$number = isset( $_POST['number']) ? $_POST['number'] : '';
$livedate = isset( $_POST['livedate']) ? $_POST['livedate'] : '';
$livetime = isset( $_POST['livetime']) ? $_POST['livetime'] : '';
$hallID = isset( $_POST['hallID']) ? $_POST['hallID'] : '';
$hall = isset( $_POST['hall']) ? $_POST['hall'] : '';
$pref = isset( $_POST['pref']) ? $_POST['pref'] : '';
$city = isset( $_POST['city']) ? $_POST['city'] : '';
$beforafter = isset( $_POST['beforafter']) ? $_POST['beforafter'] : '';
$setlist = isset( $_POST['setlist']) ? $_POST['setlist'] : '';
$countID = isset( $_POST['countID']) ? $_POST['countID'] : 0;
$text1 = isset( $_POST['text1']) ? $_POST['text1'] : '';
$text2 = isset( $_POST['text2']) ? $_POST['text2'] : '';
$media = isset( $_POST['media']) ? $_POST['media'] : '';
$participation = isset( $_POST['participation']) ? $_POST['participation'] : '';
$sponsored = isset( $_POST['sponsored']) ? $_POST['sponsored'] : 0;
$manned = isset( $_POST['manned']) ? $_POST['manned'] : 0;
$LL = isset( $_POST['LL']) ? $_POST['LL'] : 0;
$held = isset( $_POST['held']) ? $_POST['held'] : 0;


$sql = "UPDATE 公演マスタ SET 公演順 = :number,公演日 = :livedate,昼夜区分 = :livetime,会場ID = :hallID,会場 = :hall,都道府県 = :pref,都市 = :city,前後半 = :beforafter,セトリパターン = :setlist,カウント区分 = :countID,備考1 = :text1,備考2 = :text2,映像化 = :media,参戦 = :participation,主催フラグ = :sponsored,有人ライブフラグ = :manned,LLフラグ = :LL,開催フラグ = :held where 公演ID=$kouenID";

$stmt = $dbh->prepare($sql);

$stmt->execute([":number" => $number,":livedate" => $livedate,":livetime" => $livetime,":hallID" => $hallID,":hall" => $hall,":pref" => $pref,":city" => $city,":beforafter" => $beforafter,":setlist" => $setlist,":countID" => $countID,":text1" => $text1,":text2" => $text2,":media" => $media,":participation" => $participation,":sponsored" => $sponsored,":manned" => $manned,":LL" => $LL,":held" => $held]); // 連想配列でバインド


					print("<h2><font color=red>レコードを更新しました</font></h2>");
				}catch (PDOException $e) {
					print $e->getMessage() . "<br/>";
					die();
				}
			}
?>

<?php
$sql="SELECT 公演ID, ツアーID, ライブID, セットリスト照合キー, 大区分, 中区分, ツアータイトル, サブタイトル, 公演順, 公演日, 昼夜区分, 会場ID, 会場, 都道府県, 都市, 前後半, セトリパターン, カウント区分, 備考1, 備考2, 映像化, 参戦, 主催フラグ, 有人ライブフラグ, LLフラグ, 開催フラグ, 元日程フラグ, 振替フラグ FROM 公演マスタ where 公演ID=:kouenID";
$stmt = $dbh->prepare($sql); 
$stmt->bindValue(':kouenID', $_GET['公演ID'], PDO::PARAM_INT);     //ここがエラー?
$stmt->execute();
$alive = $stmt->fetch(PDO::FETCH_OBJ); 
?>

<table class="table852">
<tr>
<td width=80 class="body1">公演ID</td><td width=50 class="body2"><?php echo $alive->公演ID ?></td><td colspan=4>(主キー:振替が生じた時は再付番)</td></tr>     //ここがエラー?
<tr><td class="body1">ライブID</td><td class="body2"><?php echo $alive->ライブID ?></td><td colspan=4>(振替が生じた場合、振替前後が同じキー)</td>
</tr>
<tr>
<td class="body1">ツアーID</td><td class="body2"><?php echo $alive->ツアーID ?></td>
<td width=80 class="body1">大区分</td><td width=160 class="body2"><?php echo $alive->大区分 ?></td>
<td width=80 class="body1">中区分</td><td width=160 class="body2"><?php echo $alive->中区分 ?></td>
</tr>
<tr>
<td colspan=2 class="body1">ツアータイトル</td><td colspan=5 class="body2"><?php echo $alive->ツアータイトル ?></td></tr>
<tr><td colspan=2 class="body1">サブタイトル</td><td colspan=5 class="body2"><?php echo $alive->サブタイトル ?></td>
</tr>
</table>
<p>
<table class="table852">
<tr>
<td width=52 class="body1">公演順</td><td width=28 class="body2"><?php echo $alive->公演順 ?></td>
<td width=54 class="body1">公演日</td><td width=100 class="body2"><?php echo $alive->公演日 ?></td>
<td width=68 class="body1">昼夜区分</td><td width=38 class="body2"><?php echo $livetime; ?></td>
<td width=52 class="body1">前後半</td><td width=72 class="body2"><?php echo $alive->前後半 ?></td>
<td width=120 class="body1">セトリパターン</td><td width=38 class="body2"><?php echo $alive->セトリパターン ?></td>
</tr>
</table>
<p>
<table class="table852">
<tr>
<td width=52 class="body1">会場ID</td><td width=72 class="body2"><?php echo $alive->会場ID ?></td>
<td width=35 class="body1">会場</td><td width=220 class="body2"><?php echo $alive->会場 ?></td>
<td width=64 class="body1">都道府県</td><td width=72 class="body2"><?php echo $alive->都道府県 ?></td>
<td width=35 class="body1">都市</td><td width=72 class="body2"><?php echo $alive->都市 ?></td>
</tr>
</table>
<p>
<table class="table852">
<tr>
<td width=52 class="body1">備考1</td><td class="body2" width =440><?php echo $alive->備考1 ?></td>
</tr>
<tr>
<td class="body1">備考2</td><td class="body2"><?php echo $alive->備考2 ?></td>
</tr>
</table>
<p>
<table class="table852">
<tr>
<td class="body1">カウント区分</td><td class="body2" width=25><?php echo $alive->カウント区分 ?></td>
<td class="body1">主催フラグ</td><td class="body2" width=25><?php echo $alive->主催フラグ ?></td>
<td class="body1">有人ライブフラグ</td><td class="body2" width=25><?php echo $alive->有人ライブフラグ ?></td><td colspan=2></td>
</tr>
<tr>
<td class="body1">開催フラグ</td><td class="body2"><?php echo $alive->開催フラグ ?></td>
<td class="body1">LLフラグ</td><td class="body2"><?php echo $alive->LLフラグ ?></td>
<td class="body1">映像化</td><td class="body2"><?php echo $alive->映像化 ?></td><td width=30></td>
<td width=35 class="body1">参戦</td><td class="body2" width=25><?php echo $alive->参戦 ?></td>
</tr>
</table>

### 自分で試したこと
「ここがエラー?」と記載している箇所に当たりをつけるも、解決の糸口が見つからず。
0 likes

1Answer

Warning: Undefined array key で検索すれば情報が出てくると思いますが、 PHP 8 では配列や連想配列に未定義のキーを指定すると警告が出ます。 isset( $_GET['公演ID'] ) で存在確認してください。キーが存在しない場合や、キーがあっても対応するレコードが存在しない場合、後半の <table> の代わりにエラーメッセージを表示する処理にするのがベターです。また4行目あたりのコードでも同様にキーの存在確認をしてください。

本題から外れますが、1つ目の SQL にある where 公演ID=$kouenID ように、変数展開でユーザー入力を埋め込むのは SQL インジェクション攻撃に対して脆弱であり、極めて危険です。必ず where 公演ID=:kouenID のようにパラメータバインディングを使ってください。前回の質問にも同じ脆弱性があったのでコード全体を見直すことをお勧めします。

1Like

Comments

  1. XSSも可能に見えるので外部に公開して良いシステムでは無いですね...適当なフレームワークを使用し、全体をまともなシステムとして設計し直しすことをおすすめします。このままだと閲覧者に迷惑をかける可能性が残り続けます。

  2. @mickie1230

    Questioner

    ご教示いただきありがとうございます。
    色々試行錯誤をして、なんとか動くようになりました。

    セキュリティ面、ずっと気に放っていたのですがどう対処すればいいのか未だわかっていないというのが本当のところです。
    1年ほどかけて独学で、色々情報を集めながら仕上げているという状態で、ここ1〜2ヶ月でようやく入力フォームを作るようになったという状況です。
    お仕事で作成されている皆さんからすれば「片手間になんとなく作ってる」と思われかねない状況です。本当に申し訳ありません。
    引き続き勉強を続けます。

  3. 仕事か趣味か学習かは関係なく、外部に公開しているかどうかが問題です。
    外部に公開しているモノなら最低限のセキュリティ対策が必要です。他人に迷惑をかけます。
    学習用でローカルで動かしているだけなら全く問題ありません。
    バージョンアップ対応という事だったので、稼働中の既存システムへの対応だと早合点しました。

  4. @mickie1230

    Questioner

    当然のことですがローカルでのみ使用しています。

Your answer might help someone💌