stuck with empty and foreach - php

<form action="http:\\127.0.0.1\rechecking.php" method="post" enctype="multipart/form- data"><pre>
Enter your first Name: <input type="text" name="fname" size="15"></input>
Enter your Last Name: <input type="text" name="lname" size="15"></input>
Your Email Id: <input type="text" name="email" size="15"></input>
Your age: <input type="text" name="age" size="1"></input>
Upload your Image: <input type="file" name="file"></input>
<input type="Submit" value="Submit"></input></pre>
</form>
<?php
if(!empty($_POST["fname"])&&!empty($_POST["lname"])&&!empty($_POST["email"])&&!empty($_POST["age"]))
{
if($_FILES["file"]["error"]>0)
{
echo $_FILES['file']['error'] ."error is there in uploading files";
}
}
else
{ $emt=array($_POST['fname']=>"Firstname",$_POST['lname']=>"LastName",$_POST['email']=>"Email",$_POST['age']=>"Age");
foreach($emt as $value=>$variable)
{
if(empty($value))
{
echo $variable." cannot be left blank<br />";
}
}
}
?>
The problem is that on leaving all the spaces blank in my formIts only showing the last ement of associative array.
For ex:-Leave firstname,lastname ,email, age then it will just show 'Age filed cannot be left blank'
Similarly if age is already filled in my input field then it will just show 'Email field can not be left empty'
Well I want it to display names of all fields that are left empty

You have to change $key and $variable:
$emt=array("Firstname"=>$_POST['fname'],"LastName"=>$_POST['lname'],"Email"=>$_POST['email'],"Age"=>$_POST['age']);

Change it as
$emt=array("Firstname"=>$_POST['fname'],"LastName"=>$_POST['lname'],"Email"=>$_POST['email'],"Age"=>$_POST['age']);

