foreach invalid argument and undefined variable - php

I am trying to create a form and i get an error in these lines.
else
{
//report the errors.
echo '<h1> Err... </h1>
<p> The following error(s) have occured</p>';
foreach ($errors as $msg)
{
echo "--$msg<br />\n";
}
echo '</p><p>Please Try Again.</p><p><br/></p>';
}
So, what's wrong?? Here's the error message -
Err...
The following error(s) have occured -
Notice: Undefined variable: errors in
C:\wamp\www\password.php on line 107
Warning: Invalid argument supplied for
foreach() in C:\wamp\www\password.php
on line 107 Please Try Again.
I have set errors as an array.
My code above --
if(isset($_POST['submitted']))
{
require_once('C:\wamp\www\connect.php');
//connecting to db
$errors = array();
if (empty($_POST['email']))
{
$errors[]='Please enter a valid email address.';
}
Here is my complete code -
//forgot password update
include('C:\wamp\www\header.html');
//check if form has been submitted
require_once('C:\wamp\www\connect.php');
//connecting to db
if(isset($_POST['submitted'])) {
$errors = array();
if (empty($_POST['email']))
{
$errors[]='Please enter a valid email address.';
}
else
{
$e = mysqli_real_escape_string($db_name,trim($_POST['email']));
}
//check for current password
if (empty($_POST['password']))
{
$errors[]='Current password does not match.';
}
else
{
$p = mysqli_real_escape_string($db_name,trim($_POST['password']));
}
//check for a new password and match with confirm pass.
if(!empty($_POST['password1']))
{
if($_POST['password1'] != $_POST['cpass'])
{
$errors[] = 'The entered password and confirm password do not match.';
}
else
{
$np=mysqli_real_escape_string($db_name,trim($_POST['password1']));
}
}
if(empty($errors))
//if everything is fine.
//verify the entered email address and password.
$q="SELECT username FROM users WHERE (email='$e' AND password=SHA1('$p'))";
$r=#mysqli_query($db_name,$q);
$num = #mysqli_num_rows($r);
if($num==1)
//if it matches.
//get user id
{
$row=mysqli_fetch_array($r, MYSQLI_NUM);
//udpdate query.
$q="UPDATE users SET password= SHA1('$np') WHERE username=$row[0]";
$r=#mysqli_query($db_name, $q);
if (mysqli_affected_rows($db_name) ==1)
{
echo '<h3>Your password has been updated.</h3>';
}
else {
echo '<h3>Whops! Your password cannot be changed due a system error. Try again later. Sorry</h3>';
echo '<p>' .mysqli_error($db_name). 'Query:' . $q.'</p>';
}
exit();
}
else
{
//invalid email and password
echo 'The email address and password do not match';
}
}
else
{
//report the errors.
echo '<h1> Err... </h1>
<p> The following error(s) have occured</p>';
foreach ($errors as $msg)
{
echo "--$msg<br />\n";
}
echo '</p><p>Please Try Again.</p><p><br/></p>';
}
?>

There is no array named $errors. You will have to look further up your script why not.
You can fix the error message by using
if (!empty($errors) and (is_array($errors)))
foreach ($errors as $msg)

Your foreach loop is out of the scope in regards to where the $error array is defined.
Your code in a nutshell:
if(isset($_POST['submitted'])) {
$errors = array();
} else {
foreach($errors as $error)
}
If $_POST is not set, than your $errors is not defined.

Move your declaration for "$errors = array()" above the line "if(isset($_POST['submitted'])) {
" and everything should work fine!

You have two problems. The first is the cause of the empty/non-existent array and the second is a lack of testing for it.
The first is that you are testing for errors inside of an if block and then looping through them inside of the else block.
if (isset($_POST['submitted'])) {
// create errors array and set errors
} else {
// loop through array of errors
}
So if errors are set, the script doesn't make it to the loop. If the script makes it to the loop, no errors were set.
The second is that you should only enter the foreach loop after you have tested the array:
if (!empty($errors) && is_array($errors)) { // use this line and get rid of the else.
foreach ($errors as $msg) {
echo "--$msg<br />\n";
}
echo '</p><p>Please Try Again.</p><p><br/></p>';
} // and close it.

Basically, what's happening here is you're using $errors before it is defined.
It may be that you need to set "$errors = array( )" near the top of your script so that it is always at least an empty array.

Related

PHP I thought I had defined username, why is my code telling me otherwise?

I am struggling to understand why my code is telling me that my username is undefined whenever I try to load up this page. the error is Notice: Undefined index: username in /home/jmask072/public_html/login.php on line 12. Any help is appreciated.
<?php
$users = array("user" => '$2y$10$yHL4GKr4pKxnBJ1L2xlqYuI/k0kviae2NbIQNJLFeXgVclT2hZeDi');
$isLoggedIn = false;
$errors = array();
$required = array("username", "pass");
foreach ($required as $key => $value) {
if (!isset($_POST[$value]) || empty($_POST[$value])) {
$errors[] = "please fill out the form";
}
}
if (array_key_exists($_POST['username'],$users)) {
$userPassword = $_POST['pass'];
$dbPass = $users[$_POST['username']];
if (password_verify($userPassword,$dbPass) === true) {
$isLoggedIn = true;
} else {
$isLoggedIn = false;
$errors[] = "Username not found or password incorrect";
}
} else {
$errors[] = "Username not found or password incorrect";
}
require_once("Template.php");
$page = new Template("My Login");
$page->addHeadElement("<link rel=\"stylesheet\" href=\"styles.css\">");
$page->addHeadElement("<script src='hello.js'></script>");
$page->finalizeTopSection();
$page->finalizeBottomSection();
print $page->getTopSection();
if (count($errors) > 0) {
foreach ($errors as $error) {
print "Error";
}
}
else if ($isLoggedIn === true) {
print "Hello, you are logged in";
}
print "<form action =\"login_action.php\" method =\"POST\" class=\"form-signin\">";
print "<h1>Please sign in</h1>\n";
print "<label for=\"inputUser\">Username</label>";
print "<input type=\"password\" name=\"pass\" id=\"inputPassword\" placeholder=\"password\">";
print "<button type=\"submit\"> Sign in</button>";
print $page->getBottomSection();
?>
first you should use a single quotes ' '
it is a very good alternative for backslash
and
print "<label for='inputUser'>Username</label>";
here you add label for inputUser but i dont see any input ??
You do need to make the script work even if the page is not requested correctly because you have no control on the requests it will get. Then you have to make sure that YOU call it correctly when you do it (right now this is not the case).
You are seeing the notice because, even if your code does check for the existence of the POST variables it needs (lines 6-10), even if the check fails it still attempts to read them at line 12.
The whole code block if...then...else starting at line 12 should only be executed if the checks went well (i.e. if(empty($errors)) {...). Now if the page is requested incorrectly at least you will get a useful error message that will help you understand where the problem is.
In this case the error message is "please fill out the form". In fact the code expects a form with two input fields but the one it displays only has the password field (which is unhelpfully labelled "Username") and has no username field. You need to provide both fields and make sure that the name attributes match the POST variables you want to get the data from (the for attribute in the label tags should also match the field name exactly).

Stop PHP Execution But Display HTML

In a Profile page of the User, I want to validate his input with PHP after submission and display errors on the same page before updating in the database.
For this, I'm doing something like:
<div>
<?php
if (isset($_POST["submitted"])) {
if (!isValidEmail($_POST["email"])) {
echo "<p>Please enter a valid email address.</p>";
return; // or exit;
}
if (!isValidPhoneNumber($_POST["phoneNumber"])) {
echo "<p>Please enter a valid phone number.</p>";
return; // or exit;
}
...
if (updateUser($id, $email, $phoneNumber, $name)) {
echo("<meta http-equiv='refresh' content='0'>");
} else {
echo "<p>An error occurred! Could not update your profile information!</p>";
}
}
?>
</div>
<my-footer></my-footer>
So when an error occurs upon PHP validation, the footer doesn't appear. So I understood that with return or exit the page will stop rendering at that command.
What can I do to solve this issue?
I want it to stop execution of the PHP script but display the rest of the HTML page.
You could put your validation logic inside a function at the top of your page, and change all your echo to return.
function validate() {
if (isset($_POST["submitted"])) {
if (!isValidEmail($_POST["email"])) {
return "<p>Please enter a valid email address.</p>";
}
if (!isValidPhoneNumber($_POST["phoneNumber"])) {
return "<p>Please enter a valid phone number.</p>";
}
//...
if (updateUser($id, $email, $phoneNumber, $name)) {
return "<meta http-equiv='refresh' content='0'>";
} else {
return "<p>An error occurred! Could not update your profile information!</p>";
}
}
}
Then simply echo the string returned from the function above the footer.
<div>
<?php echo validate(); ?>
</div>
<my-footer></my-footer>
Note that the above will work because $_POST is a superglobal. However, you may consider changing your function to pass email, phoneNumber, name and id as parameters instead.
Change your flow up a little bit...
if (isset($_POST["submitted"])) {
$has_errors = FALSE;
$err_msg = '';
if (!isValidEmail($_POST["email"])) {
$err_msg .= "<p>Please enter a valid email address.</p>";
$has_errors = TRUE;
}
if (!isValidPhoneNumber($_POST["phoneNumber"])) {
$err_msg .= "<p>Please enter a valid phone number.</p>";
$has_errors = TRUE;
}
if ( $has_errors ) {
echo "<p>Please Correct the following and resubmit...</p>" . $err_msg;
} else {
if (updateUser($id, $email, $phoneNumber, $name)) {
echo("<meta http-equiv='refresh' content='0'>");
} else {
echo "<p>An error occurred! Could not update your profile information!</p>";
}
}
}
Many times you will see PHP frameworks that can handle this for you.
Here's a good website to compare a few: http://phpframeworks.com/
But what you can do is put your footer (and / or the rest of your code) into a function that holds the rest of your code for you, and you can call it later or whenever you need to so you can still end code execution gracefully.
<div>
<?php
function footer() {
$string = "</div>";
$string .= "<my-footer></my-footer>";
return $string;
}
if (isset($_POST["submitted"])) {
if (!isValidEmail($_POST["email"])) {
echo "<p>Please enter a valid email address.</p>";
die(footer()); // Displays footer
}
if (!isValidPhoneNumber($_POST["phoneNumber"])) {
echo "<p>Please enter a valid phone number.</p>";
die(footer()); // Displays footer
}
...
if (updateUser($id, $email, $phoneNumber, $name)) {
echo("<meta http-equiv='refresh' content='0'>");
} else {
die("<p>An error occurred! Could not update your profile information!</p>" . footer()); // kills the page execution, but still returns the foot of the page.
}
}
echo footer();
?>

Creating a registration page in PHP

Hi guys so im creating this registration page for my website in php..This is the PHP script
# Script 9.5 - register.php #2
// This script performs an INSERT query to add a record to the users table.
$page_title = 'Register';
include ('includes/header.html');
// Check for form submission:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$errors = array(); // Initialize an error array.
// Check for a name:
if (empty($_POST['name'])) {
$errors[] = 'You forgot to enter your name.';
} else {
$n = mysqli_real_escape_string($dbh, trim($_POST['name']));
}
// Check for an email:
if (empty($_POST['email'])) {
$errors[] = 'You forgot to enter your email.';
} else {
$e = mysqli_real_escape_string($dbh, trim($_POST['email']));
}
// Check for a password and match against the confirmed password:
if (!empty($_POST['pass1'])) {
if ($_POST['pass1'] != $_POST['pass2']) {
$errors[] = 'Your password did not match the confirmed password.';
} else {
$p = mysqli_real_escape_string($dbh, trim($_POST['pass1']));
}
} else {
$errors[] = 'You forgot to enter your password.';
}
// Check for contact number:
if (empty($_POST['contact_no'])) {
$errors[] = 'You forgot to enter your contact no.';
} else {
$cn = mysqli_real_escape_string($dbh, trim($_POST['contact_no']));
}
if (empty($errors)) { // If everything's OK.
require 'connect_db.php';
$conn= mysqli_connect('*****' , '*****', '*****' , '*****' ,****);
// Make the query:
$q = ("INSERT INTO register_user(name, email, pass, contact_no) VALUES ('$n', '$e','$p','$cn')");
$r = #mysqli_query ($dbh, $q);// Run the query.
if ($r) { // If it ran OK.
// Print a message:
echo '<h1>Thank you!</h1>
<p>You are now registered. </p>
<p>Login </p>';
} else { // If it did not run OK.
// Public message:
echo '<h1>System Error</h1>
<p class="error">You could not be registered due to a system error. We apologize for any inconvenience.</p>';
// Debugging message:
echo '<p>' . mysqli_error($dbh) . '<br/><br/> Query: ' . $q . '</p>';
} // End of if ($r) IF.
mysqli_close($dbh); // Close the database connection.
// Include the footer and quit the script:
include ('includes/footer.html');
exit();
} else { // Report the errors.
echo '<h1>Error!</h1>
<p class="error">The following error(s) occurred:<br>';
foreach ($errors as $msg) { // Print each error.
echo " - $msg<br>";
}
echo 'Please try again.</p>';
} // End of if (empty($errors)) IF.
mysqli_close($dbh); // Close the database connection.
But the thing is once i register this is the output:
System Error
You could not be registered due to a system error. We apologize for any inconvenience.
Query: INSERT INTO register_user(name, email, pass, contact_no) VALUES ('', '','','')
so im kindly would glad for any assistance
You're calling mysqli_real_escape_string() BEFORE you establish your DB connection. This is not permitted. You MUST have a connection before doing the escape operations.
That means every single one of your form fields is going to be a boolean FALSE value, which signifies failure.
Your code should be structured
1. connect to db
2. process form inputs
3. if form inputs ok, insert into db
You've got #1 and #2 reversed.

Using 'IF.. ELSE' to change variable and use it in 'form action...'

I've created a test form that uses IF.. ELSE to validate data in a simple form. This works ok and any validation messages or errors are posted to the same page (userform.php) to inform the user of success or otherwise.
What I want to do now is take the user to a different page on successful completion of the form. Here's my code so far:
<?php
if (isset($_POST['email'], $_POST['password'])) {
$errors = array ();
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$email = $_POST ['email'];
$password = $_POST ['password'];
if (empty ($firstname) || empty ($lastname) || empty ($email) || empty ($password)) {
$errors [] = "Please complete the form";
}
if (empty($email)) {
$errors [] = "You must enter an email address";
}
if (empty($password)) {
$errors [] = "You must enter a password";
}
if (filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE){
$errors[] = "Please enter a valid email address";
}
}
if (!empty ($errors)) {
foreach ($errors as $error) {
echo '<strong>', $error ,'</strong><br />';
$result = "userform.php";
}
} else {
$result = "confirm.php";
}
?>
<form action="<?php echo $result ?>" method="post">
The idea is that the users success or otherwise in completing the form changes the $result variable which is used in the form action. The above code doesn't work, so how would I do it?
Is it even possible?
instead of "form action=" at the bottom:
<?php
include($result);
?>
As I understand it you want it to work like so:
User fills form
User submits form
Form submission goes to userform.php
If all values validate, continue to confirm.php
If not, return to userform.php
If that's the case, I don't think you want to change the form action: that would require that the user re-submit the form. Instead, use a HTTP redirect to send them to confirm.php:
header("Location: confirm.php");
... or if you wanna be really by-the-book about it:
header("Status: 303 See Other");
header("Location: http://exampel.com/confirm.php"); // according to the protocol,
// `Location` headers should be full URLs
<?php
/* ... */
if (!empty ($errors)) {
foreach ($errors as $error) {
echo '<strong>', $error ,'</strong><br />';
}
?>
<form action="userform.php" method="post">
<?php
} else {
header("Location: confirm.php");
// if you need to pass additional information to confirm.php, use a query string:
// header("Location: confirm.php?var1=".$var1);
}
?>
The way you're doing it now, will redirect the user to confirm.php if they submit the form for a second time. You could change your code to this:
} else {
// $result = "confirm.php";
header("Location: confirm.php");
exit();
}
That way, if everything has been entered, the user will be redirected to confirm.php. But what do you do with the variables if everything is allright? They won't be taken to the new page.
} else {
$result = confirm.php;
foreach($_POST as $key => $val){
$input.="<input type='hidden' name='$key' value='$val' />";
}
$form = "<form method='post' name='confirm' action='confirm.php'>".$input."</form>";
$script = "<script type='text/javascript'>document.confirm.submit();</script>";
echo $form.$script;
}
empty ($errors)
will ALWAYS return empty. That's why you always get:
$result = 'confirm.php';
Check return values here
Also, I don't think you can do this easily. Instead, why don't you just create a check.php or whatever to check the variables/check for errors, etc. Then do whatever you want (redirect back to the form-filling page or proceeding to confirm.php page.
The whole idea is wrong. You have to fix 2 issues in your code.
1. A major one. Learn to properly indent nested code blocks!
It's impossible to read such an ugly mass with no indents.
2. A minor one.
I see no use of confirmation page here. What are you gonna do on that page? And from where you're going to get form values?
It seems you have to either use just simple Javascript code to show a confirmation or store entered data into session
And, I have to say, that show a confirmation page for simply a feedback form is quite uncommon practice.
So, I think you really need only one form action and only thing to ccare is properly filled form
<?
if ($_SERVER['REQUEST_METHOD']=='POST') {
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$email = $_POST ['email'];
$password = $_POST ['password'];
$errors = array();
if (empty ($firstname) || empty ($lastname) || empty ($email) || empty ($password)) {
$errors [] = "Please complete the form. All fields required.";
}
if (filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE){
$errors[] = "Please enter a valid email address";
}
if (!$errors) {
// do whatever you wish to this data
// and then redirect to whatever address again
// the current one is a default
header("Location: ".$_SERVER['PHP_SELF']);
exit;
} else {
// all field values should be escaped according to HTML standard
foreach ($_POST as $key => $val) {
$form[$key] = htmlspecialchars($val);
}
} else {
$form['fiestname'] = $form['lasttname'] = $form['email'] = $form['password'] = '';
}
include 'form.tpl.php';
?>
while in the form.tpl.php file you have your form fields, entered values and conditional output of error messages
<? if ($errors): ?>
<? foreach($errors as $e): ?>
<div class="err"><?=$e?></div>
<? endforeach ?>
<? endif ?>
<form method="POST">
<input type="text" name="firstname" value=<?=$form['firstname']>
... and so on

if else statements php

How do I get this to not display when you first go to the page???
if ($error) {
echo "Error: $error<br/>";
}
if ($keycode) {
echo "Keycode: $keycode<br/>";
}
<?php
session_start();
if ($_SESSION['been_here'] == true) {
// show what you need to show
}
else {
// don't show it
$_SESSION['been_here'] = true;
}
?>
The point here is that $_SESSION-variables "last" (as long as you session_start()).
Google "php sessions" for more information, and ask more questions on SO if necessary. :)
Use session_destroy(); to destroy the session.
<?php
if ($error){ echo "Error: $error
"; } if ($keycode) { echo "Keycode: $keycode
"; }
Based on the comments, it seems that your conditional is evaluating to true before you expect it to. Without seeing more of your code, this is only a guess, but I believe your problem is that you're giving the variable $error a default/temporary value when you create it that doesn't mean false. For example:
$error = "default error message, change me later";
// Later...
if ($error) { // This evaluates to true
echo "Error: $error<br/>";
}
If so, you'll want to check out PHP's documentation on casting to booleans, and maybe use something like this (with contribution from Christian's answer):
$error = "0"; // Default error message, change it later
// Later...
if($_SESSION['been_here'] == true)
$error = "This is the real error message.";
// Even later...
if ($error) {
echo "Error: $error<br/>";
}
This probably works for you:
if (isset($error) && !empty($error)) {
echo "Error: $error<br/>";
}
I cannot say more, because you have not specified what the value of $error might be.
Or you just have to introduce a flag that indicates that an error occurred:
$error = 'Error message.';
$has_error = false;
if(!empty($_POST) && some_condition) { // means it is a POST request
$has_error = true;
}
if($has_error) {
echo "Error: $error<br/>";
}

Categories