1

I am trying to write a simple code for php form. I wrote the php code in the same page as html. Name of the php page is signup.php But I am getting error like this:

Notice: Undefined index: nm in C:\xampp\htdocs\mini_project\signup2.php on line 5

Notice: Undefined index: email in C:\xampp\htdocs\mini_project\signup2.php on line 6

If I separate the php and html code in two different pages there is no problem with my code.

Why can't I write php and html in the same page? What I am doing wrong?

I am using php 7.

  <?php

   include 'connect.php'

$nm = $_POST['nm'];
$email = $_POST['email'];
$password = $_POST['password'];
$cpassword = $_POST['cpassword'];
$type = $_POST['type'];
$remember = $_POST['remember'];
$signup = $_POST['signup'];

if (isset($signup))
{

  $query = "INSERT INTO user_details (nm,email,pass,user_type) VALUES ('$nm','$email','$password','$type')";
 $result = mysqli_query($conn,$query);
 }
?>


    <!DOCTYPE html>
     <html>
      <head>
   <meta name="viewport" content="width=device-width, initial-scale=1.0">

 <link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
   <script src="js/jquery.min.js"></script>
 <script src="js/bootstrap.min.js"></script>

     <body>
     <div class="container">
    <div class="row">
        <div class="col-md-4 col-md-offset-4">
            <div class="login-panel panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title">Please Sign In</h3>
                </div>
                <div class="panel-body">
                    <form role="form" method="post" action="signup.php">
                        <fieldset>
                            <div class="form-group">
                                <input class="form-control" placeholder="Please Enter Name" name="nm" id="nm" type="text" autofocus>
                            </div>
                            <div class="form-group">
                                <input class="form-control" placeholder="Please Enter E-mail" name="email" id="email" type="email">
                            </div >
                            <div class="form-group">
                                <input class="form-control" placeholder="Please Enter Password" name="password" id="password" type="password" value="">
                            </div>
                            <div class="form-group">
                                <input class="form-control" placeholder="Please Confirm Password" name="cpassword" id="cpassword" type="password" value="">
                            </div>
                            <div class="form-group">
                                <select class="form-control" align="center" name="type">
                                    <option value="0">Please Select User Type</option>
                                    <option value="1">I want to Hire</option>
                                    <option value="Second Year">I want to Work</option>
                                </select>
                            </div>
                            <div class="checkbox">
                                <label>
                                    <input name="remember" id="remember" type="checkbox" value="Remember Me">Remember Me
                                </label>
                            </div>
                            <!-- Change this to a button or input when using this as a form -->
                            <input type="submit" name="signup" id="signup" value="Signup" class="btn btn-lg btn-primary btn-block">

                        </fieldset>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

</body>

</html>
Dave
  • 3,073
  • 7
  • 20
  • 33
Arnab
  • 398
  • 1
  • 6
  • 16

7 Answers7

5

The reason for that is because you haven't submitted the form yet, but you are already trying to define variables based on $_POST values. You need to check if the values are set first:

if (isset($_POST['nm'])) $nm = $_POST['nm'];
if (isset($_POST['email'])) $email = $_POST['email'];

or using a ternary operator:

$nm = isset($_POST['nm']) ? $_POST['nm'] : "";
$email = isset($_POST['email']) ? $_POST['email'] : "";

or in PHP 7, simply:

$nm = $_POST['nm'] ?? "";
$email = $_POST['email'] ?? "";
Rax Weber
  • 3,730
  • 19
  • 30
1

That is because the respective keys in the $_POST array have not yet been set -- They are set on form submission.

You should first test that the variables are set (using the isset() function) before attempting to access them; e.g.

<?php
include 'connect.php'

if (isset($_POST['signup')) {
    $nm = $_POST['nm'];
    $email = $_POST['email'];
    // The rest of your code here...
}
?>
Drefetr
  • 412
  • 2
  • 7
  • You are still assuming that all fields have been send with the POST request, or worded differently: You're still trusting the client. That will leads to errors, or at least unwanted behavior from the script. Always check that you've got the input, and that it is within accepted parameters, and handle the error-conditions. – ChristianF Oct 28 '16 at 06:27
  • I agree, that is correct; but, providing substantive input checking & validation did seem beyond the scope of the question. – Drefetr Oct 28 '16 at 06:34
0

You're running your code no matter how the page is requested but the variables are only defined when you post something to the page. You should check that it is a POST to that page and not just a regular GET request. Might work fine if you just move all your code inside a check for signup being defined.

Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
0

While your page is load at the time your $_POST data is not set, so that it will not render the keys that you mentioned. Use any of the following solution:

1) check for the set key:

