Form inserting empty data to database - php

Whenever I submit the form with empty input, it sends the empty input to my database. The form was working fine until after I used the htmlentities() for its functionality.
I used the gettype() function to return what's in the inserted variable and it returns "string", but when I checked the code from the browser, I could not see anything in the table.
This is the code snippet and the form processing code
<?php
$errors = [];
$missing = [];
if(isset($_POST['sendFirm']) ){
$expected = array('firmName','country','state','email','phoneNumber');
$required = array('firmName','country','state','phoneNumber');
<?php
foreach ($_POST as $key => $value) {
if(is_array($value)){
$value = $value;
}else{
$value = trim($value);
}
if(empty($value) && in_array($key, $required)){
$missing[] = $key;
$$key = '';
}elseif(in_array($key, $expected)){
$$key = "$value";
}
}
?>
}
?>
<?php
if($errors || $missing){
?>
<p>Please fix the following items</p>
<?php } ?>
<form method="post" action="<?php $_SERVER['PHP_SELF'] ?>">
<div class="form-group">
<label>Compnay Name
<?php if($missing && in_array('firmName', $missing)) { ?>
<span class="text-danger">Please enter firm name</span>
<?php } ?>
</label>
<input class="form-control" type="text" name="firmName" id="firmName" placeholder="Company Name"
<?php
if($errors || $missing){
print 'value="' . htmlentities($firmName) . '"';
}
>
<button class="btn btn-primary" type="submit"
name="sendFirm">Submit</button>
</form>
?>
>
<?php
if(isset($_POST['sendFirm'])){
try {
$connectToFirms = new
PDO('mysql:host=localhost;dbname=firms','root','2332');
$connectToFirms->setAttribute(PDO::ATTR_ERRMODE,
PDO::ERRMODE_EXCEPTION);
$prepInsertion = $connectToFirms->prepare('INSERT INTO contractors
VALUES (null,?,?,?,?,?)');
$prepInsertion->execute(array($firmName, $country, $state, $email,
$phoneNumber));
}catch (PDOException $e) {
print "An error occure: " . $e->getMessage();
}
}
?>
The form is expected to insert inputs into the database only if the input is not empty and is also in the $expected[];

Don't insert data
I would stop the whole data insertion, if the expected input is not given. I would also send the input data one by one to PHP, so you have a better overview over your code. Good overview = less errors ;)
Try it this way:
<?php
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$firmname = htmlentities($_POST["firmName"], ENT_QUOTES);
$country = htmlentities($_POST["country"], ENT_QUOTES);
$state = htmlentities($_POST["state"], ENT_QUOTES);
$pn = htmlentities($_POST["phoneNumber"], ENT_QUOTES);
// LET'S START THE VALIDATION
// if the required fields are not empty, insert data
if (!empty($firmname) && !empty($country) && !empty(state) && !empty($pn)) {
// insert data
} else { // else stop insertion and return error message
// return error message
}
} else {
// redirect...
}
I hope, i understood your question correctly and could help.

Related

Checking post data of a checkbox

