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

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

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

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

Q&A

解決済

3回答

191閲覧

PHPでフォームを作成する

daiku0919

総合スコア16

PHP

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

0グッド

0クリップ

投稿2025/01/14 05:41

実現したいこと

お問い合わせフォームをPHPで実装しようと思っています。
その中でPHPのバリデーションの組み方を教えていただきたいです。

発生している問題・分からないこと

strlen関数を用いて文字数の制限をかけるバリデーションを組んでいるのですがエラーが出てしまっています。

該当のソースコード

contact.php

1<?php 2 3session_start(); 4 5if(isset($_POST["submit"])) { 6 $name = htmlspecialchars($_POST['name'],ENT_QUOTES | ENT_HTML5); 7 $kana = htmlspecialchars($_POST['kana'],ENT_QUOTES | ENT_HTML5); 8 $tel = htmlspecialchars($_POST['tel'],ENT_QUOTES | ENT_HTML5); 9 $email = htmlspecialchars($_POST['email'],ENT_QUOTES | ENT_HTML5); 10 $body = htmlspecialchars($_POST['body'],ENT_QUOTES | ENT_HTML5); 11 12 $errors = []; 13 if(trim($name) === '' || trim($name) === " " && strlen($name) > 10){ 14 $errors["name"] = "氏名は必須入力です。10文字以内でご入力ください。"; 15 16 } 17 18 if(trim($kana) === '' || trim($kana) === " " && strlen($kana) > 10) { 19 $errors["kana"] = "フリガナは必須入力です。10文字以内でご入力ください。"; 20 } 21 22 if(count($errors) < 0) { 23 $_SESSION["name"] = $name; 24 $_SESSION["kana"] = $kana; 25 $_SESSION["email"] = $email; 26 $_SESSION["body"] = $body; 27 header('Location:confirm.php'); 28 } 29 30 31 32} 33 34 35?> 36 37<!DOCTYPE html> 38<html> 39<head> 40 <meta charset="UTF-8"> 41 <title>サーバーサイド基礎 課題form</title> 42 <link rel="stylesheet" type="text/css" href="style.css"> 43</head> 44<body> 45<?php include "header.php"; ?> 46<section> 47 <div id="contact_box"> 48 <h2><b>お問い合わせ</b></h2> 49 <form action="contact.php" method="post"> 50 <h3>下記の項目をご記入の上送信ボタンを押してください</h3> 51 <p>送信頂いた件につきましては、当社より折り返しご連絡を差し上げます。</p> 52 <p>なお、ご連絡までに、お時間を頂く場合もございますので予めご了承ください。</p> 53 <p><span class="required">*</span>は必須項目となります。</p> 54 <dl> 55 <dt><label for="name">氏名</label><span class="required">*</span></dt> 56 <p style="color:red;"><?php if (isset($name)) {echo $errors['name'];} ?></p> 57 <dd><input type="text" name="name" id="name" placeholder="山田太郎" ></dd> 58 <dt><label for="kana">フリガナ</label><span class="required">*</span></dt> 59 60 <dd><input type="text" name="kana" id="kana" placeholder="ヤマダタロウ" ></dd> 61 <dt><label for="tel">電話番号</label></dt> 62 63 <dd><input type="text" name="tel" id="tel" placeholder="09012345678" ></dd> 64 <dt><label for="email">メールアドレス</label><span class="required">*</span></dt> 65 66 <dd><input type="email" name="email" id="email" placeholder="test@test.co.jp" ></dd> 67 </dl> 68 <h3><label for="body">お問い合わせ内容をご記入ください<span class="required">*</span></label></h3> 69 70 <dl> 71 <dd><textarea name="body"></textarea></dd> 72 <dd><button type="submit" class="send" name="submit">送 信</button></dd> 73 </dl> 74 </form> 75 </div> 76</section> 77<?php include "footer.php"; ?> 78</body> 79</html> 80

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

teratailやGoogle等で検索したのですが解決に至らなかったためご質問しました。
どなたかご教授お願いいたします。

補足

特になし

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

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

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

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

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

maisumakun

2025/01/14 06:14

