質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.45%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

4回答

1893閲覧

PHPでの少し複雑な条件判定

Chandler_Bing

総合スコア673

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

2クリップ

投稿2019/07/13 17:34

編集2019/07/13 17:58

現在phpで大学受験のシステムを課題作成しています。
ユーザー(受験者が)受検したい学科などを選択し、個人情報、支払い情報を入力する。というのがシステムの流れです。

現在担当しているのが、ユーザー(受験者が)選択した、試験会場や学科がルールに沿っているかを確認する条件分岐です。

条件分岐の詳細

ユーザー(受験者)は画面に表示される項目を選択します。 ★ユーザー(受験者)選択の順序 試験グループ → 試験募集区分 → 受験日 → 学科、試験会場 ★試験グループについて イメージとしては「AO入試」、「一般入試」、「帰国子女枠」などです。 今回は画面には一つ(一般入試)しか表示されておらず、ユーザー(受験者)には選択肢はありません。 ★試験募集区分について 試験グループ(一般入試)を選択後に画面が遷移し、 画面には「前期」「中期」の二つが表示されています。 ★受験日について 試験募集区分を選択すると、ドロップダウンで選択できる受験日が表示されます。 「前期」→ 07/08 or 07/09 「中期」→ 12/10 or 12/11 が選択肢となっています。 ★学科、試験会場について 受験日を選択すると選択可能な学科と試験会場が表示されます。 前期、中期や選択肢した受験日に関わらず 学科は「経済学部」と「経営学部」、試験会場は「東京」「大阪」「福岡」が選択できます。 ★エラーを表示させる条件 同一試験募集区分で複数受験する場合 ↓ 例)前期 → 07/08 と 前期 → 07/09 を受験 例)中期 → 12/10 と 中期 → 12/11 を受験 ①試験会場は両日程とも同じでなけらばならない。 ②学科は両日程とも同じでなけらばならない。 エラーにしたいのはこの条件に反した場合のみです。 前期 → 07/08 → 経済学部、東京 と 前期 → 07/09 → 経済学部、大阪 は試験会場エラーですが 前期 → 07/08 → 経済学部、東京 と 中期 → 12/10 → 経済学部、大阪 は試験会場エラーになりません。 前期 → 07/08 → 経済学部、東京 と 前期 → 07/09 → 経営学部、東京 は学科エラーですが 前期 → 07/08 → 経済学部、東京 と 中期 → 12/10 → 経営学部、東京 は学科エラーになりません。

値を定義しているphpファイル

php