<?php

include 'connect.php'

$nm = isset($_POST['nm']) ? $_POST['nm'] : "";
$email = isset($_POST['email']) ? $_POST['email'] : "";
$password = isset($_POST['password']) ? $_POST['password'] : "";
$cpassword = isset($_POST['cpassword']) ? $_POST['cpassword'] : "";
$type = isset($_POST['type']) ? $_POST['type'] : "";
$remember = isset($_POST['remember']) ? $_POST['remember'] : "";
$signup = isset($_POST['signup']) ? $_POST['signup'] : "";

if (isset($signup))
{

  $query = "INSERT INTO user_details (nm,email,pass,user_type) VALUES ('$nm','$email','$password','$type')";
 $result = mysqli_query($conn,$query);
 }
?>

2) or you can sinply write like as follow:

<?php

include 'connect.php'

if (isset($_POST['signup']))
{
$nm = $_POST['nm'];
$email = $_POST['email'];
$password = $_POST['password'];
$cpassword = $_POST['cpassword'];
$type = $_POST['type'];
$remember = $_POST['remember'];
$signup = $_POST['signup'];
  $query = "INSERT INTO user_details (nm,email,pass,user_type) VALUES ('$nm','$email','$password','$type')";
 $result = mysqli_query($conn,$query);
 }
?>
Keyur Mistry
  • 926
  • 6
  • 18
0

your php code should be write like this:

 <?php
 if($_REQUEST['method'] == "POST") {
     include 'connect.php'

     $nm = $_POST['nm'] ?? "";
     $email = $_POST['email'] ?? "";
     $password = $_POST['password'] ?? "";
     $cpassword = $_POST['cpassword'] ?? "";
     $type = $_POST['type'] ?? "";
     $remember = $_POST['remember'] ?? "";
     $signup = $_POST['signup'] ?? "";

     if (isset($signup))
     {
        $query = "INSERT INTO user_details (nm,email,pass,user_type) VALUES ('$nm','$email','$password','$type')";
        $result = mysqli_query($conn,$query);
     }
 }
 ?>
JazZ
  • 4,469
  • 2
  • 20
  • 40
wang sky
  • 131
  • 5
  • Add some explanation for why the code should be written like this, and add protection against SQL injections. (Or at least a notice about these.) After you've done that, you've got a good answer. – ChristianF Oct 28 '16 at 06:24
  • @ChristianF maybe he is a new phper – wang sky Oct 28 '16 at 06:26
  • The OP is a new programmer without question, which makes it even more important to explain why. Not to mention how to protect oneself against the most common vulnerabilities. – ChristianF Oct 28 '16 at 06:28
0

As already said across many answers, the reason you're getting the notices is because you're trying to use data which haven't been sent to the server yet. To avoid these you first have to test if you have indeed been sent the data, and only then act upon it.
This is the reason why it works if you put it into a separate file, but it would still give you the same notices if you open up the target URL for the form directly (bypassing the form).

Note that even if stuff have been posted to the server, it doesn't mean that all of the data you expect will be there. Some times normal functions of the browsers mean that they won't send some fields (unchecked checkboxes etc), and other times it's the user trying to do something you don't want them doing.
This is why it's important to also check each and every value. Not only if it exists, but also if it is within an acceptable range of input values/patterns. This last bit is called input validation, and is normally done with the filter_var() function and its bretheren.

So, combining all of this into a script example:

include 'connect.php';

if (isset ($_POST['signup'])) {
    $error = process_signup ($conn);
}

/**
 * Processes the signup form, and saves the registration to the DB if successful.
 * Returns an error string detailing what went wrong, in case of errors.
 * 
 * @param PDO $db
 * @return void|string
 */
