I have the following code which checks the post for a "no" and if it exists prints and error or if not it redirects. It currently redirects everytime regardless of the fact the post array has 'NO' as a value.
if($_POST["minRequirementsForm"] == '1') {
foreach($_POST as $key => $value) {
if ($value == 'no') {
$error = 1;
} else {
header('Location: mysite.com/app-stage1.php');
}
}
//print_r($_POST);
}
Just use the header call after the loop, and check for $error:
$error = false;
if($_POST["minRequirementsForm"] == '1') {
foreach($_POST as $key => $value) {
if ($value == 'no') {
$error = true;
}
}
}
if (! $error) {
header('Location: mysite.com/app-stage1.php');
}
Notice that this uses the type boolean instead of an integer for the variable $error, which is more appropriate.
Don't use it as you did. Just write:
if (in_array('no', $_POST)) { $error = true; }
if (!$error) { header('Location: mysite.com/app-stage1.php'); }
It's better to use an already existing functions in php than reinvent the wheel.
Or use the following, which is more appropriate:
if (!array_search('no', $_POST)) { header('Location: mysite.com/app-stage1.php'); }
It redirects because of the subsequent values of non "no" strings. It echos the error, but due to next value, it redirects. Try exiting in the if(no) condition and you will see the error.
Related
I have this validation code:
public function validate() {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
foreach ($this->required as $field) {
if (empty($_POST[$field])) {
$this->error = $this->message['required'];
}
}
if (!ctype_alnum($_POST['text'])) {
$this->error = $this->message['text']['alphanum'];
}
if (strlen($_POST['text']) > 3) {
$this->error = $this->message['text']['length'];
}
}
return $this->error;
}
The problem is that even if the 'text' input is empty, it skips the if (empty($_POST[$field])) statement and goes to the if (!ctype_alnum($_POST['text'])) statement instead, displaying its error.
If I comment out the if (!ctype_alnum($_POST['text'])) statement, then it works properly and displays the "This field is required" error if the 'text' input is empty on submission.
It also works if I get the statement out of the foreach loop and use elseif, like this:
if (empty($_POST['text'])) {
$this->error = $this->message['required'];
} elseif (!ctype_alnum($_POST['text'])) {
$this->error = $this->message['text']['alphanum'];
}
But I'd like to use the loop and not use elseif, especially because I'll have a lot of required fields to validate.
I also tried:
Removing the if (empty($_POST[$field])) statement from the loop and adding it as the other ones: if (empty($_POST['text']));
Using $_POST['text'] == '' instead of empty();
Using strlen($_POST['text']) == 0 instead of empty();
Using preg_match() instead of ctype_alnum.
This shows when I use var_dump($_POST['text']) and submitting with an empty input:
/home/vagrant/code/test/index.php:13:string '' (length=0)
I can't figure out why and how to make it not skip the empty validation when using ctype_alnum() or preg_match().
The problem is you are overwriting $this->error if following conditions hold true, i.e. you won't get a $this->message['required'] back if the next condition, !ctype_alnum($_POST['text']) is true and overwrites $this->error with its message.
So you need to return $this->message inside each condition.
public function validate() {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
foreach ($this->required as $field) {
if (empty($_POST[$field])) {
$this->error = $this->message['required'];
return $this->error;
}
}
if (!empty($_POST['text']) {
if (!ctype_alnum($_POST['text'])) {
$this->error = $this->message['text']['alphanum'];
return $this->error;
}
if (strlen($_POST['text']) > 3) {
$this->error = $this->message['text']['length'];
return $this->error;
}
}
}
return $this->error;
}
I'd suggest just checking if the 'text' field is empty before checking any other criteria on it like this:
public function validate() {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
foreach ($this->required as $field) {
if (empty($_POST[$field])) {
$this->error = $this->message['required'];
}
}
if (!empty($_POST['text']) {
if (!ctype_alnum($_POST['text'])) {
$this->error = $this->message['text']['alphanum'];
}
if (strlen($_POST['text']) > 3) {
$this->error = $this->message['text']['length'];
}
}
}
return $this->error;
}
My code in PHP is pretty long and I want to make it shorter with creating one function with different values and than I would just write one line with function name instead of many lines of code, but it doesn't seem to work.
This is that repeating code:
if (!isset($_POST['ID_user']) || empty($_POST['ID_user'])) {
$_SESSION['ID_user_missing'] = "error";
header("location: index.php");
} else {
$ID_user = $_POST['ID_user'];
}
if (!isset($_POST['meta_name']) || empty($_POST['meta_name'])) {
$_SESSION['meta_name_missing'] = "error";
header("location: index.php");
} else {
$meta_name = $_POST['ID_user'];
}
if (!isset($_POST['meta_value']) || empty($_POST['meta_value'])) {
$_SESSION['meta_value_missing'] = "error";
header("location: index.php");
} else {
$meta_value = $_POST['meta_value'];
}
And this was the plan, instead of that code up ther, I would just have this down below:
function ifIssetPost($value) {
if (!isset($_POST[$value]) || empty($_POST[$value])) {
$_SESSION[$value.'_chybi'] = "error";
header("location: index.php");
} else {
$$value = $_POST[$value];
}
}
ifIssetPost('ID_user');
ifIssetPost('meta_name');
ifIssetPost('meta_value');
But it just doesn't work, when you try to echo for example variable $meta_name it shows that it's empty. Can you help me ? Thank you very much.
NOTE: when I doesn't that function and do it the long way, everything works just fine, but the problem comes when I use that function.
The variable is in the scope of function. That's why you cannot access to it outside the function. You could return the value:
function ifIssetPost($value) {
if (empty($_POST[$value])) { // Only empty is needed (as pointed out by #AbraCadaver)
$_SESSION[$value.'_chybi'] = "error";
header("location: index.php");
exit; // add exit to stop the execution of the script.
}
return $_POST[$value]; // return value
}
$ID_user = ifIssetPost('ID_user');
$meta_name = ifIssetPost('meta_name');
$meta_value = ifIssetPost('meta_value');
You can also follow your specification, using $$value:
function ifIssetPost($value) {
if (!isset($_POST[$value]) || empty($_POST[$value])) {
$_SESSION[$value.'_chybi'] = "error";
header("location: index.php");
} else {
return $_POST[$value];
}
}
$value = 'ID_user';
$$value = ifIssetPost($value);
echo $ID_user;
$value = 'meta_name';
$$value = ifIssetPost($value);
echo $meta_name;
You can use an array to iterate over the $_POST vars. If you want to declare a variable using a string or another variable containing an string, you need to use {}. like ${$value}
$postValues = ["ID_user", "meta_name", "meta_value"];
foreach ($postValues as $value) {
if (!isset($_POST[$value]) || empty($_POST[$value])) {
$_SESSION[$value."_missing"] = "error";
header("location: index.php");
} else {
${$value} = $_POST[$value];
}
}
This is the "contactprocess.php" file that the form posts to:
$result = "";
foreach ($_POST as $key => $val) {
if(($val != "") || (strpos($val,'http') == false) || (strpos($val,'seo') == false)){
$result = "clear" ;
}
}
if ($result == '') {
header("location: contact.php");
}
The code ignores the "header("location: contact.php");" line and continues on with the rest of the script. How else can this be written?
In your if-branch where you attempt to redirect, you need exit; to prevent the script from continuing execution:
if ($result == '')
{
header("location: contact.php");
exit;
}
I am trying this code as part of form processing:
<?php
if(isset($_POST['senderEmail']))
{
try
{
require '_php/_security/validation.php'; //SEE BELOW
$rules = array(
'senderEmail' => 'validEmail',
'emailTextbox' => 'validTextbox',
);
$validation = new Validation();
if ($validation->validate($_POST, $rules) == TRUE) {
require("_php/database/dbProcessing.php"); //Form Proccessing for database inclusion
}
else {
foreach($validation->emailErrors as $error){
$emailErrors[] = $error;
$_SESSION['$emailErrors'] = $emailErrors;
header('Location:indexmobile.php#emailErrors');
die('ABORT!');
}
}
}
catch (PDOException $e)
{
$error = 'Error adding elements to database: ' . $e->getMessage();
echo "Error: " . $error;
exit();
}
exit();
}
?>
The validation.php where I do my validation has this:
<?php
class Validation {
public $errors = array();
public function validate($data, $rules) {
$valid = TRUE;
foreach ($rules as $fieldname => $rule) {
$callbacks = explode('|', $rule);
foreach ($callbacks as $callback) {
$value = isset($data[$fieldname]) ? $data[$fieldname] : NULL;
if ($this->$callback($value, $fieldname) == FALSE) $valid = FALSE;
}
}
return $valid;
}
public function validEmail($value, $fieldname) {
$valid = !empty($value);
if ($valid == FALSE) {
$this->emailErrors[] = "The $fieldname is required";
return $valid;
} else {
$valid = filter_var($value, FILTER_VALIDATE_EMAIL);
if ($valid == FALSE) $this->emailErrors[] = "The $fieldname needs to be a valid email";
return $valid;
}
}
public function validTextbox($value, $fieldname) {
$valid = !empty($value);
if ($valid == FALSE) {
$this->emailErrors[] = "The $fieldname is required";
return $valid;
} else {
$whitelist = '/^[a-zA-Z0-9 ,\.\+\\n;:!_\-#]+$/';
$textarea = strip_tags($value);
$textarea = mysql_real_escape_string($textarea);
$valid = preg_match($whitelist, $textarea);
if ($valid == FALSE) $this->errors[] = "The $fieldname contains invalid characters";
return $valid;
}
}
}
Upon using this, Im have issues with the redirect (I think). It seems further that Im having errors in validation. My questions are thus:
Am I doing the header redirect correctly? I've read that " header() must be called before any actual output is sent,.." So is this the reason why this redirect is incorrect? how to make a redirect if i need to show/send something to the redirected page?
function validTextbox always ends up an error that the field is empty. Why so?
Is my entire process of form validation a good way of validating form fields (which i learned from watching an online tutorial)? What is a better way?
Is there something wrong with error reporting in this case?
Thank you for those who replies. I am new to PHP and trying my best to learn the language.
1 - There are several ways to pass on a message to the page you are redirecting to. One is through $_GET like this
$message="Some message for the next page.";
$message=urlencode($message);
header("Location:page.php?message=".$message);
then on page.php
if(!empty($_GET['message']))
{
$_GET['message'];
}
similarly you can also use the session (less secure)
$_SESSION['message']='some other message';
then on page.php
if (!empty($_SESSION['message']))
{
echo $_SESSION['message'];
unset($_SESSION['message']);
}
2 - I would have to see what you are passing to your validate function. You should do a var_dump of $_POST and add that to your question.
3 - It depends on your criteria. If you are just checking for emptiness its overkill. I don't know what text you need / consider valid, but a regex is a reasonable way of enforcing validation.
4 - See #2.
I'm trying to make an if statement with 2 conditions. One that checks if one variable is NOT present & does NOT matches the word "good2go" and the other that checks to make sure "body" variable is present. I'm trying to trip the error message here. Here is what I have and what I've tried, and none of it seems to work.
if (stripos($_POST['check'], 'good2go') == FALSE && $_POST['body']) {
$error = true; }
if (!$_POST['check'] == 'good2go' && $_POST['body']) {
$error = true; }
if (!stripos($_POST['check'], 'good2go') && $_POST['body']) {
$error = true; }
if ((!stripos($_POST['check'], 'good2go')) && $_POST['body']) {
$error = true; }
How do I get this to work?
here's the entire code of contact_us.php this has the validation code and the email code.
$error = false;
if (isset($_GET['action']) && ($_GET['action'] == 'send')) {
// Winnie the pooh check
//$t = tep_db_prepare_input($_POST['verify']);
if (!isset($_POST['check']) && !$_POST['check']=='good2go' && isset($_POST['body'])) {
$error = true;
} else { // Winnie the pooh Check
$name = tep_db_prepare_input($_POST['name']);
$email_address = tep_db_prepare_input($_POST['email']);
//IP recorder start
$ipaddress = $_SERVER["REMOTE_ADDR"];
$ip = "\n\nIP: " . $ipaddress;
$content = "\n\nName: ".$name."\n\nComments: ".$_POST['enquiry'];
$product = tep_db_prepare_input($_POST['product']);
if ($product) {
$product_text = "\n\nProduct Interest: ".$product; }
$content_ip = $content . $product_text. $ip;
$enquiry = tep_db_prepare_input($content_ip);
//IP recorder end
}
// BOF: Remove blank emails
// if (tep_validate_email($email_address)) {
// tep_mail(STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS, EMAIL_SUBJECT, $enquiry, $name, $email_address);
// tep_redirect(tep_href_link(FILENAME_CONTACT_US, 'action=success'));
// } else {
// $error = true;
// $messageStack->add('contact', ENTRY_EMAIL_ADDRESS_CHECK_ERROR);
if (! tep_validate_email($email_address)) {
$error = true;
$messageStack->add('contact', ENTRY_EMAIL_ADDRESS_CHECK_ERROR);
}
if ($enquiry == '') {
$error = true;
$messageStack->add('contact', ENTRY_EMAIL_CONTENT_CHECK_ERROR);
}
if ($error == false) {
tep_mail(STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS, EMAIL_SUBJECT, $enquiry, $name, $email_address);
tep_redirect(tep_href_link(FILENAME_CONTACT_US, 'action=success'));
// EOF: Remove blank emails
}
}
Solution to your updated problem:
if (!isset($_POST['check']) || !$_POST['check']=='good2go' || !isset($_POST['body'])) {
$error = true;
}
The reason for the pipes vs ampersands is that you want to throw an error if ANY of the fields has issue. Also, you want to check if body is NOT set vs IS set. Glad this worked out for you!
and the other that checks to make sure "body" variable is not present.
if(stripos($_POST['check'], "good2go") !== false && !isset($_POST['body'])){
//code here
}
According to PHP docs regarding the stripos function:
This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.
So you need to change the first line to:
// Doing stripos checks you MUST use === (not ==)
if (stripos($_POST['check'], 'good2go') !== FALSE && $_POST['body']) {
$error = true; }
And to check if there is no $_POST['body'] you can change the above to:
if (stripos($_POST['check'], 'good2go') !== FALSE && (!isset($_POST['body'])) {
-- Update --
According to your comment, you need $_POST['check'] to equal 'good2go', then you shouldn't be using stripos as it will check for the existence of good2go regardless if it's exactly equal, or part of a string; 'wow this hamburger is good2go'.
So I would change the conditional to:
if (((isset($_POST['body'])) && (strlen($_POST['body']) > 0)) && ((!isset($_POST['check'])) || ($_POST['check'] !== 'good2go'))) {
// Post body has a value and Post check DOES NOT equal good2go, someone is hax0rin!
}
You may want to read up on Cross-site request forgery as it seems right inline with what you are working on.
One that checks if one variable is present & matches the word "good2go"
isset($_POST['check']) AND $_POST['check'] == 'good2go'
and the other that checks to make sure "body" variable is not present.
!isset($_POST['body'])
so, just put them together
if (isset($_POST['check']) AND $_POST['check'] == 'good2go' AND !isset($_POST['body'])) {
$error = true;
}
try this:
if(!empty($_POST['check']) && $_POST['check']=='good2go' && empty($_POST['body'])) { $error=true; }
Consider using empty instead of isset if your $_POST['body'] can be present with an empty value.
No need for all those unneeded functions. What you are trying to achieve is:
if (isset($_POST['check']) && $_POST['check']=='good2go' && !isset($_POST['body']) {
// your code
}
However, As per the title of the question: Use a ternary statement. Syntax is as such
$var = <condition> ? <true> : <false>;