phpで、header関数を使って別ページに飛ぶ処理をしたいのですが、うまくいきません。
より詳しくは、
header(Location:url)を複数用意し、if文を使って飛び先のページを制御しようとすると、なぜか下にあるheader(Location:url)が先に処理されてしまう
というものです。
以下のstaff_branch.phpが問題のソースコードです。
さらに下のコードstaff_list.phpは、staff_branch.phpに飛ぶ前の(情報を渡す)ページです。
(データベースへの接続コードは、個人情報記載のため省略します)
ソース内のコメントに問題点を書いたので、どこが悪いのかご回答宜しくお願いします。
環境は、Windows10/Chrome/PHP7 です。
問題のソースコード(staff_branch.php):
php
1 2<?php 3 4if(isset($_POST['edit']) === true){//editは、buttonエレメントのname 5 if(isset($_POST['staffcode']) === false){//ラジオstaffcodeが何も選択されていなければ、staff_ng.phpに飛ぶ 6 header('Location:staff_ng.php'); 7 } 8/*ラジオstaffcodeが何かしら選択されていれば、URLパラメータにstaffcodeの値を載せて、staff_edit.phpへ飛ぶ。*/ 9 10/*ラジオstaffcodeが未選択(空っぽ)なのに、なぜか、上のif文内のheaderではなく、以下のheaderが実行されてしまう*/ 11/*以下のheaderを削除すれば、上のheaderは実行される*/ 12 $staff_code=$_POST['staffcode']; 13 header('Location: staff_edit.php?staffcode='.$staff_code); 14} 15 16if(isset($_POST['delete']) === true){//deleteはボタンエレメントのname 17 if(isset($_POST['staffcode']) === false){//ラジオstaffcodeが何も選択されていなければ、staff_ng.phpに飛ぶ 18 header('Location:staff_ng.php'); 19 } 20/*ラジオstaffcodeが何かしら選択されていれば、URLパラメータにstaffcodeの値を載せて、staff_edit.phpへ飛ぶ。*/ 21/*ラジオstaffcodeが未選択(空っぽ)なのに、なぜか、上のif文内のheaderではなく、以下のheaderが実行されてしまう*/ 22/*以下のheaderを削除すれば、上のheaderは実行される*/ 23 $staff_code=$_POST['staffcode']; 24 header('Location: staff_delete.php?staffcode='.$staff_code); 25} 26?> 27
staffcode選択画面(staff_list.php)
php
1 2データベースへの接続(個人情報が記載されているので省略) 3 4<body> 5<?php 6 print('スタッフ一覧<br><br>'); 7 8 print '<form action="staff_branch.php" method="post">'; 9 while(true){ 10 $rec = $stmt -> fetch(PDO::FETCH_ASSOC);//$stmtにはデータベースのデータが格納 11 if($rec == false){ 12 break; 13 } 14 15 print '<input type="radio" name="staffcode" value="'.$rec['code'].'">'; 16 print $rec['name']; 17 print '<br>'; 18 } 19 print '<button type="submit" name="edit">修正</button>'; 20 print '<button type="submit" name="delete">削除</button>'; 21 print '</form>'; 22 }catch(Exception $e){ 23 print('ただいまサーバーに障害が発生しております。ご迷惑おかけしております。'); 24 } 25 ?> 26<\body>
###試したこと
このコードは、2013年に書かれたあるphpの本のコードをそのまま写経したものですが、
「もしかして、この本が書かれた後にPHPやHTTPの仕様に変更があったのではないか?」
と思い、マニュアルを見てみました。
すると、2006年発表のPHP5.1.2の改訂内容に「header関数」がありました。内容は以下のとおりです:
header この関数は一度に複数のヘッダを送信できないようになりました。 これは、ヘッダインジェクション攻撃への対策です。
仮にこれの意味するところが「一つのphpプログラム内で一つのheader関数しか使えない」という意味ならば、本に書かれたコードはそれに反していることになりますが、上記以上の詳細は書いておらず、こまりました 。
今回起きた「期待と異なる挙動」と照らし合わせると、おそらく、正確には以下のような内容と思われます:
「もし一つのphpプログラムに2つ以上のheader関数が書かれた場合、最後のheader関数のみが実行され、ほかのheader関数は無視される」
しかし、
・実行後になんのnoticeもエラーメッセージを出さないのは不自然。
・仕様書にちゃんとした断りが書いていない。
・7年も前の仕様変更を見落として本を書くのはさすがに著者がうかつすぎる。
といった理由から、その線は薄いと思われます。
謎です。
###追記
解答者様のご指摘により解決しました。
header関数実行後にすぐにプログラムの処理を終了してページをジャンプするには、終了したい地点にexit()の記述が必要だったようです。
写経した書籍の公式サイト調べたら、正誤表があって、
「exitが抜けていた」
とおっしゃっていました。
環境によっては期待した挙動を示すこともあるようですが、私の環境の場合は駄目だったようです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/04/26 09:21
2019/04/26 09:44
2019/04/26 10:03 編集
2019/04/26 10:12
2019/04/26 10:41
2019/04/26 11:11
2019/04/26 11:49