> エラーが出てしまっています。 どの場所に、どのようなメッセージで(要約せずコピペしてください)エラーが出力されましたか?
guest

回答3

0

1.入力値にhtmlspecialcharsを使うのは間違い。おそらく参考にしたのが初心者の書いたコードということでしょう。その参考コードを捨てて参考にしないことが最初にやるべきことです。「ウェブアプリの脆弱性」が言われ始めた初期にこういう間違いコードが広まってた気がします。

2.strlen関数は文字数を得る関数ではないです。バイト数を得る関数です。
UTF-8でしょうから、strlenが10を越えるとエラーだというなら、strlen("山田誠")9で、strlen("山田一郎")12なので日本人の大部分の人が駄目です。文字数はmb_strlenですが、それに変えたとしても文字数10以下だけというと欧米人はほとんど駄目でしょうね。Donald John Trumpで17文字。
「10文字を超える人は相手にしなくていい」前提でない限り、条件を見直すべきでしょう。実用プログラムでなくプログラミング演習課題なら場合によってはありですが、真に受ける受講生がいると困るので、止めた方が良いですね。

3.if(trim($name) === '' || trim($name) === " " && strlen($name) > 10){は意味不明。

日本語で書くと、下記の①②いずれかに該当するときにエラーとしていることになります。
$nameが空文字列
$nameの前後の半角ホワイトスペース文字(具体的には" \n\r\t\v\x00"のいずれか)を取り除いた物が全角空白1文字であり、かつ、取り除く前の$nameのバイト数が10より大きい

②に該当するのは、「全角空白1文字の前後に半角ホワイトスペース文字を合計8つ以上連結した物」ですね。かなりレア。
&&||に変えれば意味不明ではなくなりますが、そう変更しても間違っているのには変わりないです。

4.count($errors) < 0が真になることはない。

countの意味が分からないことはないと思うので、演算子のタイプミスでしょうか。

5.HTMLは見てません。

「PHPのプログラミングの勉強をしたい」が目的の場合、アドバイスとしては、1に書いたとおりですが、「入力値にhtmlspecialcharsを使う」が教材に書いてあったわけじゃなくて、自分でググって見つけたコードのコピペの場合は、教材を捨てる必要は無いです。「ググって見つけたコードをしっかり調べることなしにコピペして使う」を止めればいいだけです。

投稿2025/01/14 11:32

編集2025/01/15 12:36
otn

総合スコア85989

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

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

0

エラーが出てしまっています。

エラーメッセージを読む努力は必要です。
重要なヒントが書かれています。

PHP

1if(isset($_POST["submit"])) { 2 $name = htmlspecialchars($_POST['name'],ENT_QUOTES | ENT_HTML5);

HTMLとしてのエスケープは、出力する際にすべき処理で受け取った時にするのはナンセンスです。

PHP

1 if(count($errors) < 0) { 2 $_SESSION["name"] = $name;

count($errors)が負の値になる事は無いと思います。
なので、セッションに書き出される事も無いでしょう。

PHP

1if(isset($_POST["submit"])) { 2 $name = htmlspecialchars($_POST['name'],ENT_QUOTES | ENT_HTML5); 3(略) 4 if(trim($name) === '' || trim($name) === " " && strlen($name) > 10){ 5 $errors["name"] = "氏名は必須入力です。10文字以内でご入力ください。"; 6 7 }

この様にセットしているので、エラーが無い時には $errors['name'] はセットされません。
なのでif (isset($name)) {echo $errors['name'];}では未定義エラーが出るでしょう。

HTML

1 <dl> 2 <dt><label for="name">氏名</label><span class="required">*</span></dt> 3 <p style="color:red;"><?php if (isset($name)) {echo $errors['name'];} ?></p>

dlタグ直下には、pタグ不可だったのでは?

投稿2025/01/14 10:40

tezcello

総合スコア381

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

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

0

ベストアンサー

ざっくりこんな判定でどうでしょうか?

PHP

1<?php 2session_start(); 3function h($str){ 4 return htmlspecialchars($str,ENT_QUOTES | ENT_HTML5); 5} 6function is_empty(){ 7 $args=func_get_args(); 8 $ret=false; 9 foreach($args as $arg){ 10 $ret = $ret || ( !is_null($arg) and $arg!=="0" and empty($arg)); 11 } 12 return $ret; 13} 14$submit= filter_input(INPUT_POST,'submit'); 15$name = filter_input(INPUT_POST,'name',FILTER_VALIDATE_REGEXP,["options"=>["regexp"=>"/\A.{1,9}\z/"]]); 16$kana = filter_input(INPUT_POST,'kana',FILTER_VALIDATE_REGEXP,["options"=>["regexp"=>"/\A.{1,9}\z/"]]); 17$tel = filter_input(INPUT_POST,'tel'); 18$email = filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL); 19$body = filter_input(INPUT_POST,'body'); 20 21$errors = [ 22 "name" =>is_empty($name)?"氏名は必須入力です。10文字以内でご入力ください。":"", 23 "kana" =>is_empty($kana)?"フリガナは必須入力です。10文字以内でご入力ください。":"", 24 "email"=>is_empty($email)?"Emailは未入力、または形式が違います。":"", 25 "body" =>is_empty($body)?"お問い合わせ内容が不明です。":"", 26 ]; 27$h =[ 28 "name" =>h(filter_input(INPUT_POST,'name')), 29 "kana" =>h(filter_input(INPUT_POST,'kana')), 30 "tel" =>h(filter_input(INPUT_POST,'tel')), 31 "email"=>h(filter_input(INPUT_POST,'email')), 32 "body" =>h(filter_input(INPUT_POST,'body')), 33 ]; 34 35if(is_empty($name,$kana,$email,$body) or is_null($submit)){ 36 session_destroy(); 37}else{ 38 $_SESSION=[ 39 "name" =>$name, 40 "kana" =>$kana, 41 "tel" =>$tel, 42 "email"=>$email, 43 "body" =>$body, 44 ]; 45 var_dump($_SESSION); 46} 47?> 48<section> 49 <div id="contact_box"> 50 <h2><b>お問い合わせ</b></h2> 51 <form action="<?= $_SERVER["SCRIPT_NAME"] ?>" method="post"> 52 <h3>下記の項目をご記入の上送信ボタンを押してください</h3> 53 <p>送信頂いた件につきましては、当社より折り返しご連絡を差し上げます。</p> 54 <p>なお、ご連絡までに、お時間を頂く場合もございますので予めご了承ください。</p> 55 <p><span class="required">*</span>は必須項目となります。</p> 56 <dl> 57 <dt><label for="name">氏名</label><span class="required">*</span></dt> 58 <p style="color:red;"><?= $errors['name'] ?></p> 59 <dd><input type="text" name="name" id="name" placeholder="山田太郎" value="<?=$h["name"] ?>"></dd> 60 <dt><label for="kana">フリガナ</label><span class="required">*</span></dt> 61 <p style="color:red;"><?= $errors['kana'] ?></p> 62 63 <dd><input type="text" name="kana" id="kana" placeholder="ヤマダタロウ" value="<?=$h["kana"] ?>"></dd> 64 <dt><label for="tel">電話番号</label></dt> 65 66 <dd><input type="text" name="tel" id="tel" placeholder="09012345678" value="<?=$h["tel"] ?>" ></dd> 67 <dt><label for="email">メールアドレス</label><span class="required">*</span></dt> 68 <p style="color:red;"><?= $errors['email'] ?></p> 69 <dd><input type="text" name="email" id="email" placeholder="test@test.co.jp" value="<?=$h["email"] ?>" ></dd> 70 </dl> 71 <h3><label for="body">お問い合わせ内容をご記入ください<span class="required">*</span></label></h3> 72 <p style="color:red;"><?= $errors['body'] ?></p> 73 74 <dl> 75 <dd><textarea name="body"><?=$h["body"] ?></textarea></dd> 76 <dd><button type="submit" class="send" name="submit" value="1">送 信</button></dd> 77 </dl> 78 </form> 79 </div> 80</section>

※HTMLの調整は必要かも・・・・

投稿2025/01/14 08:03

yambejp

総合スコア116921

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.34%

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

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

質問する

関連した質問