1/*定義① 2 3試験グループ 一般入試 EXAMG00001-0001 4試験募集区分 前期 EN00000-101 中期 EN00000-102 5試験日 07/08 EN10000-701 07/09 EN10000-702 12/10 EN10001-701 12/11 EN10001-702 6試験会場 東京 EN20000-101 大阪 EN20000-102 福岡 EN20000-103 7学科 経済 EN30000-001 経営 EN30000-002 8 9定義② 10 11試験日07/08 SCD000-001 12試験日07/09 SCD000-002 13試験日12/10 SCD000-003 14試験日12/11 SCD000-004 15 16試験会場 東京 PLA000-001 17試験会場 大阪 PLA000-002 18試験会場 福岡 PLA000-003 19 20学科 経済学部 CRS000-001 21学科 経営学部 CRS000-002 22 23定義①と②を結びつけるファイルがあり以下の様に定義されています。 24試験日グループと試験募集区分についてはどの様に定義されていたかは覚えていません。 25 26*/ 27 28$image = 29[ 30 31//試験グループ 32'EXAMG00001-0001' => 'something', 33 34//試験募集区分 35//前期 36'EN00000-101' => 'something', 37//中期 38'EN00000-102' => 'something', 39 40//試験日 41//07/08 42'EN10000-701' => 'SCD000-001', 43//07/09 44'EN10000-702' => 'SCD000-002', 45//12/10 46'EN10001-701' => 'SCD000-003', 47//12/11 48'EN10001-702' => 'SCD000-004', 49 50//試験会場 51//東京 52'EN20000-101' => 'PLA000-001', 53//大阪 54'EN20000-102' => 'PLA000-002', 55//福岡 56'EN20000-103' => 'PLA000-003', 57 58//学科 59//経済学部 60'EN30000-001' => 'CRS000-001', 61//経営学部 62'EN30000-002' => 'CRS000-002', 63 64];

POSTされる値をphpファイルに作成

php

1/* 2ユーザー(受験者)は以下の4つの試験を受験すると選択しました。 3 4希望試験: 5一般入試 → 前期 → 07/08 → 東京、経済学部 6一般入試 → 前期 → 07/09 → 大阪、経済学部 7一般入試 → 中期 → 12/10 → 福岡、経済学部 8一般入試 → 中期 → 12/11 → 福岡、経営学部 9 10 11エラーチェックについて: 12①試験会場についてのチェックと、学科についてのチェックは分けて行う 13②エラーの場合はエラーメッセージをechoするのみ 14③以下の配列($result)がPOSTで送信されてきます。ですので以下の$resultを使用し条件分岐をしたいです。 15 16定義を色々書きましたが、要は以下の配列がPOST時に飛んでくるので、どうしても以下の値を使用しなければなりません。 17*/ 18 19$result = array( 20 21'course'=>array( 22 '//EXAMG00001-0001/EN00000-101/EN10000-701/EN30000-001' => 'CRS000-001', 23 '//EXAMG00001-0001/EN00000-101/EN10000-702/EN30000-001' => 'CRS000-001', 24 '//EXAMG00001-0001/EN00000-102/EN10001-701/EN30000-001' => 'CRS000-002', 25 '//EXAMG00001-0001/EN00000-102/EN10001-702/EN30000-002' => 'CRS000-002', 26), 27 28'place'=>array( 29 '//EXAMG00001-0001/EN00000-101/EN10000-701/EN20000-101' => 'PLA000-001', 30 '//EXAMG00001-0001/EN00000-101/EN10000-702/EN20000-102' => 'PLA000-002', 31 '//EXAMG00001-0001/EN00000-102/EN10001-701/EN20000-103' => 'PLA000-003', 32 '//EXAMG00001-0001/EN00000-102/EN10001-702/EN20000-103' => 'PLA000-003', 33), 34 35);

問題点

エラーチェックはコメントアウトに記述した通りです。

★エラーを表示させる条件

同一試験募集区分で複数受験する場合 ↓
例)前期 → 07/08 と 前期 → 07/09 を受験
例)中期 → 12/10 と 中期 → 12/11 を受験

①試験会場は両日程とも同じでなけらばならない。
②学科は両日程とも同じでなけらばならない。

今回の $result の場合だと
一般入試 → 前期 → 07/08 → 東京、経済学部
一般入試 → 前期 → 07/09 → 大阪、経済学部
一般入試 → 中期 → 12/10 → 福岡、経済学部
一般入試 → 中期 → 12/11 → 福岡、経営学部

前期で別試験会場が選択されている。
中期では別学科が選択されている。

という点でエラーを出さなければなりません。

惜しい部分まで行くのですが、中々成功しません。

どのように判定すれば良いでしょうか。

私は以下のようにしましたが、
「前期は両試験とも同一試験会場(学科)で中期は1試験のみ受験するが、前期とは異なる試験会場(学科)を選択する」
の場合にエラーになってくれません。

今回のように前期と中期共に2試験受験す場合はエラーになりますが、、、、。
良い方法を教えて下さい。お願いします。

自作コード

php