function process_signup (PDO $db) {
    // Testing for early exit conditions first, so that we don't do unnecessary work.
    $signup = filter_input (INPUT_POST, 'signup', FILTER_VALIDATE_BOOLEAN);
    if (!isset ($signup)) {
        // Since we're not signing up, just exit early.
        return;
    }

    // Using a variable to keep track of the validation status.
    $errors = array ();

    // Validate that the name only contains "word characters" as defined by regex.
    $options = array ('options' => array ('regexp' => '/^\w+\\z/u'));
    $nm = filter_input (INPUT_POST, 'nm', FILTER_VALIDATE_REGEXP, $options);
    if (!$nm) {
        // Add more descriptive error messages here.
        $errors[] = 'Name';
    }

    $email = filter_input (INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
    if (!$email) {
        $errors[] = 'Email';
    }

    // Create a regex that defines a _minimum_ level of password complexity.
    $password = filter_input (INPUT_POST, 'password', FILTER_VALIDATE_REGEXP, $options);
    if (!$password) {
        $errors[] = 'Password';
    }

    // If the password confirmation is set, and identical to the validated password, we're good.
    $cpassword = isset ($_POST['cpassword']) && $_POST['cpassword'] === $password ? true : false;
    if (!$cpassword) {
        $errors[] = 'Password confirmation';
    }

    // These are optional, so no need to add error messages if they're missing/wrong.
    $type = filter_input (INPUT_POST, 'type', FILTER_VALIDATE_INT);
    $remember = filter_input (INPUT_POST, 'remember', FILTER_VALIDATE_BOOLEAN);

    // If some of the validation failed, we need to stop here and tell the user about it.
    if (!empty ($errors)) {
        // Note that this is VERY rudimentary, you should do something more informative.
        $errors = "Following fields failed validation: ".implode (', ', $errors);
        return $errors;
    }

    // ALWAYS remember to hash the password!!!
    $password = password_hash ($password, PASSWORD_DEFAULT);

    // Using PDO as it's a bit easier than MySQLi.
    $query = "INSERT INTO user_details (nm,email,pass,user_type) VALUES (:name, :email, :password, :type)";
    $statement = $db->prepare ($query);
    $data = array (
            ':name' => $nm,
            ':email' => $email,
            ':password' => $password,
            ':type' => $type
    );

    if (!$statement->execute ($data)) {
        // Something went wrong with saving the data to the database. Handle it!
        return "Someting went wrong!";
    }

    // Everything is good, so redirect the user to a confirmation page.
    // Redirect prevents reloading the page from re-submitting the data.
    header ("Location: success.php");
    die ();
}

?>

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>

<body>
    <h3 class="panel-title">Please Sign In</h3>

    <form role="form" method="post" action="signup.php">
        <fieldset>
            <input class="form-control" placeholder="Please Enter Name" name="nm" id="nm" type="text" autofocus>
            <input class="form-control" placeholder="Please Enter E-mail" name="email" id="email" type="email">
            <input class="form-control" placeholder="Please Enter Password" name="password" id="password" type="password" value="">
            <input class="form-control" placeholder="Please Confirm Password" name="cpassword" id="cpassword" type="password" value="">

            <select class="form-control" align="center" name="type">
                <option value="0">Please Select User Type</option>
                <option value="1">I want to Hire</option>
                <option value="2">I want to Work</option>
            </select>

            <input name="remember" id="remember" type="checkbox" value="Remember Me">
            <label for="remember">Remember Me</label>

            <input type="submit" name="signup" id="signup" value="Signup" class="btn btn-lg btn-primary btn-block">
        </fieldset>
    </form>
</body>
</html>

Note that I've stripped out a lot of the (unnecessary, IMHO) HTML from this, and note that this is a rather crude example. Enough to show you the steps you need to take, but not quite ready to be used in production. The error handling should be done a bit more graceful, with detailed explanations to the user about what failed and what's required/permitted in these fields.

I would also like to point out the use of prepared statements here, as they are the only way to properly defend against SQL injections.

ChristianF
  • 2,068
  • 9
  • 14
-1

nobody knows what is in settings php.ini, .htaccess, connect.php ... what her errors display rules, at what stages

why not use the design in html file:

if ($ _ POST) {
   $ Nm = isset ($ _ POST [ 'nm']) $ _ POST [ 'nm']: null;?
   ...
}

or alternatively to use display_errors ...

Dmitriy
  • 386
  • 2
  • 5