回答編集履歴

3

修正

2019/05/01 08:23

投稿

m.ts10806
m.ts10806

スコア80850

test CHANGED
@@ -330,7 +330,7 @@
330
330
 
331
331
  echo '<p>';
332
332
 
333
- if(ak('required',$setting)){
333
+ if(ak('required',$setting) && $setting['required']){
334
334
 
335
335
  echo '(必須)';
336
336
 

2

修正

2019/05/01 08:22

投稿

m.ts10806
m.ts10806

スコア80850

test CHANGED
@@ -52,4 +52,492 @@
52
52
 
53
53
  ---
54
54
 
55
+
56
+
57
+ 入力画面includeを生かして適当に組みなおしたコード
58
+
59
+ 適当に役割分担。Validationのところとか入力フォーム表示とかClassでやったほうがそれっぽい感じになるので望ましい。(今回の内容だけでもオレオレフレームワーク一歩手前)
60
+
61
+
62
+
63
+ ※[返り値の型宣言](https://www.php.net/manual/ja/functions.returning-values.php#functions.returning-values.type-declaration)とか使ってるのでPHP7以上でのみ動作可能
64
+
65
+
66
+
67
+ helper.php
68
+
69
+ ```php
70
+
71
+ <?php
72
+
73
+ //二重定義阻止
74
+
75
+ if(!function_exists('h')){
76
+
77
+ function h($str)
78
+
79
+ {
80
+
81
+ return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
82
+
83
+ }
84
+
85
+
86
+
87
+ }
88
+
89
+ if(!function_exists('ak')){
90
+
91
+ function ak($key,array $array):bool
92
+
93
+ {
94
+
95
+ return array_key_exists($key,$array);
96
+
97
+ }
98
+
99
+ }
100
+
101
+ if(!function_exists('iar')){
102
+
103
+ function iar($key,array $array):bool
104
+
105
+ {
106
+
107
+ return in_array($key,$array);
108
+
109
+ }
110
+
111
+ }
112
+
113
+ ```
114
+
115
+
116
+
117
+ input_config.php
118
+
119
+ ```php
120
+
121
+ <?php
122
+
123
+ return [
124
+
125
+ 'name'=>[
126
+
127
+ 'label'=>'名前',
128
+
129
+ 'type'=>'text',
130
+
131
+ 'required'=>true,
132
+
133
+ 'validation'=>'required'
134
+
135
+ ],
136
+
137
+ 'age'=>[
138
+
139
+ 'label'=>'年齢',
140
+
141
+ 'type'=>'text',
142
+
143
+ 'required'=>true,
144
+
145
+ 'validation'=>'required|number'
146
+
147
+ ],
148
+
149
+ 'color'=>[
150
+
151
+ 'label'=>'好きな色',
152
+
153
+ 'type'=>'checkbox',
154
+
155
+ 'select'=>['赤','緑','青']
156
+
157
+ ],
158
+
159
+ ];
160
+
161
+ ```
162
+
163
+
164
+
165
+ validation.php
166
+
167
+ ```php
168
+
169
+ <?php
170
+
171
+ function validation():array
172
+
173
+ {
174
+
175
+ $input_config = require_once 'input_config.php';
176
+
177
+
178
+
179
+ $err = [];
180
+
181
+ foreach($input_config as $input_name=>$setting){
182
+
183
+ if(ak('validation',$setting)){
184
+
185
+ $vali = explode('|',$setting['validation']);
186
+
187
+ foreach($vali as $checktype){
188
+
189
+ $check_name = $checktype.'Check';
190
+
191
+ $res = false;
192
+
193
+ if(function_exists($check_name)){
194
+
195
+ switch($checktype){
196
+
197
+ default:
198
+
199
+ $res = $check_name(filter_input(INPUT_POST, $input_name),$setting['label']);
200
+
201
+ }
202
+
203
+ if($res){
204
+
205
+ $err[$input_name][] = $res;
206
+
207
+ }
208
+
209
+ }
210
+
211
+ }
212
+
213
+ }
214
+
215
+ }
216
+
217
+
218
+
219
+ return $err;
220
+
221
+ }
222
+
223
+
224
+
225
+ function requiredCheck(string $value,string $name)
226
+
227
+ {
228
+
229
+ if(trim($value) === ''){
230
+
231
+ return $name.'を入力してください';
232
+
233
+ }
234
+
235
+ return false;
236
+
237
+ }
238
+
239
+ function numberCheck(string $value,string $name)
240
+
241
+ {
242
+
243
+ if(!empty($value) && !(ctype_digit($value))){
244
+
245
+ return $name.'は整数を入力してください';
246
+
247
+ }
248
+
249
+ return false;
250
+
251
+ }
252
+
253
+ ```
254
+
255
+
256
+
257
+ test1.php
258
+
259
+ ```php
260
+
261
+ <?php
262
+
263
+ require 'helper.php';
264
+
265
+ $input_config = require 'input_config.php';
266
+
267
+ if(!isset($err)){
268
+
269
+ $err = [];
270
+
271
+ }
272
+
273
+
274
+
275
+ ?>
276
+
277
+ <!DOCTYPE html>
278
+
279
+ <html lang="ja">
280
+
281
+ <head>
282
+
283
+ <meta charset="UTF-8">
284
+
285
+ <title>入力</title>
286
+
287
+ <style>
288
+
289
+ h1 {
290
+
291
+ color: #f00
292
+
293
+ }
294
+
295
+ .error {
296
+
297
+ color: #f00
298
+
299
+ }
300
+
301
+ </style>
302
+
303
+ <script>
304
+
305
+ function check(){
306
+
307
+ if(!confirm('送信してよろしいですか?')){
308
+
309
+ return false;
310
+
311
+ }
312
+
313
+ }
314
+
315
+ </script>
316
+
317
+ </head>
318
+
319
+ <body>
320
+
321
+ <h1>お問合せ画面</h1>
322
+
55
- 後ほど適当に組みなしたコード投稿するのであとは頑張って理解してみてください
323
+ <h2>問合せ内容入力してください</h2>
324
+
325
+ <form action="test2.php" method="post" onSubmit="return check()">
326
+
327
+ <?php
328
+
329
+ foreach($input_config as $input_name=>$setting){
330
+
331
+ echo '<p>';
332
+
333
+ if(ak('required',$setting)){
334
+
335
+ echo '(必須)';
336
+
337
+ }
338
+
339
+ echo $setting['label'];
340
+
341
+ switch($setting['type']){
342
+
343
+ case 'text':
344
+
345
+ $input_data = filter_input(INPUT_POST,$input_name);
346
+
347
+ echo '<input name="'.$input_name.'" value="'.h($input_data).'">';
348
+
349
+ break;
350
+
351
+ case 'checkbox':
352
+
353
+ $input_data = filter_input(INPUT_POST,$input_name, FILTER_DEFAULT, [
354
+
355
+ 'flags' => FILTER_REQUIRE_ARRAY
356
+
357
+ ]);
358
+
359
+ if(ak('select',$setting) && is_array($setting['select'])){
360
+
361
+ if(is_null($input_data)){
362
+
363
+ $input_data = [];
364
+
365
+ }
366
+
367
+ foreach($setting['select'] as $in=>$val){
368
+
369
+ echo '<input type="checkbox" name="'.$input_name.'[]" value="'.$in.'"'.(iar($in,$input_data)?' checked':'').'>'.$val.'&nbsp;';
370
+
371
+ }
372
+
373
+ }
374
+
375
+ break;
376
+
377
+ }
378
+
379
+ echo '</p>';
380
+
381
+ if(ak($input_name,$err)){
382
+
383
+ echo '<span class="error">'.implode('<br />',$err[$input_name]).'</span>';
384
+
385
+ }
386
+
387
+ }
388
+
389
+ ?>
390
+
391
+ <input type="submit" value="送信">
392
+
393
+ </form>
394
+
395
+ </body>
396
+
397
+ </html>
398
+
399
+ <?php
400
+
401
+ exit();
402
+
403
+ ```
404
+
405
+
406
+
407
+ test2.php
408
+
409
+ ```php
410
+
411
+ <?php
412
+
413
+ if($_SERVER['REQUEST_METHOD'] !== 'POST'){
414
+
415
+ require_once 'test1.php';
416
+
417
+ }
418
+
419
+ require 'helper.php';
420
+
421
+ require_once 'validation.php';
422
+
423
+
424
+
425
+ $err = validation();
426
+
427
+
428
+
429
+ if (count($err) > 0) {
430
+
431
+ require_once 'test1.php';
432
+
433
+ }
434
+
435
+ $input_config = require 'input_config.php';
436
+
437
+ ?>
438
+
439
+ <!DOCTYPE html>
440
+
441
+ <html lang="ja">
442
+
443
+ <head>
444
+
445
+ <meta charset="UTF-8">
446
+
447
+ <title>送信</title>
448
+
449
+ </head>
450
+
451
+ <body>
452
+
453
+ <h1 class="red">お問合せ完了画面</h1>
454
+
455
+ <h2>送信しました</h2>
456
+
457
+ <table border="1">
458
+
459
+
460
+
461
+ <?php
462
+
463
+ foreach($input_config as $input_name=>$setting){
464
+
465
+ echo '<tr>';
466
+
467
+ echo '<td>'.$setting['label'].'</td>';
468
+
469
+ echo '<td>';
470
+
471
+ switch($setting['type']){
472
+
473
+ case 'text':
474
+
475
+ $input_data = filter_input(INPUT_POST,$input_name);
476
+
477
+ echo h($input_data);
478
+
479
+ break;
480
+
481
+ case 'checkbox':
482
+
483
+ $input_data = filter_input(INPUT_POST,$input_name, FILTER_DEFAULT, [
484
+
485
+ 'flags' => FILTER_REQUIRE_ARRAY
486
+
487
+ ]);
488
+
489
+ if(ak('select',$setting) && is_array($setting['select'])){
490
+
491
+ if(is_null($input_data)){
492
+
493
+ $input_data = [];
494
+
495
+ }
496
+
497
+ foreach($setting['select'] as $in=>$val){
498
+
499
+ if(iar($in,$input_data)){
500
+
501
+ echo $val.'&nbsp';
502
+
503
+ }
504
+
505
+ }
506
+
507
+ }
508
+
509
+ break;
510
+
511
+ }
512
+
513
+ echo '</td>';
514
+
515
+ echo '</tr>';
516
+
517
+ }
518
+
519
+ ?>
520
+
521
+ </table>
522
+
523
+ </body>
524
+
525
+ </html>
526
+
527
+ <?php
528
+
529
+ exit();
530
+
531
+ ```
532
+
533
+
534
+
535
+ includeでの別画面表示をいかしたためにhelperで二重定義防止をしていますが
536
+
537
+ ビューファイルはやはり1画面1つにしたほうがいいと思う。
538
+
539
+
540
+
541
+ 入力チェック後入力画面をそのまま入力値を初期値で表示させるなら入力チェックは自画面で行ったほうが良いと思います。
542
+
543
+ リダイレクトするとか、リダイレクトが嫌ならJavaScriptでするとか、サーバーサイドでチェックしたいならAjaxでするとか、方法は幾らでもあります。

1

修正

2019/05/01 05:02

投稿

m.ts10806
m.ts10806

スコア80850

test CHANGED
@@ -46,6 +46,10 @@
46
46
 
47
47
 
48
48
 
49
+ 入力値の出力にHTMLエスケープが施されてないですね。
50
+
51
+
52
+
49
53
  ---
50
54
 
51
55
  後ほど適当に組みなおしたコードを投稿するのであとは頑張って理解してみてください。