PHP - Cleaner, More Elegant Way to Validate Content of Forms - php

I am currently working on a Upload page, where users enter in values to forms then click submit. I am going to check to see if the forms have been submitted, and if submitted that they weren't empty. Here is my current code
function validPost()
{
if(isset($_POST["title"]) && //if a post has been submitted
isset($_POST["artist"]) &&
isset($_POST["genre"]) &&
isset($_POST["url"]) &&
isset($_POST["user"]) )
{
if (strlen($_POST['title']) <= 0) {
echo 'ERROR: Please enter a title. </ br>';
return false;
}
else if (strlen($_POST['artist']) <= 0) {
echo 'ERROR: Please enter an artist. </ br>';
return false;
}
else if (strlen($_POST['genre']) <= 0) {
echo 'ERROR: Please select a genre. </ br>';
return false;
}
else if (strlen($_POST['url']) <= 0) {
echo 'ERROR: Please enter a url. </ br>';
return false;
}
else if (strlen($_POST['user']) <= 0) {
echo 'ERROR: Please enter a username to submit the song (or make one up). </ br>';
return false;
}
else
return true;
}
else //if no post was submitted
{
return false;
}
}
Is there a more elegant way to check this? I plan on adding more checks in the future to the content submitted by these forms and I feel like this is a sloppy way to do it.
Thanks!

Assuming that all of the fields will be check for non-zero string lengths only:
$field_checks = array(
// 'fieldname' => 'errormessage'
'title' => 'Please enter a title',
'url' => 'Please enter a URL',
etc...
);
$errors = array();
foreach ($field_checks as $field => $errmsg) {
if (!isset($_POST[$field]) || ($_POST[$field] === '')) {
$errors[] = $errmsg;
}
}
if (count($errors) > 0) {
print_r($errors); // probably want a nicer error display than this
return false;
}

Check into jQuery and the validate plugin

Related

Variable always being set to 0 despite conditional blocks

The following block of code is an attempt to give some feedback for what a user may be inputting incorrectly and that side of it is working alright.
The part I am having trouble with is the else block. It seems to always set the $MaxNum variable to 0. If I remove the declaration from the else block it works fine, although obviously doesn't allow my code above to validate the input. I am probably overlooking something quite basic so any help would be great.
global $MaxNum, $TheNum;
if (isset($_POST['Submit'])) {
if (empty($_POST['maxnum'])){
$error[] = "<p>Please enter at least something!";
if($_POST['maxnum'] == 0){
$error[] = "<p>Zero doesn't count!";
}
}
if (!is_numeric($_POST['maxnum'])){
$error[] = "<p>You didn't enter a number!";
}
if (is_numeric($_POST['maxnum'])){
if(($_POST['maxnum'])>2147483647){
$error[] = "<p>2.14 Billion jellybeans is a little excessive, right?";
}
}
else{
$MaxNum = $_POST['maxnum'];
}
}
Some tips:
Try to use functions and early returns in your code, it makes your flow easier.
Try to use less nested if statements and use else if
An example with function and early returns:
global $MaxNum, $TheNum;
function handleFormSubmit(): string
{
if (!isset($_POST['Submit']) || !isset($_POST['maxnum'])) {
return "<p>Please enter at least something!</p>";
}
if(empty(['maxnum'])) {
return "<p>Please fill in a number</p>!";
}
if($_POST['maxnum'] == 0) {
return "<p>Zero doesn't count</p>!";
}
if (!is_numeric($_POST['maxnum'])) {
return "<p>You didn't enter a number!";
}
if (is_numeric($_POST['maxnum']) && $_POST['maxnum'] > 2147483647) {
return "<p>2.14 Billion jellybeans is a little excessive, right?";
}
$MaxNum = $_POST['maxnum'];
return '';
}
$errorMessage = handleFormSubmit();
Used #robbert van den Bogerd's tips to clean up my if statements and then implemented that. Still had the issue of the input being passed as there was nothing stopping that.
Created a new variable called $ValidInput and used it to hold a bool.
Through the checking I set it to False if it met any conditions.
Then at the end of the checks I attach the input to $MaxNum if $ValidInput remains True through the checking, if it made it to that point and was True it must meet our requirements.
global $MaxNum, $TheNum, $ValidInput;
$ValidInput = True;
if (isset($_POST['Submit'])) {
if (empty($_POST['maxnum'])) {
$error[] = "<p>Please enter at least something!</p>";
$ValidInput = False;
}
if(empty($_POST['maxnum']) && (!is_numeric($_POST['maxnum']))) {
$error[] = "<p>Please enter a number!</p>";
$ValidInput = False;
}
if($_POST['maxnum'] == 0) {
$error[] = "<p>Zero doesn't count!</p>";
$ValidInput = False;
}
if (!is_numeric($_POST['maxnum']) && (!empty($_POST['maxnum']))) {
$error[] = "<p>That's not a number!</p>";
$ValidInput = False;
}
if (is_numeric($_POST['maxnum']) && $_POST['maxnum'] > 2147483647) {
$error[] = "<p>Anything over 2.14 Billion jellybeans is a little excessive, right?";
$ValidInput = False;
}
if($ValidInput == True){
$MaxNum = $_POST['maxnum'];
}
}