I have a checkbox that I'm looking to update a contacts details with. At the moment it's not updating the contact in Send in Blue... I don't think that's the problem though.
There's 3 issues I'm not sure I'm doing correctly:
Checking if the data has been sent.
Checking the field data that already uses square brackets.
Checking to see if the checkbox is checked or not.
Here's my php:
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
global $SendInBlue;
if(isset($_POST['data[newsletter_sub]']) == "on") {
$data_in['ONETIME_NEWSLETTER'] = true;
$data_in['PROMOS'] = true;
$data_in['SUB_NEWSLETTER'] = true;
} else {
$data_in['ONETIME_NEWSLETTER'] = false;
$data_in['PROMOS'] = false;
$data_in['SUB_NEWSLETTER'] = false;
}
// Update SiB contact
$data = array(
'attributes'=> $data_in
);
try {
$updateContact = new \SendinBlue\Client\Model\UpdateContact($data);
$result = $SendInBlue->updateContact($email, $updateContact);
return true;
} catch (Exception $e) {
}
}
?>
Here's some of the form with one checkbox:
<form method="POST" class="" id="communication_preferences" action="/event" name="communication_preferences">
<input type="checkbox" name="data[newsletter_sub]" id="newsletter_sub" <?php if($newsletter_sub == 'yes'){ echo 'checked';}?>>
<button class="button button--pink button--uppercase text--three js-profile-item-submit landmark ">
Save Changes
</button>
</form>
The page just reloads when you submit the form.
The problem with checkboxes is that they do not appear in the $_POST when not checked.
Your receiving script can simple do this:
$bMyCheckOn = isset($_POST["someCheckBoxName"]); // true/false
Please make sure that if (!empty($_POST['newsletter_sub'])) { matches your input.
Here, i rewrote your entire script:
<?php
if (!empty($_POST['submit'])) {
global $SendInBlue;
$data_in = [];
foreach(['ONETIME_NEWSLETTER', 'PROMOS', 'SUB_NEWSLETTER'] as $data) {
if (!empty($_POST['newsletter_sub'])) { //Checkbox set?
$data_in[$data] = true;
} else {
$data_in[$data] = false;
}
}
$data = ['attributes' => $data_in];
$attempt = new \SendinBlue\Client\Model\UpdateContact($data);
$result = $SendInBlue->updateContact($email, $attempt) ? true : false;
print_r($result);
} else {
echo 'Form not submitted.';
}
?>
<form method="POST" id="communication_preferences" action="">
<input type="checkbox" name="newsletter_sub" id="newsletter_sub" <?=($newsletter_sub == 'yes' ? 'checked' : '')?>>
<button type="submit" class="button button--pink button--uppercase text--three js-profile-item-submit landmark" name="submit" value="submit">
Save changes
</button>
</form>

Send radio selection to function along with textbox

I've got some code working that takes the text from my input box and moves it across to a function. I'm now trying to change it so I add another form element, a radio button and I want to access the choice within my functions.php file.
This is my current code which works for the post name, but what if I want to also grab the colours boxes that was selected too?
main.php
<?php
if (isset($_POST['submit'])) {
$data = $_POST['name']; // the data from the form input.
}
?>
...
<form action="/" method="post">
<input type="text" name="name" placeholder="Acme Corp"/>
<input name="colour" type="radio" value="red">Red<br>
<input name="colour" type="radio" value="blue">Blue<br>
<input name="colour" type="radio" value="green">Green<br>
<input type="submit" name="submit" value="Submit">
</form>
<img src="pngfile.php?data=<?php print urlencode($data);?>"
alt="png php file">
I guess I confused because currently it is calling this:
pngfile.php
<?php
require_once 'functions.php';
$inputData = urldecode($_GET['data']);
process($inputData);
exit;
?>
Which calls functions.php
<?php
function process($inputdata)
{
...
EDIT: What I have tried:
main.php [Change]
$data = $_POST['name'] && $_POST['colour']
But I'm not really sure how to progress.
Never trust user input. Sanitize and validate your inputs before using them.
This can be arranged better, but the basics are still true.
PHP Manual: filter_input_array()
PHP Manual: filter_var_array()
Small Function Library
function sanitizeArray($filterRules)
{
return filter_input_array(INPUT_POST, $filterRules, true)
}
function validateArray($filteredData, $validationRules)
{
return filter_var_array($filteredData, $validationRules, true);
}
function checkFilterResults(array $testArray, array &$errors)
{
if (!in_array(false, $testArray, true) || !in_array(null, $testArray, true)) {
foreach($testArray as $key => $value)
{
$errors[$key] = '';
}
return true;
}
if ($testArray['name'] !== true) { //You can make a function and do various test.
$errors['name'] = 'That is not a valid name.';
}
if ($testArray['clour'] !== true) { //You can make a function and do many test.
$errors['colour'] = 'That is not a valid colour.';
}
return false;
}
function processUserInput(array &$filteredData, array $filterRulesArray, array $validationRulesArray, array &$cleanData, array &$errors)
{
$filteredInput = null;
$tempData = sanitizeArray($filterRulesArray);
if (!$checkFilterResults($tempData, $errors)){
throw new UnexpectedValueException("An input value was unable to be sanitized.");
//Consider forcing the page to redraw.
}
$filteredData = $tempData;
$validatedData = validateArray($filteredData, $validationRulesArray);
if (!$checkFilterResults($validatedData, $errors)){
return false;
}
$errors['form'] = '';
$cleanData = $validatedData;
return true;
}
function htmlEscapeArray(array &$filteredData)
{
foreach($filteredData as $key => &$value)
{
$value = htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8', false);
}
return;
}
Basic Main Line
try {
$filterRulesArray = []; //You define this.
$filteredData = []; //A temporary array.
$validationRulesArray = []; //You define this.
$validatedData = null; //Another temporary array.
$results = null; //Input processing results: true or false.
$cleanData = null; //Filtered and validated input array.
$errors = []; //Any errors that have accumulated.
if (isset($_POST, $_POST['submit'], $_POST['colour']) && !empty($_POST)) {
$results = processUserInput($filteredData, $filterRulesArray, $validationRulesArray, $cleanData, $errors);
} else {
$errors['form'] = "You must fill out the form."
}
if ($results === true) {
$name = $cleanData['name']; //You can do what you want.
$colour = $cleanData['colour']; //You can do what you want.
//header("Location: http://url.com/registration/thankYou/")
//exit;
}
//Prepare user input for re-display in browser
htmlEscapeArray($filteredData);
} catch (Exception $e) {
header("Location: http://url.com/samePage/"); //Force a page reload.
}
Let the form redraw if input processing fails.
Use the $errors array to display error messages.
Use the $filteredData array to make the form sticky.
<html>
<head>
<title>Your Webpage</title>
</head>
<body>
<h1>My Form</h1>
<form action="/" method="post">
<!-- Make spots for error messages -->
<input type="text" name="name" placeholder="Acme Corp" value="PUT PHP HERE"/>
<!-- No time to display sticky radios! :-) -->
<input name="colour" type="radio" checked="checked" value="red">Red<br>
<input name="colour" type="radio" value="blue">Blue<br>
<input name="colour" type="radio" value="green">Green<br>
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>
Tip:
It may be better to submit numbers for radios, as opposed to longer string values like (red, green, blue). Numbers are easier to sanitize and validate. Naturally, then you must translate the input number into its corresponding string. You would do that after validation has finished, but before using the values. Good luck!
you can access this using array like this.
$data[] = $_POST['name'];
$data[] =$_POST['colour'];
Or combine both variable
$data = $_POST['name'].'&'.$_POST['colour'];
Use Array in php for this process as follows:
if (isset($_POST['submit'])) {
$array_val = array(
"name"=> $_POST['name'],
"color"=> $_POST['color']
);
}

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>' : '';
}