I think you're confusing:
foreach($emt as $value=>$variable)
{
with
foreach($emt as $variable=>$value)
(I would name the variable $variable $key instead, but's just a matter of taste)
And the same thing goes for the array which other answers has shown.
$emt = array(key => value, key => value, ....);

In order to check if a specific key is empty, you must make sure that it's set first (user can edit his HTML source and not send some field, triggering some warnings in your site).
Other than that, I find your code a little messy so you will find it difficult to debug or read after a while.
Here, I'm rewriting the PHP part to check the field is entered and is not empty.
<?php
$required = array(
'fname' => 'First name',
'lname' => 'Last name',
'email' => 'Email address',
'age' => 'Age',
);
$errors = array(); // Here, we store all the error messages. If it's empty, we are good to go.
foreach ($required as $key => $label) {
if (isset($_POST[$key]) || empty($_POST[$key])) {
$errors[] = "$label field is required.";
}
}
if (!isset($_FILES["file"])) {
$errors[] = 'Please upload an image';
}
elseif (isset($_FILES['file']['error']) && $_FILES['file']['error']) {
$errors[] = 'An error occurd while uploading your photo';
}
if ($errors) {
print '<ul>';
foreach ($errors as $error) {
print "<li>$error</li>";
}
print '</ul>'
}
else {
// All fields are filled and not empty, file is uploaded successfully. Process your form.
}
?>

Related

Output $_POST Array Values Inside a While Loop For An Input Element (During Form Validation) — PHP

I have a form that submits images and their titles. It is set up to check for errors via PHP validations on the image title form input elements and output any errors inside each image component (i.e. the instance in the while loop that represents a certain image). This all works OK.
What I would like to do is have it so that when one or more title is filled out correctly, but there are errors on one or more other titles, the $_POST value of the incorrect input is echoed out in the input element so the user doesn't have to re-type it. This has been easy to do on other forms on the site because there is no loop involved, e.g. on a sign up form etc. On a singular instance I would just do <?php echo $image_title; ?> inside the HTML value attribute, which is set referencing $image_title = $_POST['image-title'];]
So my question is, how do I have it so the $image_title $_POST value instances that pass the validations are outputted in their respective <input> elements, when other instances of the $image_title variable fail. If all the checks pass and there are no errors the form is then processed with PDO statements. The form submission button is placed outside of the main loop so all images are processed in one go when all the information is correct. I have a hidden input element that outputs the database image ID for each image, which can be used as a key in a foreach loop of some type. The problem of course being I can't get a foreach loop to work as I would like.
NOTE: To make the code simpler I've removed all the code relating to the outputting the images themselves.
<?php
if(isset($_POST['upload-submit'])) {
$image_title = $_POST['image-title'];
$image_id = $_POST['image-id']; // value attribute from hidden form element
// checks for errors that are later outputted on each image component
forEach($image_title as $index => $title) {
$id=$_POST['image-id'][ $index ];
if(empty(trim($title))){
$error[$id] = "Title cannot be empty";
}
}
if (!isset($error)) {
try {
// update MySQL database with PDO statements
header("Location: upload-details.php?username={$username}");
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
}
} else {
// prevents error being thrown before form submission if input elements are empty
$image_title = "";
}
?>
<form method="post" enctype="multipart/form-data">
<!-- IMAGE DETAILS COMPONENT - START -->
<?php
$user_id = $_SESSION['logged_in'];
$stmt = $connection->prepare("SELECT * FROM lj_imageposts WHERE user_id = :user_id");
$stmt->execute([
':user_id' => $user_id
]);
while ($row = $stmt->fetch()) {
$db_image_id = htmlspecialchars($row['image_id']);
$db_image_title = htmlspecialchars($row['image_title']);
?>
<div class="upload-details-component">
<?php
// output error messages from the validation above
if(isset($error)) {
foreach($error as $element_id => $msg) {
if($element_id == $id) {
echo "<p>** ERROR: {$msg}</p>";
}
}
}
?>
<div class="edit-zone">
<div class="form-row">
<!-- ** THIS IS THE INPUT ELEMENT WHERE I WOULD LIKE THE TITLE OUTPUTTED IF IT DOESN'T FAIL THE VALIDATION ** -->
<input value="<?php echo $image_title; ?>" type="text" name="image-title[]">
</div>
<div class="form-row">
<input type="hidden" name="image-id[]" value="<?php echo $db_image_id; ?>">
</div>
</div>
</div>
<?php } ?> <!-- // end of while loop -->
<!-- submit form button is outside of the loop so that it submits all of the images inside the loop in on go -->
<button type="submit" name="upload-submit">COMPLETE UPLOAD</button>
</form>
i think this is what you want:
<input value="<?php echo htmlentities($image_title); ?>" type="text" name="image-title[<?php echo $db_image_id; ?>]">
foreach ($_POST['image-title'] as $key => $value) {
$stmt->execute([
':image_id' => $key,
':image_title' => $value
]);
}
Edit: I have now created a minimized version and was able to test it successfully. I created the mysql table on my test-maschine to try it out. I hope this will help you now.
With <input name="img[id]" value="title"> an array will created with the following structure: $_POST['img'][id] = title. The id as array key and the title as array value. So the title is uniquely assigned to each id. The array can be walk through with a foreach key=>value loop.
Edit2: I added error checking. If the title is empty or is "testfail" for example, the title will not be written to the database. In addition, the input field keeps the last input (restore $_POST string).
<?php
$connection = new PDO(...);
$error = []; // declare empty array
if(isset($_POST['img'])) {
try {
$q = "UPDATE lj_imageposts SET image_title=:image_title
WHERE image_id = :image_id AND user_id = :user_id";
$stmt = $connection->prepare($q);
foreach($_POST['img'] as $key => $value) {
// here the error check, so that the wrong title
// is not written into the database
if(trim($value) === '' || $value === 'testfail') {
echo "Error image id $key title $value <br>";
$error[$key] = TRUE; // set error var with img-id
continue; // skip to next img, do not execute sql-stmt
}
$stmt->execute([
':image_id' => $key,
':image_title' => $value,
':user_id' => $_SESSION['logged_in']
]);
echo "Update image id $key title $value <br>";
}
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
}
?>
<form method="post" enctype="multipart/form-data">
<?php
$q = "SELECT * FROM lj_imageposts WHERE user_id = :user_id";
$stmt = $connection->prepare($q);
$stmt->execute([':user_id' => $_SESSION['logged_in']]);
while ($row = $stmt->fetch()) {
$id = htmlentities($row['image_id']);
// check if error with img-id is set above
if(isset($error[$row['image_id']])) {
// if error, fill in title from previous post
$title = htmlentities($_POST['img'][$row['image_id']]);
} else {
// if no error, fill in title from database
$title = htmlentities($row['image_title']);
}
?>
<input type="text"
name="img[<?php echo $id; ?>]"
value="<?php echo $title; ?>"><br>
<?php
// alternative version
//echo '<input type="text" name="img['.$id.']" value="'.$title.'"><br>';
}
?>
<button type="submit" name="upload-submit">Test</button>
</form>
This is harder than it needs to be, because you can't uniquely identify a particular title input except by the order it appears on the form, with the associated hidden input beside it. You need to do some careful juggling to correlate the IDs from the database with the $index of the $_POST arrays, to make sure your tiles and IDs match. You do have that all working, but this seems fragile and not a good solution IMO. I'd suggest using the database IDs as your form input index values, rather than relying on the order they appear on the form, as I did in my answer to a previous question of yours.
You're already tracking errors with the associated DB ID. So when it comes to displaying the input values, you can just check if there is an error for that DB ID. If there is not, this input passed validation, and you can re-display the value from the current $_POST:
<form method="post" enctype="multipart/form-data">
<!-- ... your code ... -->
while ($row = $stmt->fetch()) {
$db_image_id = htmlspecialchars($row['image_id']);
$db_image_title = htmlspecialchars($row['image_title']);
// Start with the value in the DB, this will display first time
// through.
$value = $db_image_title;
// If there's been a POST, and there is no $error for this ID,
// we know it passed validation.
if (sizeof($_POST) && ! isset($error[$db_image_id])) {
$value = $_POST['image-title'][$db_image_id];
}
?>
<!-- ... your code ... -->
<div class="edit-zone">
<div class="form-row">
<!-- Now we can use whatever value we set above -->
<input value="<?php echo $value; ?>" type="text" name="image-title[]">
</div>
Side Note
There's no need to iterate over all your errors to find the one you want. If you have its ID, you can address it directly. Instead of this:
if(isset($error)) {
foreach($error as $element_id => $msg) {
// Note your code above does not show what $id is here,
// AFAICT it is the same as $row['image_id']
if($element_id == $id) {
echo "<p>** ERROR: {$msg}</p>";
}
}
}
You can simply do:
if (isset($error) && isset($error[$row['image_id']])) {
echo "<p>** ERROR: " . $error[$row['image_id']] . "</p>";
}

PHP: REQUEST_METHOD as basic error handling for html form

I am using input from a html form to output arrays containing the value inputted. I would like to carry out basic error handling that states what fields were left empty, a error message if no fields are inputted and then if all of the fields are inputed. However, my code isn't doing as I would like. It works elsewhere in my code but I can not figure out the difference.
EDIT:
I am getting "Notice: Undefined index: ageChoice" and "Notice: Undefined index: colourChoice"
HTML
<form action="profileFilter.php" method="POST">
<p>Age: <br>
<input type="radio" name="ageChoice" value="1">1
<input type="radio" name="ageChoice" value="2">2
<p>Colour: <br>
<input type="radio" name="colourChoice" value="Tabby">Tabby:
<input type="radio" name="colourChoice" value="Ginger">Ginger
<input type="submit" name="button">
</form>
ProfileArray.class.php
class ProfileArray {
Public function dataArray() {
$profileArray = array(
array( 'Name' => 'Toby',
'Age' => 3,
'Colour' => 'Ginger',
'Gender' => 'Male',
'Personality' => 'Gentle',
),
array( 'Name' => 'Cassie',
'Age' => 2,
'Colour' => 'Tabby',
'Gender' => 'Female',
'Personality' => 'Playful',
),
);
return $profileArray;
}
}
profileFilter.php
include ("ProfileArray.class.php");
$object = new ProfileArray();
$profileArray = $object->dataArray();
if($_SERVER["REQUEST_METHOD"] == "POST") {
$passedAgeChoice = $_POST['ageChoice'];
$passedcolourChoice = $_POST['colourChoice'];
$errorMessage = "";
if (!empty($passedAgeChoice)) {
echo $errorMessage = "WARNING: You have not entered an age to search for<br>";
}
if (!empty($passedColourChoice)) {
echo $errorMessage = "WARNING: You have not entered a colour to search for<br>";
}
if ($errorMessage == TRUE) {
echo '<h4 class="error">You have inputted nothing to search for</h4> Go back and try again';
}
//If there are no errors submit the form
if ($errorMessage == "") {
echo '<h4 class="error">Here are your full search results</h4> Back to Homepage<br>';
}
}
Use isset() and !isset() for everything here and you won't get any warnings. As I mentioned in comments, isset() is best used for radio buttons (and checkboxes).
empty() is mostly used for string inputs, lengths etc.
Sidenote: $passedcolourChoice has also been replaced with $passedColourChoice.
Variables are case-sensitive.
You can omit $passedAgeChoice = $_POST['ageChoice'];
$passedcolourChoice = $_POST['colourChoice']; and use the below:
if(isset($_POST['ageChoice'])){
$passedAgeChoice = $_POST['ageChoice'];
}
if(isset($_POST['colourChoice'])){
$passedColourChoice = $_POST['colourChoice'];
}
$errorMessage = "";
if (!isset($passedAgeChoice)) {
echo $errorMessage = "WARNING: You have not entered an age to search for<br>";
}
if (!isset($passedColourChoice)) {
echo $errorMessage = "WARNING: You have not entered a colour to search for<br>";
}
if ($errorMessage == TRUE) {
echo '<h4 class="error">You have inputted nothing to search for</h4> Go back and try again';
}
In profileFilter.php change two lines
$passedAgeChoice = (isset ($_POST['ageChoice'])) ?$_POST['ageChoice']:'';
$passedcolourChoice =(isset ($_POST['clourChoice'])) ? $_POST['colourChoice']:'';
Best practice: don't use global variables (e.g. $_POST, $_GET) directly. Try to validate them before use.

Return Single Value Multidimensional Array

I'm trying to build a custom zip code search to find a delivery fee, but I can't seem to get it right.
First up this is how I have my form set up on the front-end:
<form class="delivery-fee" role="search" method="get" action="">
<div class="form-group">
<label>Find Your Delivery Area:</label>
<input class="form-control" type="number" value="" name="zipcode" placeholder="Enter Zipcode" pattern="\d*" />
<input type="submit" value="See Delivery Minimum" />
</div>
</form>
I've got my data set up like this:
$delivery_areas = [
'Rancho Cucamonga' => [
'zipcodes' => [91701, 91729, 91730, 91737, 91739],
'fee' => 100
],
'Upland' => [
'zipcodes' => [91784, 91785, 91786],
'fee' => 150
]
];
This is how I'm looping through my data:
foreach ($delivery_areas as $key => $delivery_area) {
if (is_array($delivery_area)) {
if (in_array($_GET['zipcode'], $delivery_area['zipcodes'])) {
echo $delivery_area['fee'];
} else {
echo 'Error message';
}
}
}
The problem I'm having is if I do a search for say 91701 I do get the correct fee returned, but I'm also getting the error message with it. On the flip side I'll also get two error messages if nothing is found.
Any suggestions on how I could get the desired result?
You can adapt your code by using a var, e.g.:
$fee = -1;
foreach ($delivery_areas as $key => $delivery_area) {
if (is_array($delivery_area)) {
if (in_array($_GET['zipcode'], $delivery_area['zipcodes'])) {
$fee = $delivery_area['fee'];
break;
}
}
}
if($fee == -1)
echo 'Error message';
else
echo $fee;
Test:
$fee = 0;
foreach ($delivery_areas as $key => $delivery_area) {
if (is_array($delivery_area) && in_array($_GET['zipcode'], $delivery_area['zipcodes'])) {
$fee = $delivery_area['fee']; break;
}
}
echo $fee!=0 ? $fee : 'Error Message';

Display errors of a form in different places without setting a variable for every input field

I hope you understand my title.
Instead of displaying a list of all the errors with the submitted form, I would like to show them beside the fields in the form:
This is a short snippet of my code:
$errors = array();
if (empty($subject)) {
$errors[] = $lang['Empty Subject'];
}
if (empty($category)) {
$errors[] = $lang['Empty Category'];
}
if (strlen($ath) > 255) {
$errors[] = $lang['Too Long'];
}
if (!validate_string($str)) {
$errors[] = $lang['Invalid String'];
}
and the list goes on...
And for displaying:
if (!empty($errors)) {
foreach ($errors as $error)
$page['errors'] = array();
$page['errors'][] = '<li class="red"><span>'.$error.'</span></li>';
}
I know I could set a variable for every error but that does not seem like a smart idea like, this would work but it seems so stupid:
if (empty($subject)) {
$error_subject = $lang['Empty Subject'];
}
if (empty($category)) {
$error_category = $lang['Empty Category'];
}
and then beside every field:
Subject:
<input type="text" name="subject"><?php echo isset($error_subject) ? '<span style="color: red">'.$error_subject.'</span>' : '';
Category:
<input type="text" name="category"><?php echo isset($error_category) ? '<span style="color: red">'.$error_category.'</span>' : '';
However that does only show 1 error at a time anyways.
How do pros do this?
create the inputs dynamically
$inputs=array('subject','category'); //etc
foreach ($inputs as $input){
<input type="text" name="{$input}"><?php echo isset(${$error_.$input} ? '<span style="color: red">'.${$error_.$input}.'</span>' : '';
}

Replace isset for each $_POST using foreach

I've been trying to replace each isset for $_POST(s) using foreach.
This is the real code using isset for each $_POST :
<form method='post'>
<input type='text' name='name'> <br>
<input type='text' name='address'> <br>
<input type='submit' name='send'>
</form>
<?php
if (isset($_POST['name']) && isset($_POST['address']) && isset($_POST['send']))
{
echo "All elements have been submitted";
}
else
{
echo "You forget some elements, try checking name or address";
}
?>
is there a way I can replace 4 isset(s) above with single isset using for each?
I've made this and it goes wrong.
<form method='post'>
<input type='text' name='nama'> <br>
<input type='text' name='alamat'> <br>
<input type='submit' name='kirim'>
</form>
<?php
foreach($_POST as $value)
{
if (isset($value))
{
echo "All elements have been submitted";
}
else
{
echo "You forget some elements, try checking name or address";
}
}
?>
Need help guys, It's just wasting of time if I have to write isset one by one for each element I send via post / get. I've seen something like this before in visual basic, my friend made an foreach construct to validate all textboxes in a form, so he didn't need to create something like this anymore :
if textbox1.text="" && textbox.2.text="" and so on
EDIT: jbrahy just had a typo. His answer is good now.
I think jbrahy's approach is the right general idea... but I don't think it actually works.
I'd do this.
$requiredFields = ["nama","alamat","kirim"];
$allElementsSet = true;
foreach ($requiredFields as $requiredField)
{
if (!isset($_POST[$requiredField]))
{
$allElementsSet = false;
break;
}
}
if ($allElementsSet)
{
echo "All elements have been submitted";
} else {
echo "You forget some elements, try checking name or address";
}
$_POST will only have the variables that are passed in and there are HTML elements that might not be passed in by just submitting. It's probably best to create a $required_fields array and even better if you can get some field validation but that's not what you asked for here. You'll want to take the key and value of $_POST.
$required_fields = array("name" => FALSE, "alamat" => FALSE, "kirim" => FALSE);
foreach ($required_fields as $key => $value){
if (isset($_POST[$key])){
$required_fields[$key] = TRUE;
}
}
foreach ($required_fields as $key => $value){
if (!$required_fields[$key]){
echo "Missing value for " . $key;
}
}
if you are trying to figure out if every key that is passed in has a value then something like this would work also.
foreach ($_POST as $key => $value){
if ($value == ""){
echo "Value(s) are missing";
break;
}
}

Categories