How do I let an error-message only appear after the $_POSTS are sent?

On a blog I'm coding the admin can edit existing posts.
I want to let an error-message appear when the $_POST['title'] for e.g is empty(There will be displayed:"Your post should have a title"). I also do it if the subheading, content or category are empty.
The errors work just fine if one or some of them is/are empty. As soon I load the page to edit a post every error is displayed from the beginning.
How do I make them only appear when one or some $_POST's are empty after the <input type="submit .../> is clicked (they shouldn't be there when the site has loaded)?
This is the function in the PostsAdminController.php that checks the $_POST's and renders the site:
public function edit()
{
$error = "";
$id = $_GET['id'];
$entry = $this->postsRepository->find($id);
$categoryFId = $this->categoryRepository->getOneCatFromId($entry->c_Id);
$savedSuccess = false;
$abort = false;
if ($this->loginService->check()) {
if (!empty($_POST['title'])) {
$entry->title = $_POST['title'];
} else {
$error .= "Your post should have a title.";
$abort = true;
}
if (!empty($_POST['subheading'])) {
$entry->subheading = $_POST['subheading'];
} else {
$error .= "A good subheading is nothing you should just leave out.";
$abort = true;
}
if (!empty($_POST['content'])) {
$entry->content = $_POST['content'];
} else {
$error .= "Your post should have content, you know, it wouldn't be a 'post' then.";
$abort = true;
}
if (!empty($_POST['category'])) {
$entry->c_Id = $_POST['category'];
}
if ($abort == false){
$this->postsRepository->update($entry);
$savedSuccess = true;
}
} else {
$error = "You have no permission to do this, how the hell did you get here?";
}
$this->render("post/admin/edit", [
'entry' => $entry,
'error' => $error,
'savedSuccess' => $savedSuccess,
'categoryFId' => $categoryFId
]);
}
I really hope someone can help me with this, I don't know what I could to to let them only disappear when the POSTS have already been send..
You have to check if there was a POST action use:
if ($_SERVER['REQUEST_METHOD'] == 'POST')
in your case
...
if ($this->loginService->check()) {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!empty($_POST['title'])) {
...
}
}
}

Header Redirect after form Validation in PHP

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 Have A Registration Form That Is Kicking Back Custom Made Errors Before Submission