1$courses = $result['course']; 2$early_courses = []; 3$middle_courses = []; 4$places = $result['place']; 5$early_places = []; 6$middle_places = []; 7 8//前期と中期の学科と試験会場 9foreach ($courses as $course) { 10 $early_courses[] = "EARLY_" . $course; 11} 12foreach ($courses as $course) { 13 $middle_courses[] = "MIDDLE_" . $course; 14} 15 16foreach ($places as $place) { 17 $early_places[] = "EARLY_" . $place; 18} 19foreach ($places as $place) { 20 $middle_places[] = "MIDDLE_" . $place; 21} 22 23 24$exam_error_flag_course = false; 25$exam_error_flag_place = false; 26//選択された試験の数をカウントする。$result['place']でも同じ。 27$exam_cnt = count($result['course']); 28//選択された試験のキーを取得。$result['place']でも同じ。 29$result_keys = array_keys($result['course']); 30$early_section = "EN00000-101"; 31$early_section_cnt = 0;//前期の試験がいくつ選択されているかカウント 32$middle_section = "EN00000-102"; 33$middle_section_cnt = 0;//中期の試験がいくつ選択されているかカウント 34 35$early_course_economics = "EARLY_CRS000-001"; 36$early_course_economics_cnt = 0; 37$early_course_management = "EARLY_CRS000-002"; 38$early_course_management_cnt = 0; 39 40$middle_course_economics = "MIDDLE_CRS000-001"; 41$middle_course_economics_cnt = 0; 42$middle_course_management = "MIDDLE_CRS000-002"; 43$middle_course_management_cnt = 0; 44 45 46$early_place_tokyo = "EARLY_PLA000-001"; 47$early_place_tokyo_cnt = 0; 48$early_place_osaka = "EARLY_PLA000-002"; 49$early_place_osaka_cnt = 0; 50$early_place_fukuoka = "EARLY_PLA000-003"; 51$early_place_fukuoka_cnt = 0; 52 53$middle_place_tokyo = "MIDDLE_PLA000-001"; 54$middle_place_tokyo_cnt = 0; 55$middle_place_osaka = "MIDDLE_PLA000-002"; 56$middle_place_osaka_cnt = 0; 57$middle_place_fukuoka = "MIDDLE_PLA000-003"; 58$middle_place_fukuoka_cnt = 0; 59 60 61//前期と中期の試験が複数選択されているか確認する 62for ($i = 0; $i < $exam_cnt; $i++) { 63 if ($early_section == substr($result_keys[$i], 18, 11)) { 64 $early_section_cnt++; 65 } 66 if ($middle_section == substr($result_keys[$i], 18, 11)) { 67 $middle_section_cnt++; 68 } 69} 70 71 72 /* 73 74 同一試験募集区分で複数試験が選択されている場合、 75 エラーが「出る」場合は以下である。 76 77 選択されたそれぞれの試験会場と学科をカウントした場合、 78 カウント数がもし1であればユーザー(受験者)は異なる試験会場や学科を選択肢している。 79 80 */ 81 82 //前期の試験が複数選択されている場合 83 //学科と試験会場をチェック 84 if ($early_section_cnt >= 2) { 85 foreach ($early_courses as $value) { 86 if ($value == $early_course_economics) { 87 $early_course_economics_cnt++; 88 } 89 if ($value == $early_course_management) { 90 $early_course_management_cnt++; 91 } 92 93 if ($early_course_economics_cnt == 1 || $early_course_management_cnt == 1) { 94 $exam_error_flag_course = true; 95 } 96 } 97 98 foreach ($early_places as $value) { 99 if ($value == $early_place_tokyo) { 100 $early_place_tokyo_cnt++; 101 } 102 if ($value == $early_place_osaka) { 103 $early_place_osaka_cnt++; 104 } 105 if ($value == $early_place_fukuoka) { 106 $early_place_fukuoka_cnt++; 107 } 108 109 if ($early_place_tokyo_cnt == 1 || $early_place_osaka_cnt == 1 || $early_place_fukuoka_cnt == 1) { 110 $exam_error_flag_place = true; 111 } 112 } 113 } 114 115 //中期の試験が複数選択されている場合 116 //学科と試験会場をチェック 117 if ($middle_section_cnt >= 2) { 118 foreach ($middle_courses as $value) { 119 if ($value == $middle_course_economics) { 120 $middle_course_economics_cnt++; 121 } 122 if ($value == $middle_course_management) { 123 $middle_course_management_cnt++; 124 } 125 126 if ($middle_course_economics_cnt == 1 || $middle_course_management_cnt == 1) { 127 $exam_error_flag_course = true; 128 } 129 } 130 131 foreach ($middle_places as $value) { 132 if ($value == $middle_place_tokyo) { 133 $middle_place_tokyo_cnt++; 134 } 135 if ($value == $middle_place_osaka) { 136 $early_place_osaka_cnt++; 137 } 138 if ($value == $middle_place_fukuoka) { 139 $middle_place_fukuoka_cnt++; 140 } 141 142 if ($middle_place_tokyo_cnt == 1 || $middle_place_osaka_cnt == 1 || $middle_place_fukuoka_cnt == 1) { 143 $exam_error_flag_place = true; 144 } 145 } 146 147 } 148 149 if ($exam_error_flag_course) { 150 echo "同一区分で複数の試験を受験する場合は別学科を受験できません"; 151 echo nl2br("\n"); 152 } else { 153 echo "学科問題なし"; 154 echo nl2br("\n"); 155 } 156 157 if ($exam_error_flag_place) { 158 echo "同一区分で複数の試験を受験する場合は別試験会場で受験できません"; 159 echo nl2br("\n"); 160 } else { 161 echo "試験会場問題なし"; 162 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

せっかくの課題ですしフローチャートの作成をおすすめしたい
思い切って今作成中のコードを捨ててしまい、フローチャートが完成したらその通りにプログラムを書いてみましょう

