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

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

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

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

357閲覧

PHP,HTMLを使って問い合わせフォーム

YutoYoshii

総合スコア12

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2019/02/04 16:32

編集2019/02/05 00:39

PHP、HTMLを使って問い合わせフォームを以下のソースコードで作っています。バリデーションの関数化をしています。このソースコードでページを開くと、最初からエラーメッセージが出てしまいます。var_dumpで$_POST["send"]の値を調べてみるとずっとsendに値が入っています。
ページを開いた際にいきなりエラーメッセージがでないようにしたいのですが、どうしたらよろしいのでしょうか?

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> </head> <?php session_start(); $errMsgList = []; function inputName($inputData){ $errorMsg; if($inputData === ""){ $errorMsg = "名前が入力されていません"; return $errorMsg; } return NULL; } function inputMail($inputData){ $errorMsg; if($inputData === ""){ $errorMsg = "メールアドレスが入力されていません"; return $errorMsg; } return NULL; } function stringSize($inputData){//20字以下か判定 if(strlen($inputData)>20) { $errorMsg = "名前は20文字以下で入力してください"; return $errorMsg; } return NULL; } function mailcheck($inputData){ if(!preg_match( '/^[0-9a-z_./?-]+@([0-9a-z-]+.)+[0-9a-z-]+$/', $inputData)){ $errorMsg = "正しいメールアドレスを入力してください"; return $errorMsg; } return NULL; } if (isset($_POST['send'])) { $_SESSION = $_POST; if(inputName($_SESSION["name"]) !== NULL){ $errMsgList[] = inputName($_SESSION["name"]); } if(inputMail($_SESSION["email"]) !== NULL){ $errMsgList[] = inputMail($_SESSION["email"]); } if(stringSize($_SESSION["name"]) !== NULL){ $errMsgList[] = stringSize($_SESSION["name"]); } if(mailcheck($_SESSION["email"]) !== NULL){ $errMsgList[] = mailcheck($_SESSION["email"]); } } if (count($errMsgList) == 0) { header('Location: confirm-s.php'); } ?> <body> <?php if ($errMsgList >= 0) { echo '<ul>'; foreach ($errMsgList as $errMsg) { echo "<p>$errMsg</p>"; } echo '</ul>'; var_dump($_POST['send']); } ?> <form method="post"action="input.php"> <table> <tr> <td><p>名前</p></td> <td> <input type="text" name="name" value="<?php echo isset($_SESSION['name']) ? $_SESSION['name'] : ''; ?>" > </td> </tr> <tr> <td><p>メールアドレス</p></td> <td> <input type="text" name="email" value="<?php echo isset($_SESSION['email']) ? $_SESSION['email'] : '';?>" > </td> </tr> <tr> <td></td> <input type="hidden" name="send" value="送信"> <td><input type="submit" value="送信する"></td> </table> </form> </div> </body> </html>

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

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

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

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

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

kei344

2019/02/04 16:34

(質問文は編集できます)質問文のコードはコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「<code>」ボタンを押すとコードブロックになります。
m.ts10806

2019/02/04 21:48

本件とはあまり関係ないですがhtmlの中に関数定義が書かれているというゴチャゴチャになって問題の切り分けがしづらい作りなのでロジック部分とビュー部分ははっきりと書く場所を分けられた方が良いです。
YutoYoshii

2019/02/05 00:38

ご指摘ありがとうございます。編集します。
m.ts10806

2019/02/05 01:10

インデントが結構ずれてて問題の切り出しが難しくなっていますね。 そこも含めて「現状のコードへの指摘」をメインで回答としました。 コードにコメントを書いている状態なのでちょっと読み難いかもしれませんが。
guest

回答2

0

ベストアンサー

かなり作りがおかしいです。
ちなみに今回のコードを初めて動かすと、input.php(たぶんこのPHPのファイル名ですよね)には永遠にアクセスできません。

勝手にフォーマットした上で現状のコードに指摘を書いて見ました。
途中、「今起きている問題」の原因と思われる状態に気づきましたので、そこもコメントしています。
今の私のユーザー名「mts10806」でコード内検索すると良いです

php

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4<meta charset="UTF-8"> 5</head> 6<?php 7session_start(); 8$errMsgList = []; 9//**mts10806**HTMLが始まっているのに定義があるのは読みづらい。せめてhtmlが始まる前に定義して出力ロジックのみ書くべき 10function inputName($inputData) 11{ 12 $errorMsg; //**mts10806**使われないパターンがある それなら初期値 NULL入れておいてreturnした方が良くない? 13 if ($inputData === "") { 14 $errorMsg = "名前が入力されていません"; 15 return $errorMsg; //**mts10806**文字列入れるのであればここでreturnではなく初期値にnull入れた最後にreturn $errorMsg;だけでいい 16 } 17 return NULL; 18} 19 20//**mts10806**以下functionについては前述と同じ 21function inputMail($inputData) 22{ 23 $errorMsg; 24 if ($inputData === "") { 25 $errorMsg = "メールアドレスが入力されていません"; 26 return $errorMsg; 27 } 28 return NULL; 29} 30 31function stringSize($inputData) 32{ // 20字以下か判定 33 if (strlen($inputData) > 20) { 34 $errorMsg = "名前は20文字以下で入力してください"; //**mts10806**返すだけなら変数に入れなくても良いのでは 35 return $errorMsg; 36 } 37 return NULL; 38} 39 40function mailcheck($inputData) 41{ 42 if (! preg_match('/^[0-9a-z_./?-]+@([0-9a-z-]+.)+[0-9a-z-]+$/', $inputData)) { 43 $errorMsg = "正しいメールアドレスを入力してください";//**mts10806**返すだけなら変数に入れなくても良いのでは 44 return $errorMsg; 45 } 46 return NULL; 47} 48 49if (isset($_POST['send'])) { //**mts10806** 後述の通りこれではinput.phpに永遠にアクセスできない。 50 //**mts10806** sessionは書き換わることを加味したらセッションに入れた値をチェックではなく、$_POSTの値をチェックして全てOKの場合セッションに入れるのが妥当 51 //ちなみに$_POSTも$_SESSIONもスーパーグローバル変数。引数で渡す意味はない 52 $_SESSION = $_POST; 53 if (inputName($_SESSION["name"]) !== NULL) { 54 $errMsgList[] = inputName($_SESSION["name"]); 55 } 56 if (inputMail($_SESSION["email"]) !== NULL) { 57 $errMsgList[] = inputMail($_SESSION["email"]); 58 } 59 if (stringSize($_SESSION["name"]) !== NULL) { 60 $errMsgList[] = stringSize($_SESSION["name"]); 61 } 62 if (mailcheck($_SESSION["email"]) !== NULL) { 63 $errMsgList[] = mailcheck($_SESSION["email"]); 64 } 65} 66 67//**mts10806**このファイルがinput.phpとしたら初回アクセス時必ずここを通る。つまり、永遠にinput.phpにアクセスすることができない 68//質問者さんがアクセスできているのは下記のheader()の処理を入れる前にチェック処理を行っていたからではなかろうか 69//ということは$_SESSIONのクリアがされないままinput.phpにアクセスしているのでisset($_POST['send'])を通らずにエラーメッセージが出る 70//ここが今質問者さんに起きている問題と推察される 71if (count($errMsgList) == 0) { 72 header('Location: confirm-s.php'); 73} 74?> 75<body> 76 77<?php 78//**mts10806**これだと「0件のとき」もulが出力されてしまって変な空間ができるのでは? 79if ($errMsgList >= 0) { 80 echo '<ul>'; 81 foreach ($errMsgList as $errMsg) { 82 echo "<p>$errMsg</p>"; //**mts10806** 親がulなら通常はliなどリスト系のタグですね。 83 } 84 echo '</ul>'; 85 var_dump($_POST['send']); 86} 87?> 88<form method="post" action="input.php"> 89 <table> 90 <tr> 91 <td><p>名前</p></td> 92 <td><input type="text" name="name" 93 value="<?php echo isset($_SESSION['name']) ? $_SESSION['name'] : '';//**mts10806**XSS対策(HTMLエスケープ)しましょう ?>"> 94 </td> 95 </tr> 96 <tr> 97 <td><p>メールアドレス</p></td> 98 <td><input type="text" name="email" 99 value="<?php echo isset($_SESSION['email']) ? $_SESSION['email'] : '';//**mts10806**XSS対策(HTMLエスケープ)しましょう?>"> 100 </td> 101 </tr> 102 <tr> 103 <td></td> 104 <input type="hidden" name="send" value="送信"> <!-- **mts10806**問題にあまりならないけど、hiddenとはいえ、あまり「要素が実際に置けない場所」への設置はHTML的にNG --> 105 <td><input type="submit" value="送信する"></td> 106<!-- **mts10806** </tr>が不足している --> 107 </table> 108 </form> 109 </div><!-- **mts10806** 開始<div>がないみたい --> 110</body> 111</html>

「ロジックとビューの分離」についてはQiitaで様々な記事があります。

入力チェックについては「POSTされたとき」というのは認識間違っていませんが、それが$_POST['send']のような特定の値の有無でチェックするのは危険です。
HTMLはブラウザのデベロッパーツールなどから容易に改ざん可能なので、もしsendというnameのついた要素がnameを変更されたり削除された状態だとどうなるでしょう?
なので、そもそも今POSTかどうかを判定して入れるようにしてください。
※別で回答についているコードを参照
※念のためこのような記事も参照のこと

POSTされたとき以外ではconfirm-s.phpへも行かないでしょうから、そこも考慮して閉じる箇所を決める必要があります。

蛇足:
欲を言えば、同じ処理なのであれば共通として切り出した方がコードが短くなります。
例:必須チェック

php

1function requireCheck($name,$prefix=""){ 2 if(is_null($name)) return ""; 3 $inputData = filter_input(INPUT_POST,$name); 4 if(is_null($inputData) || trim($inputData) === ""){ 5 return $prefix."が入力されていません"; 6 } 7 return ""; 8} 9 10$name_check = requireCheck("name","名前"); 11if($name_check !== ""){ 12 $err[] = $name_check; 13} 14$email_check = requireCheck("email","メールアドレス"); 15if($email_check !== ""){ 16 $err[] = $email_check ; 17}

関数はあくまで「共通化」「特定の役割を持たせる」ことが第一の目的でもあるので、同じ処理をするのであれば変わる部分だけを渡してやって中で分岐させるなり変数で対応するなりした方が呼び出す側はスッキリします。
文字数のチェックも「X文字」の「X」の部分しか変わりませんのでその部分だけ変数で渡せばできそうですよね。

もっと効率化しようと思ったら、「入力フォームのHTML」から「入力チェックの設定」まで含めて全て配列などで設定を持つと、もっと処理部分が簡潔に書けます。

参考まで。

投稿2019/02/05 01:07

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

総合スコア80850

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

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

YutoYoshii

2019/02/05 01:37 編集

わかりやすい解説をしていただきありがとうございます。 また細かい指摘までいただき大変感謝しています。 URLまで張り付けていただき大変勉強になりました。
m.ts10806

2019/02/05 01:44

var_dump()を利用するデバッグはご存じなようなのでその範囲をもっと広げたり細かくすることで問題解決につながっていきます。 がんばってください。
YutoYoshii

2019/02/05 01:46

わかりました。アドバイスまでしていただき大変恐縮です。 がんばってみます!!
guest

0

$_POST["send"]の値を調べてみるとずっとsendに値が入っています。

html

1<input type="hidden" name="send" value="送信">

こちらでvalue="送信"としているから$_POST["send"]に"送信"と値が入っているのでは?

また、エラーが出るのは、以下のようなif文の外にfunction inputName($inputData)などがあるため、毎回ページを開くたびに処理が行われエラーがでているのではないでしょうか。

php

1if ($_SERVER["REQUEST_METHOD"] == "POST") { 2//ユーザーからフォームの送信があった場合のみ処理するコード 3}

投稿2019/02/04 18:15

unotalk

総合スコア124

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

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

YutoYoshii

2019/02/05 01:34

わかりやすいご回答ありがとうございます。 if文の外にあることを見落としていました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問