🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
PHP

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

Q&A

解決済

2回答

1116閲覧

バリデーションについて

sweetruby

総合スコア19

PHP

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

0グッド

0クリップ

投稿2021/02/19 02:24

編集2021/02/19 02:27

前提・実現したいこと

書籍やネットを参考にしながらフォームの練習をしています。

テーブルへ登録は出来ているのですが、簡単なバリデーションが効いていません。
VS codeでデバッグしても問題は発見されませんでした。

if (isset($_POST)が不要なのか、変数の初期化をする必要はないのか、
色々と調べつつ試したのですが壁に突き当たってしまいました。

一体、私はどこで誤りを犯しているのでしょうか?
どなたか是非教えて下さい。

どうぞよろしくお願いいたします。

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

エラーメッセージ

ページを開くと以下のエラーが出ますが、バリデーションのメッセージは出ません。
エラー:SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'id' cannot be null

全て空欄で送信ボタンを押すと、バリデーションのメッセージは出ません。
エラー:SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect integer value: '' for column db名.table名.id at row 1

該当のソースコード

php

1<?php 2if($_POST['submit']) { 3header("Location: {$_SERVER['PHP_SELF']}"); 4exit; 5} 6?> 7<!DOCTYPE html> 8<html lang="ja"> 9 <head> 10 <title>フォームの練習</title> 11 </head> 12 <body> 13 <h1>登録</h1> 14 <form name="form" method="post" action=""> 15 ID:<br> 16 <input type="text" name="id" placeholder="IDを入力して下さい"> 17 <br> 18 氏名:<br> 19 <input type="text" name="name" placeholder="名前を入力して下さい"> 20 <br> 21 メールアドレス:<br> 22 <input type="text" name="email" placeholder="sample@sample.com"> 23 <br> 24 <input type="submit" value="送 信"> 25 </form> 26 27 <?php 28 $db_user = ""; // ユーザー名 29 $db_pass = ""; // パスワード 30 $db_host = ""; // ホスト名 31 $db_name = ""; // データベース名 32 $dsn = "mysql:host=$db_host;dbname=$db_name;charset=utf8"; 33 try { 34 $pdo = new PDO($dsn, $db_user, $db_pass); 35 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 36 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 37 print "接続しました... <br>"; 38 } catch(PDOException $e) { 39 die('エラー :' . $e->getMessage()); 40 } 41 42 //バリデーション 43 $id = ''; 44 $name = ''; 45 $email = ''; 46 47 $errors = []; 48 49 if (isset($_POST)) { 50 if (empty($_POST['id'])) { 51 $errors[] = 'IDは必須項目です。'; 52 } elseif (!preg_match('/\A[0-9]{1,4}+\z/',$_POST['id'])) throw new Exception('半角英数字で入力して下さい。'); 53 54 if (empty($_POST['name'])) { 55 $errors[] = '氏名は必須項目です。'; 56 } 57 58 if (empty($_POST['email'])) { 59 $errors[] = 'Eメールは必須項目です。'; 60 } elseif (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { 61 $errors[] = '正しいEメールアドレスを指定してください。'; 62 } 63 } 64 65 //登録 66 try { 67 $pdo->beginTransaction(); 68 $sql = "INSERT INTO ***** (id, name, email) VALUES ( :id, :name, :email )"; 69 $stmh = $pdo->prepare($sql); 70 71 $stmh->bindValue(':id', $_POST['id'], PDO::PARAM_INT ); 72 $stmh->bindValue(':name', $_POST['name'], PDO::PARAM_STR ); 73 $stmh->bindValue(':email', $_POST['email'], PDO::PARAM_STR ); 74 $stmh->execute(); 75 $pdo->commit(); 76 print "データを" . $stmh->rowCount() . "件登録しました。<br>"; 77 } catch (PDOException $e) { 78 $pdo->rollBack(); 79 print "エラー:" . $e->getMessage(); 80 } 81 ?> 82 </body> 83</html> 84

試したこと

色々と調べて、バリデーション部分のコードを書き替えてみました。
VS Codeでデバッグをしました。
POSTの変数の初期化ができないか調べて試しました。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

K_3578

2021/02/19 02:32

とりあえず落ち着いてまずはエラーメッセージを読んでみましょう。
sweetruby

2021/02/19 02:37

はじめまして、よろしくお願いいたします。 SQLの設定をしたときに、idはnot null の設定にしたのでそれが引っかかっているのかなと思いました。 DB接続時のエラーメッセージなので、バリデーションのステップまで行けないという理解で正しいでしょうか?
sweetruby

2021/02/19 02:47 編集

それから Invalid datetime formatが出ているのですが、DBを作成した時に、練習で使うかもと思って、時間の項目も設けました。それも問題になるのでしょうか? この二つのエラーがあってもテーブルには登録ができているのです。
yambejp

2021/02/19 03:19

$_SERVER['PHP_SELF']は使っちゃだめです
sweetruby

2021/02/19 03:26

恥ずかしながら、クロスサイトスクリプティング攻撃の恐れがあるといま知りました。 バリデーションしたいのに、それではダメですよね。
guest

回答2

0

POSTデータのバリデーションはfilter_inputを利用して下さい

  • 送られてきていない
  • 送られてきたデータが不正
  • 正常

で処理を変えることができます

投稿2021/02/19 03:21

yambejp

総合スコア116694

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

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

sweetruby

2021/02/19 03:32

ありがとうございます。とてもためになります。 もっと沢山コードを書いて、失敗しながらコツをつかめるようなりたいです。 PHPマニュアルのfilter_inputをよく読んでみます。
guest

0

ベストアンサー

$errorsに文字列ためていっているだけで出力していません。そしてSQL実行有無の判定にも使われていません。

実装的な観点だと、「バリデーションにかかったらSQL実行しない」なら、接続はバリデーション結果で決めるべきです。無駄なリソースとなります。

投稿2021/02/19 02:48

m.ts10806

総合スコア80875

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

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

sweetruby

2021/02/19 02:57 編集

どうもありがとうございます。お尋ねしてよかったです。 ご指摘の部分を調べて、少し工夫をしてみます。 また上手く動かなかったら、こちらで質問させてください。 よろしくお願いします。
m.ts10806

2021/02/19 02:59

ロジックとビューが入り乱れてるのも1つ、コーディングを難しくしている要因と思います。 分けましょう。form送信した情報はactionの指定先に「リクエスト」として送信されるので、指定先のコードはまた最初から実行されます。
sweetruby

2021/02/19 03:15

テンプレートとロジックは分けろという部分に妙に納得しました。 理解が不十分だから、正しくプログラムが書けないのがもどかしいです。 初心者にていねいに教えてくださり、感謝します。
m.ts10806

2021/02/19 03:30

「正しいプログラム」という概念はないです。書いた通りに動いているだけですし、要件を満たすなら中身はどうであれ「正しい“アプリケーション”」です。
sweetruby

2021/02/19 03:39

正しく書けない=動かない=正しくないアプリケーション まさにその通りだと思います。頑張って少しずつ動くものを書けるようになりたいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問