preg_match does not work - php

This script checks if there is a special character or not, if there is, it calls for the preg match's "Invalid" function, else it says username available. What happens here is that every time I write a special character like ##%^& it still says username available instead of saying invalid, and that's not how it's supposed to work. I have checked the PHP code for errors and it seemed to be clean. I have tried and run to everything on forums and couldn't find a solution. Your contribution will be so much appreciated!
if(isset($_POST['login'])) {
$login = mysql_real_escape_string($_POST['login']);
if(!empty($login)) {
$login_query = mysql_query("SELECT COUNT(`id`) FROM `account` WHERE `login` = '$login'");
$login_result = mysql_result($login_query,0);
if($login_result == 0) {
echo 'yes';
} else {
echo 'no';
}
}
}
if ( preg_match("/^[a-zA-Z0-9[:space:]]+$/" , $login) ) {
echo 'noinput';
}
P.S I am not some kid who has leeched a code from the internet and is trying to get the others to do the work for him, I have written like 70% of this script and it works pretty well except the special characters thingy which I'm so stuck with. I hope you can help me. Thank you!

Not sure what your problem is. I just wrote the following program:
<?php
$input="good string";
$input2="bad#string";
if (preg_match("/^[a-zA-Z0-9[:space:]]+$/",$input2)) {
echo $input2." matches\n";
}
else {
echo $input2." does not match\n";
}
if (preg_match("/^[a-zA-Z0-9[:space:]]+$/",$input)) {
echo $input." matches\n";
}
else {
echo $input." does not match\n";
}
And it correctly shows that $input matches, but $input2 does not.
Are you sure of what is in your input? Could there be a carriage return?
update I think it is simply a case of you misinterpreting the return values of the php script. Let's look at the options:
1) valid username, is available:
query is empty, print string "yes". The preg_match finds a match and prints "noinput".
2) valid username, not available:
query returns something, print string "no". preg_match prints "noinput"
3) invalid username, is available:
query is empty, print string "yes". The preg_match prints nothing.
4) invalid username, not available:
query returns something, prints string "no". preg_match prints nothing.
If that is not how you interpret the return values, that's your problem...
second update
I have just looked at the source code of your link, and this is indeed the problem. You seem to test for several different responses:
if(data=='no') {
// do stuff
} else {
// something else
});
}
if(data=='noinput') {
// more stuff
});
}
if(data=='invalid') {
// yet more stuff
});
In other words, you check for strings 'yes', 'no', 'noinput'. But the way your code is structured and run, this is not the output you produce. For which I refer you to the four cases above.
solution
You need to move the check for invalid inputs to earlier in the code; and you need to return immediately after finding a user name that does not match. I think the following will work:
if(isset($_POST['login'])) {
$login = mysql_real_escape_string($_POST['login']);
if ( preg_match("/^[a-zA-Z0-9[:space:]]+$/" , $login) )
{
$login_query = mysql_query("SELECT COUNT(`id`) FROM `account` WHERE `login` = '$login'");
$login_result = mysql_result($login_query,0);
if($login_result == 0)
{
echo 'yes';
}
else
{
echo 'no';
}
}
else
{
echo('noinput');
}
}

It doesn't appear your regular expression accounts for special characters. You'll need to add in the characters you want to catch outside of numbers and alpha.
Look here for some advice: http://www.regular-expressions.info/characters.html
Try something like /^[a-zA-Z0-9\$[:space:]]+$/
The \$ accounts for the literal character.

Related

Trying to get PHP to find user password in a dictionary wordlist? Code can find generic passwords like Banana123 but BananaC123 will return nothing

The user can enter a password into a POST form and the code will search the wordlist $file for the password. If it finds the password in the wordlist, it will inform the user. This works 90% of the time for generic passwords like Banana123 and Brad101. However, if the user enters a password like BananaK123 the code will return nothing. Is there a way to make the code ignore the letter 'K' in the password BananaK123 so it just searches for Banana123 instead?
if ($_SERVER["REQUEST_METHOD"] == "POST") {
function dictionaryCheck() {
$file = file_get_contents("100k-most-used-passwords-NCSC.txt");
if(isset($_POST['dictionaryCheck'])){
$password = ($_POST['password']);
$password2 = preg_replace("/[^a-zA-Z]/", "", $password);
$pos = stristr($file, $password2);
if ($pos === false) {
echo "The dictionary word '$password2' was not found";
} else {
echo "The dictionary word '$password2' was found ";
echo " and exists at position $pos";
}
}
}
}
dictionaryCheck();
Try looking into similar_text(). You may want to reject strings that match a certain similarity.
https://www.php.net/manual/en/function.similar-text.php
This was just to answer your direct question. However, I would not suggest this way. ZXCVBN is a better solution. The reason I am saying this is that you will not be able to tell your users WHY you are rejecting that password. You may cause a lot of frustration.

