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

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

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

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

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

Q&A

解決済

1回答

314閲覧

PHPにおけるバリデーションとPOSTの両立の方法について

Yamachoo

総合スコア19

PHP

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

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

0グッド

0クリップ

投稿2019/05/30 01:28

編集2019/05/30 01:56

前提・実現したいこと

オリジナルで簡単なアウトプットを作成しています。
PHPでバリデーション機能を実装中にエラーが発生しました。

発生している問題・エラーメッセージ

バリデーションを実装しつつ、index.phpから送られた$_POSTをresult.phpで読み込みたいと考えております。
イメージ説明

該当のソースコード

index.php

PHP

1<?php 2session_start(); 3 4$error = array(); 5 6if (!empty($_POST)) { 7 $subject = htmlspecialchars($_POST['doing']); 8 $date_time = new DateTime($_POST['date']); 9 $avarageTime = mb_convert_kana($_POST['time'], 'n', 'UTF-8'); 10 // エラー項目の確認 11 if ($subject == null) { 12 $error['doing'] = 'blank'; 13 } 14 if ($date_time >= new DateTime('now')) { 15 $error['date'] = 'over'; 16 } 17 if ($avarageTime == null) { 18 $error['time'] = 'blank'; 19 } 20 if (ctype_digit ($avarageTime) == FALSE) { 21 $error['time'] = 'noNumber'; 22 } 23 24 if (empty($error)) { 25 $_SESSION['join'] = $_POST; 26 header('Location: result.php'); 27 exit(); 28 } 29} 30?> 31 32<!DOCTYPE html> 33<html lang="ja" dir="ltr"> 34 <head> 35 <meta charset="utf-8"> 36 <meta name="viewport" content="width=device-width, initial-scale=1" /> 37 <title>積み上げメーター</title> 38 <!-- Bootstrap CSS --> 39 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> 40 <!-- Font Awesome --> 41 <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous"> 42 <!-- Customizing CSS --> 43 <link rel="stylesheet" href="css/styles.css"> 44 <link rel="stylesheet" href="css/responsive.css"> 45 </head> 46 <body> 47 <header> 48 <div class="container head-wrap"> 49 <img class="icon" src="img/icon_1.png"> 50 <h1><a href="index.php">積み上げメーター</a></h1> 51 <img class="icon" src="img/icon_2.png"> 52 </div> 53 </header> 54 55 <main> 56 <div class="container main-wrap"> 57 <div class="row pt-3 d-block text-center"> 58 <p class="lead font-weight-bold">あなたの頑張りを可視化できる</p> 59 <p class="lead font-weight-bold">積み上げメーター</p> 60 </div> 61 <div class="row"> 62 <form action="" method="post"> 63 <div class="col-md-12 form-group"> 64 <p class="mb-2">■積み上げてること</p> 65 <input class="form-control" type="text" name="doing" placeholder="例:プログラミング"> 66 <?php if (isset($error['doing']) && $error['doing'] == 'blank'): ?> 67 <p class="error">* 積み上げていることを入力してください</p> 68 <?php endif; ?> 69 </div> 70 71 <div class="col-md-12 form-group"> 72 <p class="mb-2">■積み上げ開始日</p> 73 <input class="form-control" type="date" name="date" value="2019-01-01"> 74 <?php if (isset($error['date']) && $error['date'] == 'over'): ?> 75 <p class="error">* 過去の日付を入力してください</p> 76 <?php endif; ?> 77 </div> 78 79 <div class="col-md-12 form-group"> 80 <p class="mb-2">■1日の積み上げ時間</p> 81 <div class="d-flex"> 82 <p class="w-15">平均</p> 83 <input class="form-control w-70" type="text" name="time" maxlength="5" placeholder="例:1.5"> 84 <p class="w-15">時間</p> 85 </div> 86 <?php if (isset($error['time']) && $error['time'] == 'blank'): ?> 87 <p class="error">* 1日の積み上げ時間を入力してください</p> 88 <?php endif; ?> 89 <?php if (isset($error['time']) && $error['time'] == 'noNumber'): ?> 90 <p class="error">* 数字を入力してください</p> 91 <?php endif; ?> 92 </div> 93 94 <div class="col-md-12"> 95 <input class="btn btn-danger btn-block" type="submit" name="" value="送信"> 96 </div> 97 </form> 98 </div> 99 </div> 100 </main> 101 102 <!-- Optional JavaScript --> 103 <!-- jQuery first, then Popper.js, then Bootstrap JS --> 104 <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> 105 <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> 106 <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> 107 </body> 108</html> 109

result.php

PHP

1<?php 2session_start(); 3 4if (!isset($_POST)) { 5 $_SESSION['join'] = ''; 6 header('Location: index.php'); 7 exit(); 8} 9 10var_dump($_POST['doing']); 11var_dump($_POST['date']); 12var_dump($_POST['time']); 13 14$subject = htmlspecialchars($_POST['doing']); 15$date_time = new DateTime($_POST['date']); 16$avarageTime = mb_convert_kana($_POST['time'], 'n', 'UTF-8'); 17//5つの積み上げレベル 18$levels = array('biginner', 'challenger', 'master', 'expert', 'professional'); 19//時間計算 20$time_now = new DateTime('now'); 21$diff = $time_now->diff($date_time); 22$totalDay = $diff->d; 23$totalTime = $totalDay * $avarageTime; 24//レベル判定 25if ($totalTime < 100) { 26 $level = $levels[0]; 27} elseif ($totalTime < 500) { 28 $level = $levels[1]; 29} elseif ($totalTime < 1000) { 30 $level = $levels[2]; 31} elseif ($totalTime < 10000) { 32 $level = $levels[3]; 33} else { 34 $level = $levels[4]; 35} 36//次のレベルとそれまでの時間(日) 37if ($totalTime < 100) { 38 $nextLevel = $levels[1]; 39 $nextTime = 100 - $totalTime; 40} elseif ($totalTime < 500) { 41 $nextLevel = $levels[2]; 42 $nextTime = 500 - $totalTime; 43} elseif ($totalTime < 1000) { 44 $nextLevel = $levels[3]; 45 $nextTime = 1000 - $totalTime; 46} elseif ($totalTime < 10000) { 47 $nextLevel = $levels[4]; 48 $nextTime = 10000 - $totalTime; 49} else { 50 $nextLevel = ''; 51 $nextTime = ''; 52} 53if ($nextTime != '') { 54 $nextDay = round($nextTime / $avarageTime); 55} 56 57//グラフのパーセント 58if ($totalTime < 100) { 59 $graphLong = $totalTime / 100 * 100; 60} elseif ($totalTime < 500) { 61 $graphLong = $totalTime / 500 * 100; 62} elseif ($totalTime < 1000) { 63 $graphLong = $totalTime / 1000 * 100; 64} elseif ($totalTime < 10000) { 65 $graphLong = $totalTime / 10000 * 100; 66} else { 67 $graphLong = 100; 68} 69 70?> 71 72<!DOCTYPE html> 73<html lang="ja" dir="ltr"> 74 <head> 75 <meta charset="utf-8"> 76 <meta name="viewport" content="width=device-width, initial-scale=1" /> 77 <title>積み上げメーター</title> 78 <!-- Bootstrap CSS --> 79 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> 80 <!-- Font Awesome --> 81 <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous"> 82 <!-- Customizing CSS --> 83 <link rel="stylesheet" href="css/styles.css"> 84 <link rel="stylesheet" href="css/responsive.css"> 85 <style type="text/css" media="screen"> 86 main .graph-left { 87 width: <?php echo $graphLong; ?>%; 88 background-color: rgb(247, 148, 40); 89 } 90 </style> 91 </head> 92 <body> 93 <header> 94 <div class="container head-wrap"> 95 <img class="icon" src="img/icon_1.png"> 96 <h1><a href="index.php">積み上げメーター</a></h1> 97 <img class="icon" src="img/icon_2.png"> 98 </div> 99 </header> 100 101 <main> 102 <div class="container main-wrap"> 103 <div class="row align-items-center"> 104 <div class="col-md-6"> 105 <p>■あなたの積み上げレベル</p> 106 <img src="img/<?php echo $level; ?>.jpg" class="mx-auto d-block rounded-circle"> 107 <p class="text-center font-weight-bold"><?php echo $subject; ?><?php echo strtoupper($level); ?></p> 108 </div> 109 110 <div class="col-md-6"> 111 <p>現在のあなたの積み上げ時間は</p> 112 <p class="text-center lead font-weight-bold total-time"><?php echo $totalTime; ?>時間</p> 113 <div class="graph"> 114 <div class="graph-left pb-4" id="graph"></div> 115 </div> 116 <?php 117 if ($nextLevel != '') { 118 echo '<p>'.$subject.'の'.strtoupper($nextLevel).'まで</p>'; 119 echo '<p class="text-center lead font-weight-bold">あと'.$nextTime.'時間('.$nextDay.'日継続!)</p>'; 120 } else { 121 echo '<p class="text-center lead font-weight-bold">今後もこの調子で</p>'; 122 echo '<p class="text-center lead font-weight-bold">積み上げていきましょう!</p>'; 123 } 124 ?> 125 </div> 126 </div> 127 </div> 128 </main> 129 130 <!-- Optional JavaScript --> 131 <!-- jQuery first, then Popper.js, then Bootstrap JS --> 132 <script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script> 133 <script> 134 $(function(){ 135 $("#graph").hide().fadeIn(2000); 136 }); 137 </script> 138 <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> 139 <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> 140 </body> 141</html> 142

文字数の関係で一部省略しています。

試したこと

最初はバリデーションを導入せずに、formのactionを"result.php"にしていたときは問題なくプログラムは動いていました。
そのため、$_POSTの値がresult.phpに送られていないのではないのではないかと思い、ディベロッパーツールにて確認したところ、データが送られていなかったのでこの部分に問題があるのではないかと考えています。
しかし、この2つを両立させる方法が分からないというのが現状になります。

補足情報(FW/ツールのバージョンなど)

PHP/7.3.4

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

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

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

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

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

m.ts10806

2019/05/30 01:34

エラーメッセージをそのまま質問本文にご提示ください。 また、PHPのデータが送信されているかどうかの確認はPHPの機能、var_dump()などで対応すべきと思います。検証結果また教えてください。
m.ts10806

2019/05/30 01:36

あと、細かいのですが、htmlspecialchars()は画面出力時にそのときに入れるべきものです・・
m.ts10806

2019/05/30 01:47

手元で簡単に検証した結果回答にしました。
Yamachoo

2019/05/30 01:51

ご指摘ありがとうございます。 先ほどvar_dump()を追加し、検証しました。 エラーメッセージは文字数の上限のため質問本文に載せられなかったためこちらに、一旦載せさせていただきます。 Notice: Undefined index: doing in C:\xampp\htdocs\stackedMeter\result.php on line 10 NULL Notice: Undefined index: date in C:\xampp\htdocs\stackedMeter\result.php on line 11 NULL Notice: Undefined index: time in C:\xampp\htdocs\stackedMeter\result.php on line 12 NULL Notice: Undefined index: doing in C:\xampp\htdocs\stackedMeter\result.php on line 14 Notice: Undefined index: date in C:\xampp\htdocs\stackedMeter\result.php on line 15 Notice: Undefined index: time in C:\xampp\htdocs\stackedMeter\result.php on line 16 Warning: A non-numeric value encountered in C:\xampp\htdocs\stackedMeter\result.php on line 23 Warning: A non-numeric value encountered in C:\xampp\htdocs\stackedMeter\result.php on line 54 Warning: Division by zero in C:\xampp\htdocs\stackedMeter\result.php on line 54
m.ts10806

2019/05/30 01:52

エラーだけ画面キャプチャに添付というのはありです
guest

回答1

0

ベストアンサー

formタグのaction属性に指定した先にしか送信しません。
つまり

php

1 $_SESSION['join'] = $_POST; 2 header('Location: result.php');

↑でリダイレクトしている先には送信されていないので$_POSTでは受け取れません。

$_SESSIONにおさめているので
result.phpでは$_POSTではなく$_SESSION['join'] として受け取るべきかと思います。

※別途コメントで書いたようにhtmlspecialchars()はHTMLエスケープを施すものなので送信データ受け取り時ではなく画面出力時に行いましょう。

追記:

var_dump($_POST['doing']);

var_dump($_POST['date']);
var_dump($_POST['time']);

var_dump()は配列も出力できるのでvar_dump($_POST);だけでじゅうぶんです。

投稿2019/05/30 01:46

編集2019/05/30 01:48
m.ts10806

総合スコア80850

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

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

Yamachoo

2019/05/30 02:02

ご丁寧な回答をありがとうございます。 無事、問題を解決することができました! htmlspecialchars()も修正させていただきます。 いろいろと本当にありがとうございました。
m.ts10806

2019/05/30 02:03

あ。あとempty($_POST)もやめたほうが。 isset()とかcount()とかのほうが。または$_SERVER['REQUEST_METHOD']がPOSTであるというのもあり。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問