The following code validates a new user password by asking them to confirm their password by entering it twice:
// search to see if is a vvalid file path
if (($val["type"] == "password") && !strstr($key , "_confirm")) {
$name = $val["name"] ? $val["name"] : $key ;
if ($input[$name] != $input[$name . "_confirm"]) {
//preparing the message
$fields["error"] = "Password and confirmation doesn't match.";
$fields["errors"][$name] = 1;
$fields["errors"][$name . "_confirm"] = 1;
$fields["values"] = $input;
}
}
I would like to include additional validation (i.e., password contains at least 1 number and 1 letter, special characters [!##$%], must be at least 8 characters in length.
What would be the proper code syntax to nest with the above code? THX
To add the validation, you need to find the Regex you like, e.g.
http://regexlib.com/Search.aspx?k=password&AspxAutoDetectCookieSupport=1
Then use that regex in your code (replace $regEx with your choice):
if (($val["type"] == "password") && !strstr($key , "_confirm")) {
$name = $val["name"] ? $val["name"] : $key ;
if ($input[$name] != $input[$name . "_confirm"]) {
//preparing the message
$fields["error"] = "Password and confirmation doesn't match.";
$fields["errors"][$name] = 1;
$fields["errors"][$name . "_confirm"] = 1;
$fields["values"] = $input;
}
if( !preg_match( $regEx, $input[$name] ) ) {
$fields["error"] = "Password must contain...";
$fields["errors"][$name] = 1;
$fields["values"] = $input;
}
}
For one-upper, one-lower, and one-digit w/ min 8 chars:
$regEx = '/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$/';
Add in some special-char requirements:
$regEx = '/^(?=.*[!##$%])(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$/';
Related
I am trying to validate a phone number using PHP, and would like to know if there's a way to do it with FILTER_SANITIZE_NUMBER_INT instead of regex.
I need the password to enforce the xxx-xxx-xxxx format (allows '-') and max length of 12 characters.
This is my code so far. Would this work to validate any number into the xxx-xxx-xxxx format?
$phone = clean_input($_POST["phone"]);
if (empty($phone)) {
$phoneErr = "Valid phone number required";
$isValid = false;
} else {
if (!filter_var($phone, FILTERSANITIZE_NUMBER_INT)) ;
$phone_to_check = str_replace("-", "", $filtered_phone_number);
if (strlen($phone_to_check) < 10 || strlen($phone_to_check) > 12) {
$isValid = false;
}
}
I would use preg_match instead as you can cover all your needs in one statement. This regex assures that the value must have 10 digits, with optional - after the third and sixth digits.
$phone = clean_input($_POST["phone"]);
$isValid = preg_match('/^\d{3}-?\d{3}-?\d{4}$/', $phone);
Demo on 3v4l.org
I prefer using preg_match() functions for this style of regex.
An example based on your pattern
$phone = '000-000-0000';
if(preg_match("/^[0-9]{3}-[0-9]{3}-[0-9]{4}$/", $phone)) {
// $phone is valid
}
For validating using FILTER_SANITIZE_NUMBER_INT() try code below
function validate_phone_number($phone)
{
$filtered_phone_number = filter_var($phone, FILTER_SANITIZE_NUMBER_INT);
if (strlen($filtered_phone_number) < 12) {
return false;
} else {
return true;
}
}
Now below is the usage of the function that we have just created:
$phone = "444-444-5555";
if (validate_phone_number($phone) == true) {
echo "Phone number is valid";
} else {
echo "Invalid phone number";
}
I am trying to code a form for a login using php to check it. But I can't get it to check the if I have any whitespaces and special characters for the username. I tried using the [\W]+ but that did not work.
<?php
$usernerr = "";
$passwerr = "";
$usern = "";
$passw = "";
$pattern = '/[\'\/~`\!##\$%\^&\*\(\)_\-\+=\{\}\[\]\|;:"\<\>,\.\?\\\]/';
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
if(empty($_POST['uname']))
{
$usernerr = "*Please add a username please!";
}
else
{
$usern = clearInput($_POST['uname']);
if(!preg_match('/s/', $usern) || !preg_match($pattern, $usern))
{
$usernerr = "*Username have only letters and numbers!";
}
$usernerr = "";
}
if(empty($_POST['psw']))
{
$passwerr = "*Please add a password please!";
}
else
{
$passw = clearInput($_POST['psw']);
$passwerr = "";
}
}
function clearInput($input)
{
$input = trim($input);
$input = stripslashes($input);
$input = htmlspecialchars($input);
return $input;
}
?>
Considering the error message you wrote, you are complicating yourself.
Instead of searching for the list of characters that aren't alpha num, search for alpha num only. Try using this pattern, and don't negate the condition.
$pattern = "/^[a-zA-Z0-9]+$/";
// Some code...
if(preg_match($pattern, $usern))
// ^-------------------------------Notice the changes
{
//Username is valid
}
Description of the pattern :
^ from the begining
[a-zA-Z0-9] search an alpha num
+ 1 or more time
$ to the end
/^[a-zA-Z0-9]+$/can be replaced by /^[[:alnum:]]+$/ or /^[a-z\d]+$/i which produce the same effect.
I'm trying to validate a password using preg_match and RegEx but it doesn't seem to work. What I want to do is: ensure the password meets the following minimal conditions:
- Contains mixed case letters
- Contains atleast one number
- The rest can be anything as long as the two conditions above are met.
I've tried the following RegEx but it doesn't seem to work properly:
(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9])
I've had other previous easier RegEx'es like: [A-Za-z0-9] but without success. I'm checking if preg_match($string, $pattern) == 0 (meaning the pattern doesn't match => validation fails) but it always returns 0. What am I doing wrong ?
Just add a starting anchor to your regex,
^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9])
OR
^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9]).*
Example:
$yourstring = 'Ab';
$regex = '~^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9])~m';
if (preg_match($regex, $yourstring)) {
echo 'Yes! It matches!';
}
else {
echo 'No, it fails';
} // No, it fails
I always try to avoid regex if it's possible so I took a different approach to the problem. The below code will test the password for at least one uppercase, one lowercase and one digit.
function isValidPassword($password)
{
$hasUppercase = false;
$hasLowercase = false;
$hasDigit = false;
foreach (str_split($password) as $char)
{
$charAsciiValue = ord($char);
if ($charAsciiValue >= ord('A') && $charAsciiValue <= ord('Z')) {
$hasUppercase = true;
}
if ($charAsciiValue >= ord('a') && $charAsciiValue <= ord('z')) {
$hasLowercase = true;
}
if ($charAsciiValue >= ord('0') && $charAsciiValue <= ord('9')) {
$hasDigit = true;
}
}
return $hasUppercase && $hasLowercase && $hasDigit;
}
var_dump(isValidPassword('Ab9c'));
var_dump(isValidPassword('abc'));
Output
bool(true)
bool(false)
I offer a different solution, mainly because regexp provides little error reporting, and you would have to manually test the string afterwards anywhay for cohesion. Consider breaking the patterns apart and adding their own error. Iterate each of the requirements, and test the pattern. Push errors into an array and check after for their existence. Return a predeclared variable as true/false for the purpose of validating using if(validate_password($pass)):. Here's the mockup:
function validate_password($pass){
$requirements = array();
//uppercase
$requirements['uppercase']['pattern'] = '/[A-Z]/';
$requirements['uppercase']['error'] = 'Your password must contain at least one uppercase letter.';
//lowercase
$requirements['lowercase']['pattern'] = '/[a-z]/';
$requirements['lowercase']['error'] = 'Your password must contain at least one lowercase letter.';
//requires a number
$requirements['number']['pattern'] = '/[0-9]/';
$requirements['number']['error'] = 'Your password must contain at least one number.';
//special characters
$requirements['special_character']['pattern'] = '/[!##$%^&*()\\-_=+{};\:,<\.>]/';
$requirements['special_character']['error'] = 'Your password must contain at least one special character.';
//length
$requirements['length']['pattern'] = '/^.{8,}/';
$requirements['length']['error'] = 'Your password must be at least 8 characters in length total.';
$is_valid = false; //our flag to return as true once all tests have passed.
$errors = false;
//validate all requirements
foreach($requirements as $idx => $req):
if(preg_match($req['pattern'], $pass, $matches)):
$is_valid = true;
else:
$errors[] = $req['error'];
$is_valid = false;
endif;
endforeach;
//if we had errors above
if($errors):
$is_valid = false;
foreach($errors as $error):
echo '<p>', $error, '</p>';
endforeach;
endif;
return $is_valid;
}
$pass = 'j!Adz6'; //change this to test
echo validate_password($pass);
And an eval.in example for your pleasure.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Regular Expression matching for entire string
On my form page, I am trying to make it only accept alphanumeric characters for my username and password and require that they be from 6 to 15 characters. When I type in invalid data, it will insert it into the database rather than throw the user error that I defined in my CheckAlNum function.
functions.php
function checkAlNum($whichField)
{
if (preg_match('/[A-Za-z0-9]+/', $_POST[$whichField])){
if ( (!count(strlen($whichField) >= 6)) OR (!count(strlen($whichField) <= 15 ))) {
$message1 = '<p> Username and password must be between 6 and 15 characters </p>';
return user_error($message1);
}
else{
return true;
}
}
else {
$message = '<p>Username and password can only be numbers or letters</p>';
return user_error($message);
}
}
Form.php
if (count($_POST) > 0) {
//Validate the inputs
$errorMessages = array();
//Validate the username
$item5 = checkAlNum('username');
if($item5 !== true) {
$errorMessages[] = $item5;
}
//Validate the password
$item6 = checkAlNum('password');
if($item6 !== true) {
$errorMessages[] = $item6;
}
//Validate the firstName and lastName
$item1 = checkNameChars('firstName');
if ($item1 !== true) {
$errorMessages[] = $item1;
}
$item2 = checkNameChars('lastName');
if ($item2 !== true) {
$errorMessages[] = $item2;
}
//Validate the office name
$item3 = checkOfficeChars('office');
if ($item3 !== true) {
$errorMessages[] = $item3;
}
//Validate the phone number
$item4 = validate_phone_number('phoneNumber');
if($item4 !== true) {
$errorMessages[] = $item4;
}
//Check to see if anything failed
if (count($errorMessages) == 0) {
$newEmployee = new Person;
$newEmployee -> insert();
}
else { //Else, reprint the form along with some error messages
echo "<h2><span>Error</span>: </h2>";
foreach($errorMessages as $msg) {
echo "<p>" . $msg . "</p>";
}
}
}
?>
I've tried playing around with the nesting of the if-else statements of the checkAlNum function and also the regex (although I'm pretty sure the regex is right). Maybe I'm just missing something really silly?
function checkAlNum($whichField)
{
if (preg_match('/^[a-z0-9]{6,15}$/i', $_POST[$whichField])) {
return true;
}
else {
$message = '<p>Username and password can only be numbers or letters, 6-15 characters long</p>';
return user_error($message);
}
}
Without the ^ and $ anchors, your regex only checks whether there are alphanumerics anywhere in the field, not that the whole thing is alphanumeric. And changing + to {6,15} implements the length check here, so you can remove that extra check in your code.
I think the second if statement is incorrect. It should be like this:
if ( !( (!count(strlen($whichField) >= 6)) OR (!count(strlen($whichField) <= 15 )) ) ) {
// ... do something
}
This is due to De Morgan Rule which states
A AND B = !( !A OR !B )
In any case, I would not do my checks this way, strucurally you will end up with too many nested if statements that are hard to maintain and make your code look unpretty. Try avoiding nested conditions in your code.
Barmar's answer is the best. But if you want to keep your if statement to check string length, you need to remove the count() as you are already checking the length using strlen().
if ( (!(strlen($whichField) >= 6)) OR (!(strlen($whichField) <= 15 ))) {
I want to refactor this piece of code, it takes input from a form, then sanitizes the input, then it checks if its empty, or too short. It does this for title, content and tags. It stores an errors encountered in an array called errors.
I want to make a function, something like this:
function validate_input($args)
Except I'm unsure as to how I'm going to implement it, and how it'll build up an error list.
(I know I can use something like PEAR QUICKFORM or php-form-builder-class, so please don't mention 'oh use Class xyz').
$title = filter_input(INPUT_POST, 'thread_title', FILTER_SANITIZE_STRING,
array('flags' => FILTER_FLAG_STRIP_HIGH|FILTER_FLAG_STRIP_LOW ));
$content = filter_input(INPUT_POST, 'thread_content');
$tags = filter_input(INPUT_POST, 'thread_tags');
# title here:
if (is_null($title) || $title == "") # is_null on its own returns false for some reason
{
$errors['title'] = "Title is required.";
}
elseif ($title === false)
{
$errors['title'] = "Title is invalid.";
}
elseif (strlen($title) < 15)
{
$errors['title'] = "Title is too short, minimum is 15 characters (40 chars max).";
}
elseif (strlen($title) > 80 )
{
$errors['title'] = "Title is too long, maximum is 80 characters.";
}
# content starts here:
if (is_null($content) || $content == "")
{
$errors['content'] = "Content is required.";
}
elseif ($content === false)
{
$errors['content'] = "Content is invalid.";
}
elseif (strlen($content) < 40)
{
$errors['content'] = "Content is too short, minimum is 40 characters."; # TODO: change all min char amounts
}
elseif (strlen($content) > 800)
{
$errors['content'] = "Content is too long, maximum is 800 characters.";
}
# tags go here:
if (is_null($tags) || $tags == "")
{
$errors['tags'] = "Tags are required.";
}
elseif ($title === false)
{
$errors['tags'] = "Content is invalid.";
}
elseif (strlen($tags) < 3)
{
$errors['tags'] = "Atleast one tag is required, 3 characters long.";
}
var_dump($errors);
Should be pretty simple if understood your problem correctly and you want to validate and sanitize only those three variables.
function validateAndSanitizeInput(Array $args, Array &$errors) {
//validation goes in here
return $args;
}
In this case the errors array is passed by reference so you'll be able to get the error messages from it after the function has been called.
$errors = array();
$values = validateAndSanitizeInput($_POST, $errors);
//print $errors if not empty etc.
By the way you could replace "is_null($content) || $content == """ with "empty($content)"