problem with registration and login php,will you check my code?if there is an error

I have a problem with either registration and login shows (undefined offset) and look at registration is there some problem with my code?it is the registration form the problem it sometimes saves the existing email in spite of the fact that I wrote a function for not submitting the existing email which is inside my data.txt. shortly the functions do not work properly
<?php
if(isset($_POST['submit_reg'])){
$var=file("data.txt");
$userData = $_POST['email'] . " " . $_POST['password'] . "\r\n";
$lines=0;
$db = fopen("data.txt", "a+");
foreach($var as $key=>$value){
$user = (explode(' ', $value));
if ($_POST["password"] === $_POST["confirm_password"]) {
//print_r($value);
if (trim($user[0]) == $_POST['email']) {
$lines++;
}
break;
}
}
if($lines){
echo "The email is already exists ";
}else{
fwrite($db,$userData."\r\n");
fclose($db);
echo "you are registered successfully ";
}
}
?>
and it is my login form the problem with login is it gives an error undefined offset 12
<?php
if (isset($_POST['submit_log'])) {
$email =isset($_POST['email']);
$password =isset($_POST['password']);
$file = explode( PHP_EOL, file_get_contents( "data.txt" ));
$auth = false;
foreach( $file as $line ) {
list($email, $password) = explode(" ", $line);
if ($_POST['email'] == $email && $_POST['password'] == $password) {
$auth =true;
break;
}
}
if($auth) {
echo "Login successfull!";
} else {
echo "Invalid username or password";
}
}
?>
Let me say first off, storing plaintext passwords in a .txt file is probably not the best way of building a longin system. (that's the disclaimer anyway).
Undefined offset (just a guess)
That said I see a few places to improve your code. My guess without more specifics about the error, is you may be pulling a empty array at the end of the file, it's typical to leave a hanging line return at the end (a new line with nothing else for the last line). Which may turn into something like this once you explode it for the second time on the space ['']. And then you try to access it using list which gives you undefined offsets.
You could use array_filter and maybe trim but instead of doing this:
$file = explode( PHP_EOL, file_get_contents( "data.txt" ));
You could try (which you should know as you use this function already)
$file = file( "data.txt", FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES ));
The file function, takes a file and breaks it into an array based on the line returns. So this takes the place of both explode and file_get_contents.
Then it has 2 (bitwise) flags which you could make use of:
array file ( string $filename [, int $flags = 0 [, resource $context ]] )
Reads an entire file into an array.
FILE_IGNORE_NEW_LINES
Omit newline at the end of each array element
FILE_SKIP_EMPTY_LINES
Skip empty lines
http://php.net/manual/en/function.file.php
These take the place of filtering the data for empty lines (something you weren't doing). Granted this is a file you created but you never know when a errant line return could creep in there.
Non-unique entries
if(isset($_POST['submit_reg'])){
$var=file("data.txt");
$userData = $_POST['email'] . " " . $_POST['password'] . "\r\n";
$lines=0;
$db = fopen("data.txt", "a+");
foreach($var as $key=>$value){
$user = (explode(' ', $value));
if ($_POST["password"] === $_POST["confirm_password"]) {
//NOTE: the uniqueness check only happens when the confirm password matches
if (trim($user[0]) == $_POST['email']) {
$lines++;
}
break;
}
}
if($lines){
echo "The email is already exists ";
}else{
//NOTE:yet you save it no matter if that is the case
fwrite($db,$userData."\r\n");
fclose($db);
echo "you are registered successfully ";
}
}
Your uniqueness check only works when the confirm password matches the password, however when it comes time to save the data, there is no check. Instead of just adding that check in around the saving bit, it would be better to wrap the whole thing inside this confirm test, as both pieces of that are known before touching the file:
Here I reworked this a bit for you
if(isset($_POST['submit_reg'])){
if ($_POST["password"] === $_POST["confirm_password"]) {
//VERIFY AND SANITIZE user input, if you put junk in you get junk out
$password = trim($_POST['password']);
//again use something better then die
if(empty($password))die('Password cannot be empty');
//because you split on space, you cannot allow it in inputs
if(preg_match('/\s+/', $password)) die('Password cannot contain spaces');
$email = trim($_POST['email']);
if(empty($email))die('Email cannot be empty');
//you may want to validate using something better
if(preg_match('/\s+/', $email )) die('Email cannot contain spaces');
//Use the flags
$var=file("data.txt", FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES);
//for duplication we only care if there is 1 previous entry
//which is enough to say its a duplicate
$exists=false;
foreach($var as $key=>$value){
$user = explode(' ', $value);
if (trim($user[0]) == $email) {
//we found a match this is enough to call it a duplicate
$exists = true;
break;
}
}
if($exists){
echo "The email is already exists ";
}else{
file_put_contants("data.txt", $email." ".$password.PHP_EOL, FILE_APPEND);
echo "you are registered successfully ";
}
}else{
echo "Confirm password must match password";
}
}
Other stuff
These are also incorrect:
$email =isset($_POST['email']);
$password =isset($_POST['password']);
Isset returns a boolean value, so you are assigning true or false to those two variables. This doesn't matter as you never check them and in your loop you overwrite with the call to list(). But just because someting "doesn't matter" doesn't mean it's correct.
These really should be something like this:
if(!isset($_POST['email']))
die("no email"); //dont use die but do some kind of error message
if(isset($_POST['password']))
die("no password"); //dont use die but do some kind of error message
SUMMERY
Really it's quite a mess. What I mean by this is you used 3 different ways to open and access the file data. You used the PHP line constant in some places but not all. You had code that was somewhat haphazardly thrown around, where you were setting things long before you need them, and in some cases you may not have needed them, so you were wasting resources setting them.
Please don't take the criticism hard, as I am not trying to offend. Simply pointing out places you could improve the flow of the code and simplify things. The big thing is don't get discouraged, in order to program effectively you have to have a no-quite attitude and the drive for continuous self improvement. Even after 9 years of PHP programing I still learn new things all the time, I learned (and wrote a library around it) something new just 2 days ago...
As I said at the beginning and to be honest a database would actually reduce the amount of code you need. It might be intimidating at first to use a database but you'll find that it's easier then doing this. An example is your check for uniqueness, you can set a field to be unique in the Database then you never need to worry about duplicates, only catching the errors for them.
I would suggest looking into PDO and prepared statements, password_hash and password_verify.
A final word of warning is I didn't test any of this so forgive me if there are any typos...
Hope it helps.

How can i check if a single mysql field is empty in php

After getting the user-info from my sql database I would like to check if some of the fields are empty and continue the script based on that. A simplified piece of code would look like this:
$userData = mysql_query("SELECT * FROM user WHERE user='".$user."' LIMIT 1");
if(mysql_num_rows($data) == 1){
$u_info = mysql_fetch_assoc($data);
if(empty($u_info['u_mobile'])){
echo 2;
exit();
} else {
echo 1;
exit();
}
} else {
echo 3;
exit();
}
The problem is the empty statement checking the recieved field. I've tried using empty(), isset(), not_null() and array_key_exists() with no luck and can't get around to what I'm doing wrong.
I also tried if($u_info['u_mobile']) == '' || $u_info['u_mobile']) == NULL) but that doesnæt work either.
Why is this, or how can I go about getting this information?
I need to collect the user-information and send them to fill out the information I don't have...
You're setting the query result to $userData but then you're using mysql_fetch_assoc($data); -- doh. You need to pass the variable that you set the query result to:
$u_info = mysql_fetch_assoc($userData);
It's OK, it is still 10AM EST so this can happen in the morning =)
I suggest that you turn on PHP error reporting. PHP would have alerted you that the array values were trying to access do not exist, saving you a lot of wasted frustration.
$userData = mysql_query("SELECT * FROM user WHERE user='".$user."' LIMIT 1");
if(mysql_num_rows($userData ) == 1){
$u_info = mysql_fetch_assoc($userData );
if(empty($u_info['u_mobile'])){
echo 2;
exit();
} else {
echo 1;
exit();
}
} else {
echo 3;
exit();
}
Please Run code..I think it will be compile better it was minor mistake