惜しい部分まで行くのですが、中々成功しません。

この考え方をしている状態はプログラム作る上ではNGです
取ってつけての繰り返しの対応になって頭の中も書いたコードもゴッチャになる寸前か既になっていると思われます

投稿2019/07/13 20:23

hentaiman

総合スコア6426

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/07/13 21:16

true or falseしかないですもんね。作り直した方がいいことも多いです。
guest

0

前期と中期を通して学科や会場が同じでなければならない
という条件は提示されてないようですが?

まあ、結論からいうと、前期は前期だけ中期は中期だけを
チョイスしてるからそうなるわけでして、
通してチェックしたいなら前期や中期を分けずに
チェックすればいいはなしですな。

あと、変数名が長いのは初見で意味がとりやすくはありますが
コードを追っていく中ではなかなか負担になるわけでして、
機能を分けて(サブルーチン化して)短い変数名にすると
目がとどきやすくなると思います。
--- 追記 ---
現在のロジックをベースにするなら…
前期/中期の処理中に学科と会場を拾っておいて
最後に突き合わせるのが簡単だと思います。

投稿2019/07/14 01:39

編集2019/07/14 01:46
takasima20

総合スコア7460

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

質問自体はつまみ食い程度にしか見てませんが、「条件判定が複雑」な場合の対処としては「判定部分を関数化して、名前を付け、可読性を高める」方法がメンテもしやすくなります。is_hoge() みたいな関数をつくり、判定部分を切り出して、if (is_hoge()) のように記述すると、読むのが楽でフローをおいやすくなります。

参考
真偽値を返す関数のネーミング

投稿2019/07/13 21:52

編集2019/07/13 22:09
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決

皆さまありがとうございます。

以下のコードででうまく行きました。

php

