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

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

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

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

Q&A

解決済

2回答

2485閲覧

php登録画面でNotice: Undefined variable: error inがでる。

mogumogu22

総合スコア24

PHP

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

0グッド

0クリップ

投稿2019/08/25 17:22

編集2019/08/28 13:53

前提・実現したいこと

教本みながら登録画面作ってます。Notice: Undefined variable: error in のエラーが出てしまいます。
エラーにかかわりそうなところをnullにしたら、次の画面へ進まなくなってしまいました。
どうしたらよいか教えていただけると幸いです。
■■な機能を実装中に以下のエラーメッセージが発生しました。

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

Undefined index: name in が88,89行に Undefined index: email in が97,100行に Undefined index: password in が108,111行に出ます。 パスワードの入力画面にも「・・・・・・・・・・・・・・・・・・・・」とあるのでエラーが出ていると思われます。

php

<?php require('../dbconnect.php'); session_start(); $error['name'] = ''; $error['email'] = ''; $error['password'] = ''; $error['password'] = ''; $_POST['name'] = ''; $_POST['email'] = ''; $_POST['password'] = ''; if (!empty($_POST)){ if ($_POST['name'] == '') { $error['name'] = 'blank'; } if ($_POST['email'] == '') { $error['email'] = 'blank'; } if (strlen($_POST['password']) < 4) { $error['password'] = 'length'; } if ($_POST['password'] == '') { $error['password'] = 'blank'; } //---------- Check for duplicate accounts -------------------------------------------------// if(empty($error)) { $member = $db->prepare('SELECT COUNT(*) AS cnt FROM members WHERE email=?'); $member->execute(array($_POST['email'])); $record = $member->fetch(); if ($record['cnt'] > 0) { $error['email'] = 'duplicate'; } if(empty($error)) { $_SESSION['join'] = $_POST; header('Location: check.php'); exit(); } } if($_REQUEST['action'] == 'rewrite') { $_POST = $_SESSION['join']; $error['rewrite'] = true; } } ?> <!-----------end------------------------------------------------> <meta charset="UTF-8"> <title></title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="format-detection" content="email=no,telephone=no,address=no"> <link href="../font/css/open-iconic-bootstrap.css" rel="stylesheet"> <!-- BootstrapのCSS読み込み --> <link href="../css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery読み込み --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" ></script> <!-- BootstrapのJS読み込み --> <script src="../js/bootstrap.min.js"></script> <!---css-------> <link rel="stylesheet" href="../css/join.css"> <link rel="stylesheet" href="../css/common.css"> <!---Google Material Icons-------> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> </head> <body> <header class="text-center mt-3"> <img class="head_rogo ml-md-5" src="../images/SVG/rogo.svg"> <div class="float-right mr-md-3"> <img class="head_icon mr-2" src="../images/SVG/head_login.svg"> <img class="head_icon mr-2 mt-1" src="../images/SVG/head_favorite.svg"> <img class="head_icon mr-2" src="../images/SVG/head_bag.svg"> </div> <div class="border-bottom ml-3 mr-3"></div> </header> <main> <!-----------contents-------------------------------------------------------------------------------------------------> <div class="container"> <div class="border-pink f-darkpink mt-4"><img class="title_icon mr-2 mb-2" src="../images/SVG/head_login.svg">アカウント作成</div> <form class="f-white" action="" method="post" > <div class="form-group w-25 formwidth"> <label for="inputname">name<span class="required ml-2 fs-8 f-darkpink">必須</span></label> <input type="text" name="name" class="form-control" id="inputname" value="<?php echo htmlspecialchars($_POST['name'],ENT_QUOTES); ?>"/> <?php if ($error['name'] == 'blank'): ?> <p class="error">*名前を入力してください。</p> <?php endif; ?> </div> <div class="form-group w-50 formwidth"> <label for="exampleInputEmail1">email<span class="required ml-2 fs-8 f-darkpink">必須</span></label> <input type="text" name="email" class="form-control" id="exampleInputEmail1" value="<?php echo htmlspecialchars($_POST['email'], ENT_QUOTES); ?>"/> <?php if ($error['email'] == 'blank'): ?> <p class="error">*メールアドレスを入力して下さい</p> <?php endif; ?> <?php if ($error['email'] == 'duplicate'): ?> <p class="error">*指定されたメールアドレスは既に登録されています</p> <?php endif; ?> </div> <div class="form-group w-50 formwidth"> <label for="exampleInputPassword1">password<span class="required ml-2 fs-8 f-darkpink">必須</span></label> <input type="password" name="password" class="form-control" id="exampleInputPassword1" value="<?php echo htmlspecialchars($_POST['password'],ENT_QUOTES); ?>"/> <?php if ($error['password'] == 'blank'): ?> <p class="error">*パスワードを入力してください</p> <?php endif; ?> <?php if ($error['password'] == 'length'): ?> <p class="error">*パスワードは4文字以上で入力してください</p> <?php endif; ?> </div> <div class="text-center pt-5"> <input type="submit" class="btn bg-pink f-white" value="アカウント作成"> </div> </form>

したはアドバイスをいただいて変更したものです。

php

<head> <!-----------Confirmation of input items------------------------------------------------> <?php require('../dbconnect.php'); session_start(); $error =[]; if (!empty($_POST)){ if (array_key_exists($_POST['name']) && $_POST['name'] == '') { $error['name'] = 'blank'; } if (array_key_exists($_POST['email']) && $_POST['email'] == '') { $error['email'] = 'blank'; } if (array_key_exists($_POST['password']) && strlen($_POST['password']) < 4) { $error['password'] = 'length'; } if (array_key_exists($_POST['password']) && $_POST['password'] == '') { $error['password'] = 'blank'; } //---------- Check for duplicate accounts -------------------------------------------------// if(empty($error)) { $member = $db->prepare('SELECT COUNT(*) AS cnt FROM members WHERE email=?'); $member->execute(array($_POST['email'])); $record = $member->fetch(); if ($record['cnt'] > 0) { $error['email'] = 'duplicate'; } $_SESSION['join'] = $_POST; header('Location: check.php'); exit(); } if($_REQUEST['action'] == 'rewrite') { $_POST = $_SESSION['join']; $error['rewrite'] = true; } } ?> <!-----------end------------------------------------------------> <meta charset="UTF-8"> <title></title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="format-detection" content="email=no,telephone=no,address=no"> <link href="../font/css/open-iconic-bootstrap.css" rel="stylesheet"> <!-- BootstrapのCSS読み込み --> <link href="../css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery読み込み --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" ></script> <!-- BootstrapのJS読み込み --> <script src="../js/bootstrap.min.js"></script> <!---css-------> <link rel="stylesheet" href="../css/join.css"> <link rel="stylesheet" href="../css/common.css"> <!---Google Material Icons-------> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> </head> <body> <header class="text-center mt-3"> <img class="head_rogo ml-md-5" src="../images/SVG/rogo.svg"> <div class="float-right mr-md-3"> <img class="head_icon mr-2" src="../images/SVG/head_login.svg"> <img class="head_icon mr-2 mt-1" src="../images/SVG/head_favorite.svg"> <img class="head_icon mr-2" src="../images/SVG/head_bag.svg"> </div> <div class="border-bottom ml-3 mr-3"></div> </header> <main> <!-----------contents-------------------------------------------------------------------------------------------------> <div class="container"> <div class="border-pink f-darkpink mt-4"><img class="title_icon mr-2 mb-2" src="../images/SVG/head_login.svg">アカウント作成</div> <form class="f-white" action="" method="post" > <div class="form-group w-25 formwidth"> <label for="inputname">name<span class="required ml-2 fs-8 f-darkpink">必須</span></label> <input type="text" name="name" class="form-control" id="inputname" value="<?php echo htmlspecialchars($_POST['name'],ENT_QUOTES); ?>"/> <?php if ($error['name'] == 'blank' ): ?> <p class="error">*名前を入力してください。</p> <?php endif; ?> </div> <div class="form-group w-50 formwidth"> <label for="exampleInputEmail1">email<span class="required ml-2 fs-8 f-darkpink">必須</span></label> <input type="text" name="email" class="form-control" id="exampleInputEmail1" value="<?php echo htmlspecialchars($_POST['email'], ENT_QUOTES); ?>"/> <?php if ($error['email'] == 'blank'): ?> <p class="error">*メールアドレスを入力して下さい</p> <?php endif; ?> <?php if ($error['email'] == 'duplicate'): ?> <p class="error">*指定されたメールアドレスは既に登録されています</p> <?php endif; ?> </div> <div class="form-group w-50 formwidth"> <label for="exampleInputPassword1">password<span class="required ml-2 fs-8 f-darkpink">必須</span></label> <input type="password" name="password" class="form-control" id="exampleInputPassword1" value="<?php echo htmlspecialchars($_POST['password'],ENT_QUOTES); ?>"/> <?php if ($error['password'] == 'blank'): ?> <p class="error">*パスワードを入力してください</p> <?php endif; ?> <?php if ($error['password'] == 'length'): ?> <p class="error">*パスワードは4文字以上で入力してください</p> <?php endif; ?> </div> <div class="text-center pt-5"> <input type="submit" class="btn bg-pink f-white" value="アカウント作成"> </div> </form>

試したこと

エラーにかかわりそうなところnullにしてみた。

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

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

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

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

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

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

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

CHERRY

2019/08/25 20:59

エラーメッセージには、行数なども記載されていると思いますので、途中で省略などはしないでそのまま記載していただけないでしょうか? ( ディレクトリやファイル名に個人名などが含まれていて名前などを隠したい場合は、隠したい部分の文字だけを置き換えてください。)
mogumogu22

2019/08/27 15:03

89、90、97、98、101、109、112の行でエラーが出ていました。行数書かないとエラー部分わからないですよね>< 質問の仕方が良くなかったですね。教えてくださりありがとうございます!
m.ts10806

2019/08/27 21:12 編集

質問編集して追記してください
退会済みユーザー

退会済みユーザー

2019/08/27 23:28

教本に書いてあるコードを写経してこれなら、その本は廃棄してください
mogumogu22

2019/08/28 13:59 編集

遅くなりすみません。編集しました! ネットでおすすめされていたのを買ったのですがあまりよくない本だったのでしょうか?>< 皆さんのアドバイス見ているとわからないことばかりなのでもう少し踏み込んだ内容のありそうな教科書見たほうがいいように思えてきました。
m.ts10806

2019/08/28 13:58

書籍ではなくPHPマニュアルを。
mogumogu22

2019/08/29 11:28

マニュアルみつつ、勉強しないとだめだと思いました。教えていただきありがとうございます。
guest

回答2

0

ベストアンサー

セキュリティ的にはpostデータのパスワードは引き継いではいけません
あとはこんな感じでバリデートも検討してください

PHP

1<?PHP 2$h=function($str){return htmlspecialchars($str);}; 3foreach(["name","email","password"] as $val){ 4 $$val=filter_input(INPUT_POST,$val); 5 $error[$val]=""; 6} 7if(!is_null($name)){ 8 if ($name===""){ 9 $error['name'] = '*名前を入力してください。'; 10 } 11} 12if(!is_null($password)){ 13 if ($password===""){ 14 $error['password'] = '*パスワードを入力してください'; 15 }elseif(filter_input(INPUT_POST,"password",FILTER_VALIDATE_REGEXP,["options"=>["regexp"=>"/^[0-9a-z]+$/i"]])===false){ 16 $error['password'] = '*パスワードは英数字で入力してください'; 17 }elseif (strlen($password) < 4) { 18 $error['password'] = '*パスワードは4文字以上で入力してください'; 19 } 20} 21if(!is_null($email)){ 22 if ($email===""){ 23 $error['email'] = '*メールアドレスを入力して下さい'; 24 }elseif(filter_input(INPUT_POST,"email",FILTER_VALIDATE_EMAIL)===false){ 25 $error['email'] = '*メールアドレスの形式がおかしい'; 26 }else{ 27 $stmt = $db->prepare('SELECT COUNT(*) AS cnt FROM members WHERE email=?'); 28 $stmt->execute([$email]); 29 $row=$stmt->fetch(PDO::FETCH_ASSOC); 30 if ($row['cnt'] > 0) { 31 $error['email'] = '*指定されたメールアドレスは既に登録されています'; 32 } 33 } 34} 35?> 36<form method="post"> 37 <div class="form-group w-25 formwidth"> 38 <label for="inputname">name<span class="required ml-2 fs-8 f-darkpink">必須</span></label> 39 <input type="text" name="name" class="form-control" id="inputname" 40 value="<?=$h($name);?>"/> 41 <?=$error['name'];?> 42 </div> 43 <div class="form-group w-50 formwidth"> 44 <label for="exampleInputEmail1">email<span class="required ml-2 fs-8 f-darkpink">必須</span></label> 45 <input type="text" name="email" class="form-control" id="exampleInputEmail1" 46 value="<?=$h($email);?>"/> 47 <?=$error['email'];?> 48 </div> 49 <div class="form-group w-50 formwidth"> 50 <label for="exampleInputPassword1">password<span class="required ml-2 fs-8 f-darkpink">必須</span></label> 51 <input type="password" name="password" class="form-control" id="exampleInputPassword1" 52 value="" /> 53 <?=$error['password'];?> 54 </div> 55 <div class="text-center pt-5"> 56 <input type="submit" class="btn bg-pink f-white" value="アカウント作成"> 57 </div> 58</form>

投稿2019/08/26 01:49

yambejp

総合スコア114585

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

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

m.ts10806

2019/08/26 01:51

>$_SESSION['join'] = $_POST; 確かにここは危ないですね。
mogumogu22

2019/08/27 14:59

コードありがとうございます!変更したらエラーはすべて消えました! セキュリティももっと考えてつくらないとだめなのですね。 ちょっとコードが難しく感じましたが、徐々に勉強しつつ理解していけたらとおもいます。 これからの勉強の足掛かりにさせていただきたいと思います。教えてくださってありがとうございました!
mogumogu22

2019/08/29 11:31

コード難しくて自分ではまだ作れそうにないですが、エラーも出ず目的のもができたのでベストアンサーに選ばせていただきました。 アドバイスしてくださったみなさまありがとうございました。
guest

0

配列としての$error自体の初期化が必要に思います。

php

1$error = [];

また本問題とは関係はほぼないですが$_POSTに直接値を代入しているところが散見されます。
これはやってはいけません。
$_POSTにはmethod=POSTのformから送信された情報が自動的に割り当てられます。
値を代入してしまうと送信される情報が全て上書きされてしまうことになります。
特に冒頭で全部空を代入していますよね。
これではどうやっても何も送られてきません。

もし何かしら値を加工するとしても一度別の変数に受け取ってその変数だけを加工しましょう。
(たとえばhtmlspecialchars()で出力する場合)

もう一点、下記のようになっている箇所がありますね。

php

1if(empty($error)) { 2 if(empty($error)) { 3 } 4}

このifのネストは全く意味がありません。
はじめのifの内部でレコード件数をチェックされているようですが、
emailが空でなければチェック可能なので、emailが空でないときにチェックするとこのifのネストが1つ減ります。

それに冒頭で初期化していることによって絶対にempty()はtrueになりません。

php

1<?php 2$e["a"] = ""; 3if(empty($e)) { 4 echo 1; 5}else{ 6 echo 2; 7} 8//2

初期化は$error本体だけにしcount()でチェックされた方が良いです。
※$_POSTのところも同様にempty()よりはcount()のほうが適当。

投稿2019/08/25 21:07

m.ts10806

総合スコア80765

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

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

mogumogu22

2019/08/27 14:53

回答ありがとうございます! 変更したら、質問のエラーはなくなったのですが、Undefined index: name in のエラーが、 value="<?php echo htmlspecialchars($_POST['hoge'],ENT_QUOTES); と <?php if ($error['name'] == 'blank' ): ?> の行に出てくるようになりました。 issetを <?php if ($error['name'] == 'blank' && isset($_POST['name']) ): ?> と if (count($_POST) != 0){ if ($_POST['name'] == '' && isset($_POST['name'])) { $error['name'] = 'blank'; } if ($_POST['email'] == '' && isset($_POST['email'])) { $error['email'] = 'blank'; } if (strlen($_POST['password']) < 4 && isset($_POST['password'])) { $error['password'] = 'length'; } if ($_POST['password'] == '' && isset($_POST['password'])) { $error['password'] = 'blank'; } のように入れてみたのですが、何も変化がありませんでした。 どうしたら、改善できるか、よろしければ教えていただけませんでしょうか? countでチェックということですが、あっているかわからないのですが、 if (count($_POST) != 0){....}のように変更してみました。 ifのネスト構造に関してはわかりました。教えていただきありがとうございます!
m.ts10806

2019/08/27 21:15

ifの式の評価は左側から行うのでその場所では意味がありません。 あとキーチェックはisset()よりarray_key_exists()のほうが適切と思います。 「変更したら」だけではこちらが意図した通りの対応がされたか分かりませんので、 質問本文にコードを「追記」してください。 (回答は今のコードを元にしているので最初のコードを変更するのではなく別のコードブロックにて追記してください)
mogumogu22

2019/08/28 13:58

ifの中でも順番は大事なんですね! array_key_existsはnullでも検知してくれるからいいのでしょうか? アドバイスありがとうございます!変更してみました!
m.ts10806

2019/08/28 14:00

>array_key_existsはnullでも検知してくれるからいいのでしょうか? _POSTが空じゃない時点で「指定したキーが存在するか」にフェーズがうつっているからです。
mogumogu22

2019/08/29 11:26

なるほど!回答ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問