I need exact character match in PHP

I am trying to make a script, that interact with mysql database and allows to find someone by username. But the problem is that it is not comparing characters. Means in my databse, user name is "abcd", in lowercase. But when I go to
localhost/ABCD or
localhost/Abcd or
localhost/ABcd or any upper or lowercase, it shows me same result. I want different result with different cases. I don't know what to use. I searched a lot and found preg_match function but don't know how to use. The function I created for this match from database is,
function CheckPnP($var){
$db = new mysqli ('localhost', 'root', '', 'database');
if($var){
if($result = $db->query("SELECT * FROM `view` WHERE `username` = '$var'")){
if($result->num_rows){
$rows = $result->fetch_assoc();
$_GET['username'] = $rows['username'];
$_GET['view'] = $rows['page'];
include $_SERVER['DOCUMENT_ROOT'].'/core/view.php';
return true;
}
}
}
}
and my view.php page codes are
<?php
#$view = $_GET['view'];
#$username = $_GET['username'];
if($view == 'profile'){
echo 'This is profile page.';
}
else if ($view == 'page'){
echo 'This is page.';
}
else if ($view){
header('Location: /');
}
else if (empty($view)){
echo 'this is view page123. ';
}
echo '<br>'.$username;
?>
view.php page's codes are temporary. I will change them soon but right now I need to match characters of username from database and I need exact character match.
Please help me.
I actually just found out about this a few weeks ago:
SELECT * FROM `your_table` WHERE BINARY `your_column` = 'VaLue';
SELECT * FROM `your_table` WHERE BINARY `your_column` = 'value';
SELECT * FROM `your_table` WHERE BINARY `your_column` = 'vaLue';
This would return different results depending on your query.
I suggest you do the above instead of in PHP.
About your second question:
There are a ton of things you can do to match characters in PHP. strcmp (case sensitive), ===, ==, strcasecmp (case insenstive)