1$result_keys = array_keys($result['course']); 2//選択された試験の数をカウントする。$result['place']でも同じ。 3$exam_amount = count($result['course']); 4 5$early_section = "EN00000-101"; 6$early_section_cnt = 0;//前期の試験がいくつ選択されているかカウント 7$middle_section = "EN00000-102"; 8$middle_section_cnt = 0;//中期の試験がいくつ選択されているかカウント 9 10$course_economics = "CRS000-001"; 11$course_economics_cnt = 0; 12$course_management = "CRS000-002"; 13$course_management_cnt = 0; 14 15 16$place_tokyo = "PLA000-001"; 17$place_tokyo_cnt = 0; 18$place_osaka = "PLA000-002"; 19$place_osaka_cnt = 0; 20$place_fukuoka = "PLA000-003"; 21$place_fukuoka_cnt = 0; 22 23$error_msg = "問題ありません"; 24$error_flag = false; 25 26//学科と試験会場のキーを取得 27$course_key_value = array_keys($result['course']); 28$place_key_value = array_keys($result['place']); 29//選択された学科と試験会場のコードを取得 30foreach ($result['course'] as $value) { 31 $courses[] = $value; 32} 33foreach ($result['place'] as $value) { 34 $places[] = $value; 35} 36 37//キーとコードを結合する 38for ($i = 0; $i < $exam_amount; $i ++) { 39 $course_key_value[$i] .= '/' . $courses[$i]; 40} 41 42for ($i = 0; $i < $exam_amount; $i ++) { 43 $place_key_value[$i] .= '/' . $places[$i]; 44} 45 46//前期と中期の試験が複数選択されているか確認する 47foreach ($result_keys as $result_key) { 48 //前期の試験が選択されているか 49 if (strpos($result_key, $early_section) !== false) { 50 $early_section_cnt ++; 51 } 52 53 if (strpos($result_key, $middle_section) !== false) { 54 $middle_section_cnt ++; 55 } 56} 57 58//前期の試験が複数選択されていれば 59if ($early_section_cnt >= 2) { 60 61 //前期の選択学科に問題がないか 62 foreach ($course_key_value as $value) { 63 if (strpos($value, $early_section) !== false && strpos($value, $course_economics) !== false) { 64 $course_economics_cnt ++; 65 } 66 67 if (strpos($value, $early_section) !== false && strpos($value, $course_management) !== false) { 68 $course_management_cnt ++; 69 } 70 } 71 if ($course_economics_cnt == 1 || $course_management_cnt == 1) { 72 $error_flag = true; 73 $error_msg = '同一試験募集区分で複数の試験を受験する場合は同一学科しか選択できません。(前期)'; 74 } 75 //別学科が選択されていれば 76 if ($error_flag) { 77 goto endOfValidationCheck; 78 } 79 //前期の試験会場に問題がないか 80 foreach ($place_key_value as $value) { 81 if (strpos($value, $early_section) !== false && strpos($value, $place_tokyo) !== false) { 82 $place_tokyo_cnt ++; 83 } 84 85 if (strpos($value, $early_section) !== false && strpos($value, $place_osaka) !== false) { 86 $place_osaka_cnt ++; 87 } 88 if (strpos($value, $early_section) !== false && strpos($value, $place_fukuoka) !== false) { 89 $place_fukuoka_cnt ++; 90 } 91 } 92 if ($place_tokyo_cnt == 1 || $place_osaka_cnt == 1 || $place_fukuoka == 1) { 93 $error_flag = true; 94 $error_msg = '同一試験募集区分で複数の試験を受験する場合は同一試験会場でしか選択できません。(前期)'; 95 } 96 97 //学科と試験会場のカウント変数を初期化 98 $course_management_cnt = 0; 99 $course_economics_cnt = 0; 100 $place_tokyo_cnt = 0; 101 $place_osaka_cnt = 0; 102 $place_fukuoka_cnt = 0; 103 104 //別試験会場が選択されていれば 105 if ($error_flag) { 106 goto endOfValidationCheck; 107 } 108} 109 110 111//中期の試験が複数選択されていれば 112if ($middle_section_cnt >= 2) { 113 114 //中期の選択学科に問題がないか 115 foreach ($course_key_value as $value) { 116 if (strpos($value, $middle_section) !== false && strpos($value, $course_economics) !== false) { 117 $course_economics_cnt ++; 118 } 119 120 if (strpos($value, $middle_section) !== false && strpos($value, $course_management) !== false) { 121 $course_management_cnt ++; 122 } 123 } 124 if ($course_economics_cnt == 1 || $course_management_cnt == 1) { 125 $error_flag = true; 126 $error_msg = '同一試験募集区分で複数の試験を受験する場合は同一学科しか選択できません。(中期)'; 127 } 128 //別学科が選択されていれば 129 if ($error_flag) { 130 goto endOfValidationCheck; 131 } 132 //中期の試験会場に問題がないか 133 foreach ($place_key_value as $value) { 134 if (strpos($value, $middle_section) !== false && strpos($value, $place_tokyo) !== false) { 135 $place_tokyo_cnt ++; 136 } 137 138 if (strpos($value, $middle_section) !== false && strpos($value, $place_osaka) !== false) { 139 $place_osaka_cnt ++; 140 } 141 if (strpos($value, $middle_section) !== false && strpos($value, $place_fukuoka) !== false) { 142 $place_fukuoka_cnt ++; 143 } 144 } 145 if ($place_tokyo_cnt == 1 || $place_osaka_cnt == 1 || $place_fukuoka == 1) { 146 $error_flag = true; 147 $error_msg = '同一試験募集区分で複数の試験を受験する場合は同一試験会場でしか選択できません。(中期)'; 148 } 149 150 //学科と試験会場のカウント変数を初期化 151 $course_management_cnt = 0; 152 $course_economics_cnt = 0; 153 $place_tokyo_cnt = 0; 154 $place_osaka_cnt = 0; 155 $place_fukuoka_cnt = 0; 156 157 //別試験会場が選択されていれば 158 if ($error_flag) { 159 goto endOfValidationCheck; 160 } 161} 162 163endOfValidationCheck: 164 165echo $error_msg; 166

投稿2019/07/14 04:52

Chandler_Bing

総合スコア673

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/07/14 05:57 編集

こんなコードを以て「システム」とすべきではないので低評価をしています(あと回答を一切無視している)。 15年前の環境ですか? 勝手に自分で余計複雑にしてどうするんですか。これではなんのためのプログラミング言語かわかりませんね。
Chandler_Bing

2019/07/14 06:03

もしよろしければmts10806様の回答をいただけませんか。
m.ts10806

2019/07/14 06:09

他の回答者の回答を参考にすればできるのであえて私からそのままのコードを渡すことはしませんよ。 現状、全部作り直さないとどうにもならないくらいのダメコードなので、それなりの対価が発生するレベルです。 だから誰もコードで回答しないのです。
Chandler_Bing

2019/07/14 06:27

ありがとうございます。 考え直します。
hentaiman

2019/07/14 06:45

どのコードもほとんど読んではいないけど、各回答もらっておきながらgotoに行きつくとは 紙一重で天才の素質があるかもしれないが、おとなしくgoto使わない頃までcomebackすべし
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.45%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問