I'm working on a registration for my classifieds (via a tutorial) but I'm having problems. For some reason, just visiting this page: http://classifieds.your-adrenaline-fix.com/register.php
will generate the 2 custom errors you'll see in a red box above the registration form BUT the form hasn't even been submitted yet so I don't know why this is happening. If anyone could shed some light on this I'd be most appreciative and I thank you all in advance!!
(I've been staring at it for hours)
Here's the code that validates and submits the form data;
<?php
if(empty($_POST) === false) {
$VisitorsFirstName = $_POST['First_Name'];
$VisitorsLastName = $_POST['Last_Name'];
$VisitorsEmail = $_POST['E_mail'];
$VisitorsPassword = $_POST['Pass'];
$RequiredFlds = array('First_Name', 'Last_Name', 'E_mail', 'Pass', 'PassAgain');
foreach($_POST as $key=>$value) {
if(empty($value) && in_array($key, $RequiredFlds) === true) {
$Err[] = 'All Fields Are Required';
break 1;
}
}
if(empty($Err) === true) {
if(email_exists($VisitorsEmail) === true) {
$Err[] = 'The Email Address \''. $VisitorsEmail. '\' Is Already In Use.';
}
if(strlen($VisitorsPassword) < 4) {
$Err[] = 'Please Select A Password of At Least 4 Characters.';
}
if($_POST['Pass'] !== $_POST['PassAgain']) {
$Err[] = 'Passwords Do Not Match.';
}
if(filter_var($VisitorsEmail, FILTER_VALIDATE_EMAIL) === false) {
$Err[] = 'A Valid Email Address is Required';
}
}
}
if(isset($_GET['success']) && empty($_GET['success'])) {
echo 'You Have Now Been Registered and Can Proceed to Creating Your First Ad<br>(Use the Email and Password That You Registered With to Login)';
} else {
if(empty($_POST) === false && empty($Err) === true) {
$register_data = array (
'VisitorsFirstName' => $_POST['First_Name'],
'VisitorsLastName' => $_POST['Last_Name'],
'VisitorsPassword' => $_POST['Pass'],
'VisitorsEmail' => $_POST['E_mail'],
'Notify' => $_POST['Notify']
);
register_func($register_data);
header('Location: register.php?success');
exit();
} else if(empty($Err) === false) {
echo output_error($Err);
}
}
?>
Upon putting just the code you provided on my own server by itself, it works as designed. It isn't running the top block of code, because the $_POST variable is empty. Try outputting the contents of $_POST at the top of the file so you can figure out why it isn't empty.
print_r($_POST);
Try this:
if(!empty($_POST['First_Name']) && !empty($_POST['Last_Name']) && !empty($_POST['E_mail']) && !empty($_POST['Pass'])){
....
}
OR
try isset($_POST['First_Name'])......
This works fine for me!
You could instead check if the submit button was pressed. Like this:
if (isset($_POST['submit']) {
// get the post values
}
This way you could eliminate the script launching before the form was actually submitted. Right now it seems to run as soon as I visit the page.

email validation in php

I'm trying to validate my username as an email address, however PHP isn't letting me do this! what's wrong here?
//This checks if all the fields are filled or not
if (!empty($_POST['username']) ||
!empty($_POST['password']) ||
!empty($_POST['repassword']) ||
!empty($_POST['user_firstname']) ||
!empty($_POST['user_lastname']) ){
header('Location: register.php?msg=You didn\'t complete all of the required fields');
}
if (filter_var($_POST['username'], FILTER_VALIDATE_EMAIL) === false){
$errors[] = 'The email address you entered is not valid';
}
here is the form i used in register.php
<form action="createuser.php" method="post" name="registration_form" id="registration_form">
<label>Email</label>
<input name="username" type="text" id="username" size="50" maxlength="50" /><br />
Typo?
header('Location: register.php?msg=You didn't complete all of the required fields');
^---unescaped embedded quote
Your empty logic is also faulty. You're checking if any fields are NOT empty (e.g. filled out) and then complaining that they're not filled out. remove the ! to invert the logic.
if (empty(...) || empty(...) || etc...)
instead of this use regular expression for validating your email address
function check_email_address($email) {
// First, we check that there's one # symbol,
// and that the lengths are right.
if (!preg_match("^[^#]{1,64}#[^#]{1,255}$", $email)) {
// Email invalid because wrong number of characters
// in one section or wrong number of # symbols.
return false;
}
// Split it into sections to make life easier
$email_array = explode("#", $email);
$local_array = explode(".", $email_array[0]);
for ($i = 0; $i < sizeof($local_array); $i++) {
if
(!preg_match("^(([A-Za-z0-9!#$%&'*+/=?^_`{|}~-][A-Za-z0-9!#$%&
↪'*+/=?^_`{|}~\.-]{0,63})|(\"[^(\\|\")]{0,62}\"))$",
$local_array[$i])) {
return false;
}
}
// Check if domain is IP. If not,
// it should be valid domain name
if (!preg_match("^\[?[0-9\.]+\]?$", $email_array[1])) {
$domain_array = explode(".", $email_array[1]);
if (sizeof($domain_array) < 2) {
return false; // Not enough parts to domain
}
for ($i = 0; $i < sizeof($domain_array); $i++) {
if
(!preg_match("^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|
↪([A-Za-z0-9]+))$",
$domain_array[$i])) {
return false;
}
}
}
return true;
}
and then check if it return true redirect it to location if not then simply throw an error
You would not get to Validate the email because your if statement is wrong .. it is checking if any of the post is not empty.
Replace it with
if (empty($_POST['username']) || empty($_POST['password']) || empty($_POST['repassword']) || empty($_POST['user_firstname']) || empty($_POST['user_lastname'])) {
For starters, look at the syntax highlighting for why you're getting parse errors.
header('Location: register.php?msg=You didn't complete all of the required fields');
needs to become:
header('Location: register.php?msg=You didn\'t complete all of the required fields');
How about you use javascript window.location? Sometimes header function is sensitive.And also put a submit button in your form since by default fields are empty when loaded.
if(isset($_POST['your_submit_button_name'])){
if (empty($_POST['username']) ||
empty($_POST['password']) ||
empty($_POST['repassword']) ||
empty($_POST['user_firstname']) ||
empty($_POST['user_lastname']) ){
?>
<script>
window.location = 'register.php?msg=You didn\'t complete all of the required fields';
</script>
<?php
}
if (filter_var($_POST['username'], FILTER_VALIDATE_EMAIL) === false){
$errors[] = 'The email address you entered is not valid';
}
}
NOTE: I remove "!" before your empty function since youre trapping the fields that are empty.
Try to use this solution:
$FormData = $_POST;
if(isset($FormData['button_name'])){
$Errors = array();
foreach ($$FormData as $key => $value) {
if(empty($value)) $Errors[] = 'Some message';
if($key = 'username'){
if(filter_var($value, FILTER_VALIDATE_EMAIL){
$Errors[] = 'The email address you entered is not valid';
}
}
}
if(empty($Errors)){
// #todo Do some action
} else {
header('Location: register.php?msg=You didn\'t complete all of the required fields');
}
}
function check_email($check) {
$expression = "/^[a-zA-Z0-9._-]+#[a-zA-Z0-9._-]+\.([a-zA-Z]{2,4})$/";
if (preg_match($expression, $check)) {
return true;
} else {
return false;
}
}
Now use this method as :
if(!check_email($_REQUEST['ContactEmail'])){
$register_error .="Enter the correct email address!<br />";
$reg_error=1;
}

Categories