setting the result of a sql query as a variable inside an if statement in php

Kind of an unclear question but I'm trying to check if a username has been taken or not. The code I have now isn't erroring but it's also not working, when echoing the $username variable I get nothing.
$sql="SELECT people_username FROM people WHERE people_username='{$_POST['username']}'";
//Set the result of the query as $username and if the select fails echo an error message
if ($username = !mysql_query($sql,$con)) {
die('Error: ' . mysql_error());
}
else if ($_POST['username'] == $username){
$errors[ ] = 'This username is already in use, please try again...sorry';
}
Is it a syntax error or is my logic wrong?
i would just do
$resource = mysql_query("SELECT people_username FROM people WHERE people_username='".mysql_escape_string($_POST['username'])."'");
if(!$resource) {
die('Error: ' . mysql_error());
} else if(mysql_num_rows($resource) > 0) {
$errors[ ] = 'This username is already in use, please try again...sorry';
} else {
//username is not in use... do whatever else you need to do.
}
If some cheeky user happens to try: '; DROP people; -- as a username, you'd be in big trouble.
You may want to check the following Stack Overflow post for further reading on this topic:
What is SQL injection?
As for the other problem, the other answers already addressed valid solutions. However, make sure to fix the SQL injection vulnerability first. It is never too early for this.
Your code is wrong.
It should be something like this:
$sql="SELECT people_username FROM people WHERE people_username='".mysql_escape_string($_POST['username'])."'";
//If the select fails echo an error message
if (!($result = mysql_query($sql,$con))) {
die('Error: ' . mysql_error());
}
$data = mysql_fetch_assoc($result);
if ($data == null){
$errors[ ] = 'This username is already in use, please try again...sorry';
}
Notice that for security reasons you need to escape the strings you use in SQL queries.
mysql_query($sql,$con) returns a resultset (which may be empty)
you are not testing any condition with if($var = !'value'), you are just assigning a negated resultset to the variable $username (what beast that is, I am not sure)
My suggestion: Simplify the code, do not overload lines of code with multiple tasks.
3. List item

Categories