I have a html form and this form is validating by PHP with jQuery/Ajax request.
Currently it's working perfectly. Now I want to show a dynamic error message.
For e. g:
I am validating integer number using following function :
function only_number ($string) {
if( preg_match('/^[0-9]+$/', $string ) ) {
return true;
} else {
return false;
}
}
This function is implementing by following way :
$msg = array();
$msg['error'] = false;
if(empty($emp_id)) {
$msg[] = 'Select assign to';
$msg['error'] = true;
} elseif( only_number($emp_id) === false ) {
$msg[] = 'Assign to must be numeric value';
$msg['error'] = true;
}
echo json_encode($msg);
You see that I am showing error message
Assign to must be numeric value
in the function implemented page e.g. update.php
It's very time consuming that I need to type several type of error message every time.
NOW, I want to write this error message in the function and it will show/implemented on validating page like : update.php page.
How can I do this ?
You can return array from your function. E.g:
function only_number ($string) {
$result = array(
'success' => false,
'error' => '',
);
if( preg_match('/^[0-9]+$/', $string ) ) {
$result['success'] = true;
} else {
$result['error'] = 'Assign to must be numeric value';
}
return $result;
}
And check:
if (empty($emp_id)) {
$msg[] = 'Select assign to';
$msg['error'] = true;
} else {
$check = only_number($emp_id);
if ($check['success'] == false) {
$msg[] = $check['error'];
$msg['error'] = true;
}
}
In stead of returning true/false you can also return a string with the error message
function only_number ($string) {
if (empty ($string) return 'Select assign to';
if(!preg_match('/^[0-9]+$/', $string ) ) return 'Assign to must be numeric value';
else return 'no error';
}
next in your code
if (only_number($emp_id) <> 'no error') echo (json_encode(only_number($emp_id)));
Related
I have a form in which I am using a preg_match function to validate fields. I have a generalized function for the matching. The function validateForm() is being called earlier on in the script with the appropriate values.
When the function is NOT passed any values, all the fields show the error message despite having correctly matching information. Generalized function with no arguments:
function validateForm() {
if(preg_match()) {
return true;
}
else {
return false;
}
} // end function validateForm
When I pass just ONE specific regex/field pair argument, all the fields begin to validate and show the error message when appropriate (so basically the code works as it should despite having a field-specific argument in the function). For example, when I pass this single regex/field argument into preg_match, all the fields begin to validate each field correctly, regardless of the fact that I am only checking for the 'City' field in this case. Example of passing a field-specific argument, in which all the code 'works':
function validateForm($cityRegex, $city) {
if(preg_match($cityRegex, $city)) {
return true;
}
else {
return false;
}
} // end function validateForm
Can someone explain to me why, when passed a specific argument for a specific field, the function will work for all individual preg_match arguments in the code? The script is running as I would want it to, I just do not understand why the specific argument is what makes it validate all fields.
Here is all of the PHP code, if needed:
<?php
$first = '';
$last = '';
$phone = '';
$city = '';
$state = '';
$error_message = '';
$firstLastRegex = '/^[a-zA-Z]{2,15}$/';
$lastRegex = '/^[a-zA-Z]{2,15}$/';
$phoneRegex = '/^(\(\d{3}\))(\d{3}\-)(\d{4})$/';
$cityRegex = '/^[a-zA-Z]{3,20}$/';
$stateRegex = '/^[a-zA-Z]{2}$/';
$validate_first = '';
$validate_last = '';
$validate_phone = '';
$validate_city = '';
$validate_state = '';
$phone_string = '';
if(isset($_POST['submit'])) {
$first = $_POST['firstName'];
$last = $_POST['lastName'];
$phone = $_POST['phoneNumber'];
$city = $_POST['userCity'];
$state = $_POST['userState'];
$show_form = false;
$phone_string = str_replace(array('-', '(', ')'), '', $phone);
$validate_first = validateForm($firstLastRegex, $first);
$validate_last = validateForm($lastRegex, $last);
$validate_phone = validateForm($phoneRegex, $phone);
$validate_city = validateForm($cityRegex, $city);
$validate_state = validateForm($stateRegex, $state);
if($validate_first == false) {
$show_form = true;
$error_message .= "Please enter your FIRST name between 2 and 15 letters.<br>";
}
if($validate_last == false) {
$show_form = true;
$error_message .= "Please enter your LAST name between 2 and 15 letters.<br>";
}
if($validate_phone == false) {
$show_form = true;
$error_message .= "Please enter your phone number in (###)###-### format.<br>";
}
if($validate_city == false) {
$show_form = true;
$error_message .= "Please enter your city name between 3 and 20 letters.<br>";
}
if($validate_state == false) {
$show_form = true;
$error_message .= "Please enter your state's abbreviation (Example: CA).<br>";
}
} // end if isset();
else {
$show_form = true;
$error_message = "";
} // end else
// REGEX FUNCTION
function validateForm() {
if(preg_match()) {
return true;
}
else {
return false;
}
} // end function validateForm
?>
You still need to have arguments for you function. The code below will make your validate function work.
function validateForm($regEx, $field) {
if(preg_match($regEx, $field)) {
return true;
}
else {
return false;
}
} // end function validateForm
I also see other potential issues with not checking if post variables are set before using them, and you are setting $show_form = true for all your if/else cases. I'm sure you can figure everything else out with some debug statements.
<?php
class Validator {
public $errors = array(
'password' => '',
'email' => '');
const PASSWORD_MINCHARS = 8;
public function checkEmail($email) {
if ($this->checkEmpty($email)) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->errors['email'] = "Please provide a valid email";
return FALSE;
} else {
return TRUE;
}
} else {
$this->errors['email'] = "Please provide a value for the email";
return FALSE;
}
}
public function checkPassword($string) {
if ($this->checkEmpty($string)) {
if (strlen($string) < self::PASSWORD_MINCHARS) {
$this->errors['password'] = "The password should be atleast ".self::PASSWORD_MINCHARS." characters long.";
return FALSE;
} else {
return TRUE;
}
} else {
$this->errors['password'] = "Please provide a value for the password";
return FALSE;
}
}
private function checkEmpty($string) {
if (!empty($string)) {
return TRUE;
}
return FALSE;
}
public function displayErrors() {
$output = '';
foreach ($this->errors as $error) {
if (!empty($error)) {
$output .= '<p>'.$error.'</p>';
}
}
return $output;
}
}
?>
<?php
require 'Validator.php';
$validator = new Validator();
$email = '';
$password = '';
if ($validator->checkPassword($password) && $validator->checkEmail($email)) {
echo 'You have entered a valid password and email.';
} else {
echo $validator->displayErrors();
}
?>
The above code comes from two separate files. The one that comes begins with class Validator comes from Validator.php while the one that begins with the require function comes from index.php. So am just wondering why the method call that is $validator->displayErrors() in index.php only displays one error at a time instead of displaying them all at once.
There is only one error displayed because of your condition:
if ($validator->checkPassword($password) && $validator->checkEmail($email))
It executes your checkPassword method first, it returns false and so the second condition (which should execute the second validation method) is never checked.
You can avoid this by executing the validation methods first:
$validPassword = $validator->checkPassword($password);
$validEmail = $validator->checkEmail($email);
if ($validPassword && $validEmail) {
echo 'You have entered a valid password and email.';
} else {
echo $validator->displayErrors();
}
Replace
if ($validator->checkPassword($password) && $validator->checkEmail($email))
with
if ($validator->checkPassword($password) || $validator->checkEmail($email)) {
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 certain script for Feed back. when i submit the form, it shows
"
Warning: substr() expects parameter 2 to be long, string given in /home/jetkvdmn/public_html/genFunctions.php on line 26"
the code below
<?php
$cEpro ="© Redeeming Mission 2012.";
function checkText($ElementVal) {
// If Text is too short
if (strlen($ElementVal)< 3) {
//alert('Text too small');
return false;
} else{
return true;
}
}
function checkEmail($vEmail) {
$invalidChars ="/:,;" ;
if(strlen($vEmail)<1) return false; // Invalid Characters
$atPos = stripos($vEmail,"#",1); // First Position of #
if ($atPos != false)
$periodPos = stripos($vEmail,".", $atPos); //If # is not Found Null . position
for ($i=0; $i<strlen($invalidChars); $i++) { //Check for bad characters
$badChar = substr($invalidChars,i,1); //Pick 1
if(stripos($vEmail,$badChar,0) != false) //If Found
return false;
}
if ($atPos == false) //If # is not found
return false;
if ($periodPos == "") //If . is Null
return false;
if (stripos($vEmail,"##")!=false) //If ## is found
return false;
if (stripos($vEmail,"#.") != false) //#.is found
return false;
if (stripos($vEmail,".#") != false) //.# is found
return false;
return true;
}
?>
$badChar = substr($invalidChars,i,1);
should be
$badChar = substr($invalidChars,$i,1);
^^^
You are passing i to the substr function, instead of $i
I have a validation function which returns either true or false.
However, I want it to provide info as to what the problem is, when there is one.
Let's say the function is like this:
function is_valid($val) {
$result = true;
if( rule_1_not_met ) $result = false;
if( rule_2_not_met ) $result = false;
return $result;
}
Which is used like this
$val = $_GET['some_param'];
if(!is_valid($val)) $out .= 'Not so helpful feedback.';
...
I thought I could change it like this:
function is_valid($val) {
$result = array(true, array());
if( rule_1_not_met ) $result[1][] = 'Reason 1';
if( rule_2_not_met ) $result[1][] = 'Reason 2';
if(count($result[1]) > 0) $result[0] = false;
return $result;
}
And use it like this:
$val = $_GET['some_param'];
$validation_result = is_valid($val);
if(!$validation_result[0]) $out .= implode('<br/>', $validation_result[1]);
...
My question is
Am I in, for unexpected results with this?
Are there better ways to achieve this?
P.S. Would make this community wiki
You are in the right track but I would like to do this in this way
function is_valid($val,&$mes) {
$result = true;
if( rule_1_not_met ) { $mes[]='message one'; $result = false; }
if( rule_2_not_met ) { $mes[]='Message two'; $result = false; }
return $result;
}
$mes=array();
if(isvalid($val,$mes) ===false) $out .= implode('<br/>', $mes);
In my opinion, your proposed solution works fine. The only problem with it is that you have to remember that $validation_result[0] is the status and $validation_result[1] contains the messages. This might be OK with you but it will be hard to maintain if other people use your code. One thing you can do is when you call your function, you can use array destructuring to at least store the results with meaningful variable names. For example:
[$valid, $errors] = is_valid($val);
if(!$valid) $out .= implode('<br/>', $errors);
For the reason mentioned above, I like Brad Thomas's solution of creating a specialized class that contains the messages and status. Since the properties are named, you don't have to guess how to access the validation information. Also, most good IDEs will autocomplete when you try to access their properties.
I also have an alternate solution. Instead of including a boolean true or false. Just return the array of messages. The caller would just have to check if the returned array has a non-zero number of errors. Here is an example:
function get_errors($val) {
$errors = array();
if( rule_1_not_met ) $errors[] = 'Reason 1';
if( rule_2_not_met ) $errors[] = 'Reason 2';
return $errors;
}
Then the caller would use it like this:
$val = $_GET['some_param'];
$validation_result = get_errors($val);
if (count($validation_result) > 0) $out .= implode('<br/>', $validation_result);
You could use a Result object that encapsulates return data, a message and a status.
i.e.
class Result( $bResult, $sMessage, $mData ) {
public function __construct() {
$this->bResult = $bResult;
$this->sMessage = $sMessage;
$this->mData = $mData;
}
}
In Your code:
$result = new Result(true, 'some helpful message here', null);
$reasons = array();
function is_valid($val)
{
global $reasons;
if ( rule_1_not_met ) $reasons[] = 'Reason 1';
if ( rule_2_not_met ) $reasons[] = 'Reason 2';
if ( count($reasons) == 0 )
return TRUE;
else
return FALSE;
}
if (!is_valid($condition))
{
echo 'Was not valid for these reasons<br />';
foreach($reasons as $reason)
echo $reason, '<br>';
}
else
echo 'Is valid!';
This question is old, and makes a showcase of bad and outdated practices. Using global is frowned upon, and using references in this context is just the same.
Only Cave Johnson's answer makes it straight, but still the usage could be confusing. A better solution would be to write a class, but not as silly one as in the Brad Thomas's answer.
class NumberValidator
{
protected $errors;
public function validate($number)
{
if(!is_numeric($number))
{
$this->errors[] = "The value provided is not numeric";
return false;
}
if($number < 10)
{
$this->errors[] = "The number is less than 10";
return false;
}
return true;
}
public function getErrors()
{
return $this->errors;
}
}
and then it can be used like this
$validator = new NumberValidator();
if($validator->validate($number)) {
/*success*/
}
and then $validator->getErrors() can be used elsewhere