Passing information using post method without session variables

I will admit immediately that this is homework. I am only here as a last resort after I cannot find a suitable answer elsewhere. My assignment is having me pass information between posts without using a session variable or cookies in php. Essentially as the user continues to guess a hidden variable carries over all the past guesses up to that point. I am trying to build a string variable that holds them all and then assign it to the post variable but I cannot get anything to read off of the guessCounter variable i either get an undefined index error at the line of code that should be adding to my string variable or im just not getting anything passed over at all. here is my code any help would be greatly appreciated as I have been at this for awhile now.
<?php
if(isset($_POST['playerGuess'])) {
echo "<pre>"; print_r($_POST) ; echo "</pre>";
}
?>
<?php
$wordChoices = array("grape", "apple", "orange", "banana", "plum", "grapefruit");
$textToPlayer = "<font color = 'red'>It's time to play the guessing game!(1)</font>";
$theRightAnswer= array_rand($wordChoices, 1);
$passItOn = " ";
$_POST['guessCounter']=$passItOn;
$guessTestTracker = $_POST['guessCounter'];
$_POST['theAnswer'] = $theRightAnswer;
if(isset($_POST['playerGuess'])) {
$passItOn = $_POST['playerGuess'];
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
$guessTestTracker = $_GET['guessCounter'];
$theRightAnswer = $_GET['theAnswer'];
}
else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if(isset($_POST['playerGuess'])) {
if(empty($_POST['playerGuess'])) {
$textToPlayer = "<font color = 'red'>Come on, enter something(2)</font>";
}
else if(in_array($_POST['playerGuess'],$wordChoices)==false) {
$textToPlayer = "<font color = 'red'>Hey, that's not even a valid guess. Try again (5)</font>";
$passItOn = $_POST['guessCounter'].$passItOn;
}
if(in_array($_POST['playerGuess'],$wordChoices)&&$_POST['playerGuess']!=$wordChoices[$theRightAnswer]) {
$textToPlayer = "<font color = 'red'>Sorry ".$_POST['playerGuess']." is wrong. Try again(4)</font>";
$passItOn = $_POST['guessCounter'].$passItOn;
}
if($_POST['playerGuess']==$wordChoices[$theRightAnswer]) {
$textToPlayer = "<font color = 'red'>You guessed ".$_POST['playerGuess']." and that's CORRECT!!!(3)</font>";
$passItOn = $_POST['guessCounter'].$passItOn;
}
}
}
}
$_POST['guessCounter'] = $passItOn;
$theRightAnswer=$_POST['theAnswer'];
for($i=0;$i<count($wordChoices);$i++){
if($i==$theRightAnswer) {
echo "<font color = 'green'>$wordChoices[$i]</font>";
}
else {
echo $wordChoices[$i];
}
if($i != count($wordChoices) - 1) {
echo " | ";
}
}
?>
<h1>Word Guess</h1>
Refresh this page
<h3>Guess the word I'm thinking</h3>
<form action ="<?php echo $_SERVER['PHP_SELF']; ?>" method = "post">
<input type = "text" name = "playerGuess" size = 20>
<input type = "hidden" name = "guessCounter" value = "<?php echo $guessTestTracker; ?>">
<input type = "hidden" name = "theAnswer" value = "<?php echo $theRightAnswer; ?>">
<input type = "submit" value="GUESS" name = "submitButton">
</form>
<?php
echo $textToPlayer;
echo $theRightAnswer;
echo $guessTestTracker;
?>
This is a minimal functional example of what you need to do. There are still a couple of minor bugs (like duplicate entries in the history), but I've left these as an exercise for you. Treat this as a starting point and build up what you need from it.
I've added comments to explain what's happening, so hopefully it is clear to you.
$answer = null;
$history = [];
$choices = ['apple', 'grape', 'banana'];
$message = '';
// check if a guess has been made.
if (!empty($_POST) && !empty($_POST['guess'])) {
// check if previous guesses have been made.
if (!empty($_POST['history'])) {
$history = explode(',', $_POST['history']);
}
// check guess.
if (!empty($_POST['answer']) && !empty($_POST['guess'])) {
// check guess and answer are both valid.
if (in_array($_POST['guess'], $choices) && isset($choices[$_POST['answer']])) {
if ($_POST['guess'] == $choices[$_POST['answer']]) {
// correct; clear history.
$history = [];
$message = 'correct!';
} else {
// incorrect; add to history and set previous answer to current.
$history[] = $_POST['guess'];
$answer = $_POST['answer'];
$message = 'incorrect!';
}
} else {
// invalid choice or answer value.
}
}
}
if (empty($answer)) {
// no answer set yet (new page load or correct guess); create new answer.
$answer = rand(0, count($choices) - 1);
}
?>
<p>Guess the word I'm thinking:</p>
<p><?php echo implode(' | ', $choices) ?></p>
<form method="POST">
<input type="hidden" name="answer" value="<?php echo $answer; ?>">
<input type="hidden" name="history" value="<?php echo implode(',', $history); ?>">
<input type="text" name="guess">
<input type="submit" name="submit" value="Guess">
</form>
<p><?php echo $message; ?></p>

