Basically I have several big forms (lot of fields submitted) that need to be processed, which are very similar but may differ by one or two fields. Firstly all fields get escaped and assigned to a variable of their original name (thus $_POST['f_name'] will be $f_name).
Then I need to validate the data, things like certain obligatory fields must be present, certain fields much match (confirming password/email), certain fields must pass regex check. I do this via a long if/else statement, where each failure has it's own error message.
Now of course I would like to avoid this repetition of the clumsy code, and replace it with some looping function, which will be easier to edit and maintain.
However this poses a bit of a problem, especially performing the checks and assigning individual error messages.
I would be keen to hear suggestions as how would you approach developing such validation/error reporting function.
Here is a short version of what the code looks like:
$name = mysqli_real_escape_string($mysqli, $_POST['name']);
$password = mysqli_real_escape_string($mysqli, $_POST['password']);
$password_re = mysqli_real_escape_string($mysqli, $_POST['password_re']);
if ($name == '') :
$data = "Please enter name";
elseif ($password != $password_re) :
$data = "Passwords don't match";
endif;
First off I would make a function to clean your post array.
$clean_post = sanitize($_POST);
function sanitize($input) {
if (is_array($input)) {
foreach($input as $var=>$val) {
$output[$var] = sanitize($val);
}
}
else {
if (get_magic_quotes_gpc()) {
$input = stripslashes($input);
}
$input = cleanInput($input);
$output = mysql_real_escape_string($input);
}
return $output;
}
Next I would add divs with the same name as the field and set error variable within the $data array and remove the ifs in between them, personally I hate being spoon fed my form errors.
if ($name == '')
$data['name'] = "Please enter name";
if ($password != $password_re)
$data['password] = "Passwords don't match";
Finally, I would set the content of the divs to the $data array value.
<div><?=$data[name];?></div>
<input type="text" name="name" value="<?=$clean_post[name];?>">
<div><?=$data[password];?></div>
<input type="password" name="password" value="<?=$clean_post[password];?>">
<input type="password" name="password_re" value="<?=$clean_post[password_re];?>">
Hope this helps
I'm not sure that there's one cut-and-dried approach to this problem. Here's how my company has addressed this problem:
1) Front side validation. Yes, can be bypassed. However, if you're only using it as the first line of defense it's a great solution (and acceptable to some of my biggest clients including an international banking group) I love the simplicity of Cedric Dugas' inline validation script because it's basically just a few extra characters per field. Another HUGE benefit to the inline validation--it allows us to use one centralized alert area for server-side validation errors along with a simple alert trigger via css on individual elements, while the majority are caught inline and alerted which is FAR more user friendly.
2) A class that deals with "stuff" We refer to it as the "garbage in, garbage out" It takes an array of post data, sets fields based on element names, and deals accordingly. This includes data sanitizing, validations, etc. The problem with validations is that unless you have generic types data to validate, you can get into a lot of specifics which can really gum up code in a hurry. Also, this can make you actually have to do MORE work on the front end because your field names have to line up accordingly. In our case, we deal with external webform responses from clients a lot who don't necessarily appreciate the need for standardized naming of fields, and that can get to be a headache.
3) "Chunking" sections. On huge form scenarios, we've resorted to "chunking" submits in phases via Ajax to minimize the damage to the server done in one big submit. So, user updates profile information, submit happens. User does background info section, update happens...etc. It's not right for all situations, but is some it can work well...and it allows progressive validation as you move from start to finish. I certainly wouldn't ever recommend this approach for each individual question, though.
4) "Forced Sanitation" Sounds evil, huh? In cases such as zip codes, addresses, etc you can simply fix information for the client. Rather than barking about a missing Zip Code, you can get it automatically, correct 100% of the time. That's the beauty of Google and the USPS--they're free and smarter than the average user.
I'd say it's better to do this on the client side using a javascript form validator, before anything gets submitted. Do a search for javascript form validation. It'll save you a page load and force your users to correct errors before even submitting. Here's a simple example of one way, taken from the first google hit for "javascript form validation":
<form name="myForm" action="demo_form.asp" onsubmit="return validateForm()" method="post">
First name: <input type="text" name="fname">
<input type="submit" value="Submit">
</form>
<script language="javascript">
function validateForm()
{
var x=document.forms["myForm"]["fname"].value
if (x==null || x=="")
{
alert("First name must be filled out");
return false;
}
}
</script>
Related
I'm working on creating a search form where clients will be able to enter their vin number to a vehicle and the other related columns in that row will be displayed. I've gotten this process working to some extent by using a 'where like' operator in my select statement, however, I want clients to have to enter at least five correct digits before any rows are returned.
In my code's current state, just entering a single digit will return all rows with that digit. Additionally, entering nothing and searching will result in all rows being displayed.
Here is what my select statement currently looks like:
$query = "SELECT Record, `EMAIL 2`, DATEi, DATEf, PROJECT, `SAMPLE DESCRIPTION`, `FLD5_(As/VIN)` FROM `tbl_2018a` WHERE CONCAT (`EMAIL 2`, `PROJECT`, `SAMPLE DESCRIPTION`, `FLD5_(As/VIN)`) LIKE '%".$valueToSearch."%'";
valueToSearch in this case is the variable controlled by the client while preforming the search.
Is there a way to restrict the amount of characters the client must enter correctly before the results are displayed through either PHP or by modifying the select statement?
There are 2 solutions Client-side validation and Server-side validation :
Both need to be implemented by end of the day else you can't enforce the proper validation. And you can't just rely on client-side validation.
Client-side handling
It's better to put the client side validation first. Else you're hitting the server with unnecessary calls which can, in turn, affect your optimizations and performance in the long run, if not immediately.
If you're using the jQuery than on KEYUP while typing in the search bar you can check the number of characters enter in the search box in the length is more than or equal to 5 characters then only allowed to go for the ajax request.
/* Assuming that you may have the following kind of HTML */
<input type="text" name="filter" id="filter">
<span id="filter-error"></span> <!-- To show the filter error option, not a mandatory but useful to know the user whats causing the problem -->
For example to implement in jQuery
$('#filter').on('keyup', function(){
//
var searchData = $(this).val();
if(searchData == undefined || searchData.length < 5){
$('#filter-error').html("Please enter atleast 5 characters.");
return false;
}
/* Else the normal jQuery call what you want to handle her for sending the ajax request */
$.ajax({
/* Implementation */
});
});
Implementing on Serverside ie PHP
Once the form is submitted you need to check for the following validation.
Note: I am not demonstrating anything against a security vulnerability
if($_SERVER['REQUEST_METHOD'] == 'POST'){ /* Check if its a post method and not get method */
$filter = trim($_POST['filter']); /* making sure to trim the spaces just to make sure user doesnt post white spaces */
(strlen($filter)) ? (return 'Please enter atlease 5 characters') : '';
/* Even you can check for some more validations like whether its having only AlphaNumeric only or not or anything which you require */
}
Thank you everyone for your help. I was able to find a solution by modifying my html from to restrict the amount of minimum characters entered by the client.
<form action="php_html_table_data_filter.php" method="post">
<input type="text" name="valueToSearch" required minlength="5" maxlength="30" placeholder="Search"><br><br>
<input type="submit" name="search" value="Find Project"><br><br>
The 'required minlength' and 'required maxlength' functions were able to solve my problem and restrict client-side how many characters the user must eneter before the data is returned to the server.
Basically i have a form where a studentID is inputted, i then want to check id the inputted studentID is in the database, if it is post the form to the next page. If not then display an error on the page where you input studentID
Don't really know where to start
Cheers
is this what you want?
<form id = "form" action = "./?page=markandfeedback" method = "post">
<br>
Mark for:
<INPUT id="stud" onkeypress="return isNumberKey(event)" type="text" name="stud" value="Enter Student Number">
<input type="submit" value = 'Continue'>
<?
$studID = $_POST['stud'];
$module2 = $_SESSION['module'];
$ex = $_POST['exer'];
$studerr = array();
$sql = 'SELECT * FROM `student`, `modules` WHERE `studentID` = '.$studID.' AND `moduleCode` = '.$_SESSION['module'];
$result = mysql_query ($sql);
// echo $_SESSION['module'];
if ($result == NULL) { // nothing found
echo "the student id you entered is not in the database";
}
else {
$_SESSION['student'] = $studID;
Header("Location: http://www.whereever.com/"); // send the browser where you want
exit();
}
?>
EDIT:
I went over the other answers. I assume you check for mysql injection properly. I recommend implementing AJAX AFTER everything works and is secure. The idea behind my solution was to solve the problem as simple as possible. If you want to make something fancy out of it you could:
generate the whole form via php and tell the user in the input field, that the id wasn't found
tell your Javascript to present the information in some fancy way
Use AJAX. Everybody loves forms with AJAX.
You could, as suggested, assume that the user entered a valid id. You would check on the "whereever" page wether the id is actually valid. If it weren't, you would simply send the user back to the form and tell the php to output an error message (maybe via get). This possibility is not usual, I am not sure if it has any advantages.
the mysql_num_rows hint is nice, too, if you don't want any data from the user. I thought you wanted to do something with the data because of the SELECT *.
Make a seperate controller that does the checking of the username.
Use ajax to check if user input is valid or not.
So you'll have something like this:
<input id="stud" onchange="checkStudentId(this)" />
<script>
function checkStudentId(inputElement) {
var id = inputElement.value();
$.ajax({
url: "test.html",
context: {id:id}
}).done(function() {
// Check the return result
});
}
</script>
Here is a reference to jquery ajax
http://api.jquery.com/jQuery.ajax/
You actually have to connect to the server in some fashion to figure out of the student exists. What you'd normally do in this situation is submit the form to the server and do validation server-side. If the student exists, you return the "next" page. If the student doesn't exist, then you return (or redirect to using a Location header) the same form again with an error message.
Another popular method would be to use an AJAX request to check asynchronously (which I see many other people are recommending). I'd only recommend this way if you're actually doing validation right as they've finished entering the student id and are showing an error message in real-time, effectively. In this way, AJAX is a nice-to-have to provide quick user feedback, but not a real solution. Keep in mind that regardless of this, you need to check for and handle this when the form is submitted anyway, or at the least, consider what will happen when the form is submitted with an invalid id.
People can bypass this check (EVERY request from the client side is considered hostile, you can't implicitly trust anything)
Another user may have deleted the student ID between the time the check was done and the form was submitted
There could be an error in your code that causes validation to falsely pass or not to recognize a negative response
Doing AJAX onsubmit makes no sense, because effectively you're doubling the amount of work by making the server handle two separate requests in a row. It's simply the wrong answer to the problem.
The biggest trouble with this implementation is the PHP code can quickly get quite hairy and hard to follow as you have everything mixed together.
This is where you probably start to tip over using PHP like a templating language (mixed php code and html markup) and start getting into using a framework where your views (the HTML) are decoupled from your PHP code (if you're using the very-populate MVC pattern, this code is called your controller -- precisely because it controls how the server responds). This is how any professional developer will work. Kohana, CakePHP, and Zend are all examples of fairly popular MVC frameworks, all of which are used professionally.
You can do this in two different ways
AJAX - make ajax call to your server and check the ID if its exist display the error else go to the next page
PHP - put a hidden input in your form and make the action of the form to the same page and check everything their and keep the values of the input fields is the $_POST['field_name'];
And you can make the action into another page and return back variable or make a session to hold the error message
Try this:
<?
if(isset($_POST['stud'])){
$studID = $_POST['stud'];
$module2 = $_SESSION['module'];
$ex = $_POST['exer'];
$studerr = array();
$host="hostname";//your db host
$user="user";//your db user
$pass="pass";//your db pass
$conn=mysql_connect($host,$user,$pass);
$sql = 'SELECT * FROM `student`, `modules` WHERE `studentID` = '.$studID.' AND `moduleCode` = '.$_SESSION['module'];
$result = mysql_query ($sql,$conn);
if(mysql_num_rows($result)>0){//the id was found in the DB, do whatever here...
echo $_SESSION['module'];
$_SESSION['student'] = $studID;
Header("Location: http://www.whereever.com/");//redirect to wherever
$error=false;
}
else{//id was not found
$error=true;}
}//end of isset
?>
<? if($error===true){?> <div> The id was not found.... </div> <?}?>
<form id = "form" action = "<? echo $_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']; ?>" method = "post">
<br>
Mark for:
<INPUT id="stud" onkeypress="return isNumberKey(event)" type="text" name="stud" value="Enter Student Number">
<input type="submit" value = 'Continue'>
So what this does is: When the user hits submit, conects to the DB, and checks if the ID exists...if it does, then it redirects it to wherever.com (see comments) and if it don't an error messege will show up. Be sure to change the db variable values to your own ($host, $user, $pass).
On my website, I have user accounts that are configurable with forms that allow users to update everything from first and last names to privacy settings. I use the following function to update the database with that input. (Note that the following code uses WordPress-specific features.)
function update_account() {
global $current_user; get_currentuserinfo();
require_once( ABSPATH . WPINC . '/registration.php' );
$uid = $current_user->ID;
// First Name
if(isset($_POST['first_name']) && $_POST['first_name'] <> $current_user->first_name) {
wp_update_user( array(
'ID' => $uid, 'first_name' => esc_attr($_POST['first_name'])
));
}
// ...and so on 43 more times...
}
This feels like the wrong way to process forms. This also looks like it will negatively impact server performance when there are multiple users and frequent updates, given that the if-then-else conditions for every field, even fields not on a particular page, force checking each field for input.
Moreover, since form data can be expected to remain relatively constant, I added the <> operator to prevent the function from updating fields where there has not been any change, but I suspect this also means that every field is still evaluated for change. To make matters worse, adding new fields -- there are already 44 fields in total -- is an unwieldy process.
What's a better way to process form data?
Keep an array of the fields you will be processing with this code, and iterate over it. This works if all your attributes are strings, for example. If you have different data types such as boolean flags to handle differently from the strings, you may wish to group them into their own array.
// All the fields you wish to process are in this array
$fields = array('first_name', 'last_name', 'others',...'others99');
// Loop over the array and process each field with the same block
foreach ($fields as $field) {
if(isset($_POST[$field]) && $_POST[$field] != $current_user->{$field}) {
wp_update_user( array(
'ID' => $uid, $field => esc_attr($_POST[$field])
));
}
}
There's a lot of things missing with your implementation. I don't know what kinds of data you're allowing the user to manipulate but most usually have some kind of requirements to be acceptable. Like not having certain characters, not being blank, etc. I don't see any validation occurring, so how do you handle values that might be undesirable? And what happens when you receive bad data? How do you inform the user of the bad data and prompt them to correct it?
If we abstract the situation a bit we can come up with generalizations and implement an appropriate solution.
Basically form fields [can] have a default value, a user specified value [on form review], validation requirements and validation errors [with messages]. A form is a collection of fields that upon form submit needs to be validated and if invalid, re-displayed to the user with instructive corrective prompts.
If we create a form class that encapsulates the above logic we can instantiate and use it to pass around our controller/views. Oops, I was just assuming you were using an Model/View/Controller type framework, and I'm not really familiar with wordPress so I don't know if that is exactly applicable. But the principle still applies. On the page where you both display or process the form, here's some pseudo logic how how it might look.
function update_account()
{
// initialize a new form class
$form = new UserAccountInfoForm();
// give the form to your view for rendering
$this->view->form = $form;
// check if form was posted [however your framework provides this check]
if(!Is_Post())
return $this->render('accountform.phtml');
// check if posted form data validates
if(!$form->isValid($_POST))
{
// if the form didn't validate re-display the form
// the view takes care of displaying errors, with the help of its
// copy of the $form object
return $this->render('accountform.phtml');
}
// form validated, so we can use the supplied values and update the db
$values = $form->getValues(); // returns an array of ['fieldname'=>'value']
// escape the values of the array
EscapeArrayValues($values);
// update db
wp_update_user($values);
// inform the user of successful update via flash message
$this->flashMessage('Successfully updated profile');
// go back to main profile page
$this->redirect('/profile');
That makes your controller relatively clean an easy to work with. The view gets some love and care to, utilizing the $form value to display the form correctly. Technically, you can implement a method in the form class to give you the form html, but for simplicity I'm just going to assume your form html is manually coded in accountform.phtml and it just uses $form to get field info
<form action='post'>
<label>first name</label> <input class='<?=$this->form->getElement('first_name')->hasError() ? "invalid":""?>' type='text' name='first_name' value="<?=$this->form->getElement('first_name')->getValue()"/> <span class='errmsg'><?=$this->form->getElement('first_name')->getError()?></span><br/>
<label>last name</label> <input class='<?=$this->form->getElement('last_name')->hasError() ? "invalid":""?>' type='text' name='last_name' value="<?=$this->form->getElement('last_name')->getValue()"/> <span class='errmsg'><?=$this->form->getElement('last_name')->getError()?></span><br/>
<label>other</label> <input class='<?=$this->form->getElement('other')->hasError() ? "invalid":""?>' type='text' name='other' value="<?=$this->form->getElement('other')->getValue()"/> <span class='errmsg'><?=$this->form->getElement('other')->getError()?></span><br/>
<input type='submit' value='submit'/>
</form>
Here the pseudo code relies on the form class method "getElement" which returns the field class instance for the specified field name (which would be created an initialized in the constructor of your form class). Then on the field class methods "hasError" and "getError" to check if the field validated correctly. If the form has not be submitted yet, then these return false and blank, but if the form was posted and invalid, then they will have been set appropriately in the validate method when it was called. Also "getValue" would return either the value supplied by the user when the form was submitted, or if the form has not been submitted, the default value as specified when the field class was instantiated and initialized.
Obviously this pseudo code is relying on a lot of magic that you'd have to implement if you roll your own solution--and it's certainly doable. However, at this point I'll direct you to the Zend Framework Zend_Form components. You can use zend framework components by themselves without having to utilize the entire framework and application structure too. You might also find similar form component solutions from other frameworks but I wouldn't know about those (we are a Zend Framework shop at my work place).
Hopefully this hasn't been too complicated, and you know where to go from here. Of course just ask if you need any clarification.
In Yahoo or Google and in many websites when you fill up a form and if your form has any errors it gets redirected to the same page.
Note that the data in the form remains as it is. I mean the data in the text fields remains the same.
I tried ‹form action="(same page here)" method="post or get"›. It gets redirected to the page, but the contents of the form gets cleared.
I want the data to be displayed.
You know how tiresome it will be for the user if he has to fill up the entire form once again if he just forgets to check the accept terms and conditions checkbox.
Need help!
You need to do this yourself. When the page gets posted you'll have access to all the form values the user entered via $POST['...']. You can then re-populate the form fields with this data.
Here is a modified version of what I use for very simple websites where I don't want/need an entire framework to get the job done.
function input($name, $options = array()) {
if(!isset($options['type'])) $options['type'] = 'text';
$options['name'] = $name;
if(isset($_POST[$name]) && $options['type'] != 'password') {
$options['value'] = htmlspecialchars($_POST[$name]);
}
$opts = array();
foreach($options as $key => $value) {
$opts[] = $key . '="' . $value . '"';
}
return '<input ' . implode(' ', $opts) . '/>';
}
(I have a few similar functions for <select> and <textarea> and so on)
When you're building fields you can do something like:
First Name: <?=input('first_name')?>
Last Name: <?=input('last_name')?>
Password: <?=input('password', array('type' => 'password'))?>
If you process your forms in the same page as the form itself, they will get auto filled if there are any errors. Most frameworks, though, do all of this for you (and in a much better way than the code above), I personally suggest CakePHP or CodeIgniter.
This is not done automatically. They get values from post / get and then assign the values the user typed to the template. What you see is html that was generated from the script that handled user values.
If you put your form and the form data processing in the same script, you can easily print out the data that has already been entered in the form, e.g.:
$valid = false;
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['name']) && $_POST['name'] == 'Hugo') {
$valid = true;
} else {
echo '<p>Seriously, you have to enter "Hugo"!</p>';
}
// more data processing
if ($valid) {
echo '<p>Everything’s fine!</p>';
}
}
if (!$valid) {
echo '<form action="" method="post">';
echo '<p>Please enter "Hugo": <input type="text" name="name" value="', (isset($_POST['name']) ? htmlspecialchars($_POST['name']) : ''), '"></p>';
echo '<p><input type="submit"></p>';
echo '</form>';
}
Well this is not nice example but that’s how it works.
a lot of frameworks do this job for you, so dont waste your time doing this manually
You'll have to check the data within the same file, and if it is correct, then you redirect to the correct location. Then you can use the $_POST or $_GET information the user posted and he can fix the error(s).
You can use two approachs (they're not mutually exclusive):
Use JavaScript to help the user before he submits the form. That way, you save a roundtrip to the server.
What you asked for:
In the form, fill the value attributes of the fields with the data sent back from the server. For example: you send a field name, which you get as $_POST['name'] in PHP (assuming you used method='post'. If you send back the data and modify that field adding value='<?php $_POST['name']; ?> you should get your data back.
If you're using a template or framework system (I've incorporated the Smarty engine into several projects of mine), you can usually tweak the templates so they automatically fill fields with values if they detect that the $_POST[$variable] value corresponding to their field is set.
As for the passwords, as far as I understand it (I could be wrong): it's a convention that minimizes the amount of time that password is being sent over the wire, hence shrinking the window for anyone who may be sniffing to pick up on the text. It's just good practice to leave password fields blank, is all.
I've got a submission page in php with an html form that points back to the same page. I'd like to be able to check if the required fields in the form aren't filled so I can inform the user. I'd like to know how to do that with php and javascript each. However, I imagine this is a common issue so any other answers are welcome.
Do the check in posting part of your php
if(isset($_POST['save']))
{
$fields=array();
$fields['Nimi'] = $_POST['name'];
$fields['Kool'] = $_POST['school'];
$fields['Aadress'] = $_POST['address'];
$fields['Telefon'] = $_POST['phone'];
$fields['Email'] = $_POST['email'];
foreach ($fields as $key => $val)
{ if(trim($val)=='')
{ $errmsg=$key." is not filled!";
break;
}
}
}
if($errmsg == '')
{ //do your saving here
exit();
}
if(!isset($_POST['save']) || $errmsg != '')
{ //show your form here
// and make it to return to the same page on submit
//<input name="save" type="submit" value="Save" onclick="return true;">
}
For extra credit, once you know how to do it in PHP and JavaScript from Riho and annakata's answers, then build a way of defining a field constraint in a single form that can both be rendered as JavaScript for client-side validation and run on the server.
Since you need both (client-side for user convenience, server-side because we're really very much past trusting the client at this point), it seems like quite a decent idea to support both from a single infrastructure.
As far as JS goes you have to check before you submit. Generally this involves binding some validation function to the onsubmit event trigger of the form, and that validation function will consist of some tests for each field you're interested.
Most JS libraries have validation implementations that will do most of the work for you, which sounds like it might be a good idea for you. Googling "client side validation" will yield infinite results, but this (I'm library agnostic, read and choose for yourself) should get you started*:
http://blog.jquery.com/2007/07/04/about-client-side-form-validation-and-frameworks/
http://tetlaw.id.au/view/blog/really-easy-field-validation-with-prototype/
http://dojotoolkit.org/book/dojo-book-0-4/part-4-more-widgets/forms/validation
*this is on the teaching you to fish plan
The LiveValidation library would help you out a lot:
http://www.livevalidation.com/