teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

修正

2019/05/01 08:23

投稿

m.ts10806
m.ts10806

スコア80888

answer CHANGED
@@ -164,7 +164,7 @@
164
164
  <?php
165
165
  foreach($input_config as $input_name=>$setting){
166
166
  echo '<p>';
167
- if(ak('required',$setting)){
167
+ if(ak('required',$setting) && $setting['required']){
168
168
  echo '(必須)';
169
169
  }
170
170
  echo $setting['label'];

2

修正

2019/05/01 08:22

投稿

m.ts10806
m.ts10806

スコア80888

answer CHANGED
@@ -25,4 +25,248 @@
25
25
  入力値の出力にHTMLエスケープが施されてないですね。
26
26
 
27
27
  ---
28
+
29
+ 入力画面includeを生かして適当に組みなおしたコード
30
+ 適当に役割分担。Validationのところとか入力フォーム表示とかClassでやったほうがそれっぽい感じになるので望ましい。(今回の内容だけでもオレオレフレームワーク一歩手前)
31
+
32
+ ※[返り値の型宣言](https://www.php.net/manual/ja/functions.returning-values.php#functions.returning-values.type-declaration)とか使ってるのでPHP7以上でのみ動作可能
33
+
34
+ helper.php
35
+ ```php
36
+ <?php
37
+ //二重定義阻止
38
+ if(!function_exists('h')){
39
+ function h($str)
40
+ {
41
+ return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
42
+ }
43
+
44
+ }
45
+ if(!function_exists('ak')){
46
+ function ak($key,array $array):bool
47
+ {
48
+ return array_key_exists($key,$array);
49
+ }
50
+ }
51
+ if(!function_exists('iar')){
52
+ function iar($key,array $array):bool
53
+ {
54
+ return in_array($key,$array);
55
+ }
56
+ }
57
+ ```
58
+
59
+ input_config.php
60
+ ```php
61
+ <?php
62
+ return [
63
+ 'name'=>[
64
+ 'label'=>'名前',
65
+ 'type'=>'text',
66
+ 'required'=>true,
67
+ 'validation'=>'required'
68
+ ],
69
+ 'age'=>[
70
+ 'label'=>'年齢',
71
+ 'type'=>'text',
72
+ 'required'=>true,
73
+ 'validation'=>'required|number'
74
+ ],
75
+ 'color'=>[
76
+ 'label'=>'好きな色',
77
+ 'type'=>'checkbox',
78
+ 'select'=>['赤','緑','青']
79
+ ],
80
+ ];
81
+ ```
82
+
83
+ validation.php
84
+ ```php
85
+ <?php
86
+ function validation():array
87
+ {
88
+ $input_config = require_once 'input_config.php';
89
+
90
+ $err = [];
91
+ foreach($input_config as $input_name=>$setting){
92
+ if(ak('validation',$setting)){
93
+ $vali = explode('|',$setting['validation']);
94
+ foreach($vali as $checktype){
95
+ $check_name = $checktype.'Check';
96
+ $res = false;
97
+ if(function_exists($check_name)){
98
+ switch($checktype){
99
+ default:
100
+ $res = $check_name(filter_input(INPUT_POST, $input_name),$setting['label']);
101
+ }
102
+ if($res){
103
+ $err[$input_name][] = $res;
104
+ }
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ return $err;
111
+ }
112
+
113
+ function requiredCheck(string $value,string $name)
114
+ {
115
+ if(trim($value) === ''){
116
+ return $name.'を入力してください';
117
+ }
118
+ return false;
119
+ }
120
+ function numberCheck(string $value,string $name)
121
+ {
122
+ if(!empty($value) && !(ctype_digit($value))){
123
+ return $name.'は整数を入力してください';
124
+ }
125
+ return false;
126
+ }
127
+ ```
128
+
129
+ test1.php
130
+ ```php
131
+ <?php
132
+ require 'helper.php';
133
+ $input_config = require 'input_config.php';
134
+ if(!isset($err)){
135
+ $err = [];
136
+ }
137
+
138
+ ?>
139
+ <!DOCTYPE html>
140
+ <html lang="ja">
141
+ <head>
142
+ <meta charset="UTF-8">
143
+ <title>入力</title>
144
+ <style>
145
+ h1 {
146
+ color: #f00
147
+ }
148
+ .error {
149
+ color: #f00
150
+ }
151
+ </style>
152
+ <script>
153
+ function check(){
154
+ if(!confirm('送信してよろしいですか?')){
155
+ return false;
156
+ }
157
+ }
158
+ </script>
159
+ </head>
160
+ <body>
161
+ <h1>お問合せ画面</h1>
28
- 後ほど適当に組みなしたコード投稿するのであとは頑張って理解してみてください
162
+ <h2>問合せ内容入力してください</h2>
163
+ <form action="test2.php" method="post" onSubmit="return check()">
164
+ <?php
165
+ foreach($input_config as $input_name=>$setting){
166
+ echo '<p>';
167
+ if(ak('required',$setting)){
168
+ echo '(必須)';
169
+ }
170
+ echo $setting['label'];
171
+ switch($setting['type']){
172
+ case 'text':
173
+ $input_data = filter_input(INPUT_POST,$input_name);
174
+ echo '<input name="'.$input_name.'" value="'.h($input_data).'">';
175
+ break;
176
+ case 'checkbox':
177
+ $input_data = filter_input(INPUT_POST,$input_name, FILTER_DEFAULT, [
178
+ 'flags' => FILTER_REQUIRE_ARRAY
179
+ ]);
180
+ if(ak('select',$setting) && is_array($setting['select'])){
181
+ if(is_null($input_data)){
182
+ $input_data = [];
183
+ }
184
+ foreach($setting['select'] as $in=>$val){
185
+ echo '<input type="checkbox" name="'.$input_name.'[]" value="'.$in.'"'.(iar($in,$input_data)?' checked':'').'>'.$val.'&nbsp;';
186
+ }
187
+ }
188
+ break;
189
+ }
190
+ echo '</p>';
191
+ if(ak($input_name,$err)){
192
+ echo '<span class="error">'.implode('<br />',$err[$input_name]).'</span>';
193
+ }
194
+ }
195
+ ?>
196
+ <input type="submit" value="送信">
197
+ </form>
198
+ </body>
199
+ </html>
200
+ <?php
201
+ exit();
202
+ ```
203
+
204
+ test2.php
205
+ ```php
206
+ <?php
207
+ if($_SERVER['REQUEST_METHOD'] !== 'POST'){
208
+ require_once 'test1.php';
209
+ }
210
+ require 'helper.php';
211
+ require_once 'validation.php';
212
+
213
+ $err = validation();
214
+
215
+ if (count($err) > 0) {
216
+ require_once 'test1.php';
217
+ }
218
+ $input_config = require 'input_config.php';
219
+ ?>
220
+ <!DOCTYPE html>
221
+ <html lang="ja">
222
+ <head>
223
+ <meta charset="UTF-8">
224
+ <title>送信</title>
225
+ </head>
226
+ <body>
227
+ <h1 class="red">お問合せ完了画面</h1>
228
+ <h2>送信しました</h2>
229
+ <table border="1">
230
+
231
+ <?php
232
+ foreach($input_config as $input_name=>$setting){
233
+ echo '<tr>';
234
+ echo '<td>'.$setting['label'].'</td>';
235
+ echo '<td>';
236
+ switch($setting['type']){
237
+ case 'text':
238
+ $input_data = filter_input(INPUT_POST,$input_name);
239
+ echo h($input_data);
240
+ break;
241
+ case 'checkbox':
242
+ $input_data = filter_input(INPUT_POST,$input_name, FILTER_DEFAULT, [
243
+ 'flags' => FILTER_REQUIRE_ARRAY
244
+ ]);
245
+ if(ak('select',$setting) && is_array($setting['select'])){
246
+ if(is_null($input_data)){
247
+ $input_data = [];
248
+ }
249
+ foreach($setting['select'] as $in=>$val){
250
+ if(iar($in,$input_data)){
251
+ echo $val.'&nbsp';
252
+ }
253
+ }
254
+ }
255
+ break;
256
+ }
257
+ echo '</td>';
258
+ echo '</tr>';
259
+ }
260
+ ?>
261
+ </table>
262
+ </body>
263
+ </html>
264
+ <?php
265
+ exit();
266
+ ```
267
+
268
+ includeでの別画面表示をいかしたためにhelperで二重定義防止をしていますが
269
+ ビューファイルはやはり1画面1つにしたほうがいいと思う。
270
+
271
+ 入力チェック後入力画面をそのまま入力値を初期値で表示させるなら入力チェックは自画面で行ったほうが良いと思います。
272
+ リダイレクトするとか、リダイレクトが嫌ならJavaScriptでするとか、サーバーサイドでチェックしたいならAjaxでするとか、方法は幾らでもあります。

1

修正

2019/05/01 05:02

投稿

m.ts10806
m.ts10806

スコア80888

answer CHANGED
@@ -22,5 +22,7 @@
22
22
 
23
23
  echo書いたり<?=とshort tag使っていたり、コーディングに統一性がないのもよろしくない。
24
24
 
25
+ 入力値の出力にHTMLエスケープが施されてないですね。
26
+
25
27
  ---
26
28
  後ほど適当に組みなおしたコードを投稿するのであとは頑張って理解してみてください。