Creating an error in an else

Basically I want to add one last piece of validation, if nothing is selected on the items page then an error appears or the user is returned to another page.
When submit is selected the form action sends it to the confirm page and the below is executed which displays the items selected if there is 1 or more entered if ($partno == $varname & $qty > 0) but I dont no what to put in the else part to return an error or take the user back to the previous page.
<?php
$visitor = $_POST['visitor'];
echo "<p>" . 'Hello ' . "<b>" . $visitor . "</b> " . 'please confirm your purchase(s) below.' . "</p>";
if (!($data = file('items.txt'))) {
echo 'ERROR: Failed to open file! </body></html>';
exit;
}
$total = 0;
foreach ($_POST as $varname => $varvalue) {
$qty = $varvalue;
foreach ($data as $thedata) {
list($partno, $name, $description, $price, $image) = explode('|', $thedata);
if ($partno == $varname & $qty > 0) {
echo "<tr><td><img src='$image' width='50' height='50' alt='image'</td>
<td>$partno<input type='hidden' name='$partno' value=$partno></td><td>$name</td><td>£$price</td>
<td> $qty</td><td><input type='hidden' name='visitor' value=$visitor></td>
<td><input type='hidden' name='qty' value=$qty></td></tr>";
$total = $total + $price * $qty;
} else {
}
}
}
?>
You'd have something like this:
$errors = array();
foreach(...) {
if ($partno == $varname & $qty > 0) {
... code for "ok" stuff
} else {
$errors[] = "$partno is incorrect";
}
}
if (count($errors) > 0) {
die("Errors: " . implode($errors));
}
... proceed to "success" code ...
Basically, for every test that fails, you record a message. Once the loop exits, if there's any error messages, you display them and abort processing. If there's no errors, you proceed onwards with the rest of the code.
Why not use a try catch block?
try {
if (isset($_POST)) {
if (!$email) {
throw new Exception('email is not valid', 100);
}
// everything is good process the request
}
throw new Exception('Error!', 200);
} catch (Exception $e) {
if ($e->getCode == 200) {
// redirect
} else {
// do something else
}
}
throw an Exception in your If statement, then put your data in try/catch block, so it will catch an exception if error occured
Consider the following approach: both the form and the php code to do something with the form data are on the same page. If the form was posted, you'll first check if the form was ok, after that you'll do something with the submitted data. If the form was not valid, display an error message.
The advantage is: no die() in the middle of your code, no strange redirects, everything in one script.
// simplified code in example.php
<?php
// in this variable we'll save success/error messages to print it
$msg = "";
// run this php code if the form was submitted
if(isset($_POST['submit'])) {
// is the form valid?
if (strlen($_POST['username']) == 0) {
$msg = "Please enter a username";
}
else {
// all validation tests are passed, give the user a nice feedback
// do something with the data, e.g. save it to the db
$msg = "Your data was saved. Have a great day";
}
}
?>
<div class="msg"><?php print $msg; ?></div>
<form method="post">
<input type="text" name="username">
<input type="submit" name="submit" value="Submit">
</form>

Categories