Jump to content

Archived

This topic is now archived and is closed to further replies.

jeds

preg_match not working?

Recommended Posts

I have a form on page1.php which submits to itself:

[code]<FORM ACTION="page1.php" METHOD="POST">

enter: <INPUT TYPE="PASSWORD" NAME="field" MAXLENGTH="17" /><BR />

<INPUT TYPE="submit" />
</FORM>
[/code]

the second part of page1.php checks that the entry is correct, and starts the session if the entry is correct.
The entry is checked by a script:
[code] <?php         
if ($field == 'mylogin')
{
$var1 = "value1";
}
elseif ($field == 'yourlogin')
{
$var1 = "value2";
else
echo "error message";
?>[/code]

The problem is that I want to allow only upper and lower case letters, and numbers for "field". This is how I am doing it:
[code]extract($_POST);
function check_field($field) //allowed chars
{
if (!preg_match("/[^a-zA-Z0-9]+$/s",$field))
return TRUE;
else
echo "bad entry"
}[/code]

I either cannot tell if it is working or it just isn't working, because the script throws its error message if an incorrect value is entered for $field. I have tried my preg_match script in several places (before the submit statement, before the session starts, inside the script.

Do I have something wrong with my preg_match script?
Do I need it in a certain place, to get it to check an entry before the other script checks it?
How do I check to see if preg_match is working? (If I add an entry to the variable script that includes a character other than big and small letters or numbers for $field, such as "#%7gE>", the script returns the value of $var1
just like it does not contain any unnallowed characters. If I enter a field value that includes unnallowed characters, but is not a match for $field, it goes to the error for the variable script.

I do have different error messages for each script. Everything works fine if I do not try to check for unnallowed characters.

Thanks

Share this post


Link to post
Share on other sites
Thanks, I tried it and got it to run, but it still is allowing unnallowed characters.
[code]<FORM ACTION="page1.php" METHOD="POST">

enter: <INPUT TYPE="PASSWORD" NAME="field" MAXLENGTH="17" /><BR />
<?php
extract($_POST);
function check_field($field) //allowed chars
{
if (!preg_match("/^[a-zA-Z0-9]$/i",$field))
return TRUE;
else
echo "bad entry";
}
?>

<INPUT TYPE="submit" />
</FORM>
[/code]
the error message "bad entry" never writes to the page (only my other error msg writes, when entering a field value not in the login script), and if the login script has a value using an unnallowed character, it still allows it to login.

Share this post


Link to post
Share on other sites
First off, preg_match("/^[a-z0-9]$/i", $blah) is fine. No need for A-Z seeing as i is case insensitivity. Secondly , it should look something like this

[code=php:0]
<?php

function validField( $field)
{
          if( preg_match( "/^[a-z0-9]$/i", $field ) ) {
                      return TRUE;
            } else {
                      print "Bad Chars\n";
            }
return FALSE;
}
[/code]

Share this post


Link to post
Share on other sites
still, the error message "Bad Chars" never writes to the page (only my other error msg writes, when entering a field value not in the login script), and if the login script has a value using an unnallowed character, it still allows it to login.

Share this post


Link to post
Share on other sites
I'd check to make sure your code is being called at all. Put

<?php if (isset($_POST)) { echo 'Yes, my code is working!'; } ?>

where you currently have your function and see if the script is being called at all.  I assume that the name of the file this form is in is 'page1.php'?

Share this post


Link to post
Share on other sites
I uploaded the files (may be different now) here:
http://www.phpfreaks.com/forums/index.php/topic,110652.msg448282.html#msg448282
I will do that again only if needed, to not use too many resources here.

I think that flow is the problem, but don't have the answer. I did try dwees test code, but let me try to explain the layout/flow, before I give the results.

page1.php - the login or start page:
This actually one large function, see http://www.phptutorial.info/learn/session.php, scroll down to "Password protection using sessions"

The only thing I do different from the tutorial above, is after the session starts and the $post variable is registered, is that I use a php include instead of writing a new html statement to page1.php

I also include "error.php" instead of his html, that writes if an incorrect value has been posted by the form.

The included file is "start.php" (sucessful login)
Right after the doc declaration start.php includes the file containing the function that checks to see if the form passed a correct value, and if so makes the associated variable available to print to the pages.
That file is called "check.php"

Note that check.php has its own error statement. It fires only if someone tries to browse directly to it. Voila! - the only thing viewable in source is "you are not authorized"

start.php contains links to the other files that are available upon submission of a correct form value. These each have a session start statement at the top, and an include statement for check.php. They also have an include for the error.php page, which fires if they are not logged in.

Now, all of that works, the error page fires with an incorrect login, or if they logout and try to type in one of the "inside" files. A successful login allows me to print the associated variables to any of the inside pages.

I just can't get my preg-check function to work. I have tried it:[list]
[*]just before the submit button, right after the input entry line. Putting dwees test code there prints the success text there, before (?) submitting a form value.

[*]just before the session start/reg. statements in the second part of page1.php.  dwees code here prints 2 session start warnings to the very top of the page:
"Cannot send session cookie/cache limiter - headers already sent by page1.php". However, still logged into "start.php, and returning variables from check.php. Clicking a link to the other inside pages fires "error.php, without the session start warnings

[*]At the beggining of check.php. Here (and in case 1) my preg_match function does not seem to work. dwees code prints the success statement to the very top of the resulting page, when logged in.

[/list]


Share this post


Link to post
Share on other sites
???

umm, should I put the files up here?

Do you prefer as code, or zipped attachment. (or not zipped)?

Share this post


Link to post
Share on other sites
I'm short on time to read all of that. See if this quick example helps. Type in some text and submit; it will show you the POST and tell you if your string is OK or not.

[code]
<pre>
<?php
if ($_POST) {
print_r($_POST);
echo preg_match('/^[a-zA-Z\d]+$/', $_POST['field']) ? 'OK' : 'Not OK';
}
?>

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="text" name="field"/>
<input type="submit"/>
</form>
</pre>

[/code]

Share this post


Link to post
Share on other sites
effigy,

What I did find out from your code was that I was not checking for the right input, so now that is corrected, I think.
However I still have the problem that the preg_match script is not checking the input. So along with my long narrative a couple posts ago, I am putting up my code in as flowchart a manner as I can, maybe somebody can see what is happening. I hope its not overkill, I have tried to keep it as short as possible, without leaving out something that might be relevant


login.php:

[code]<?php
if ($_POST["fieldname"]=="") {
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
        <head>                <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
                <title>login</title>
</head>
<body>
<h4> User Information</h4>

##tried preg_match here##

<FORM ACTION="login.php" METHOD="POST">

Entry: <INPUT TYPE="PASSWORD" NAME="fieldname" /><BR />

##tried preg_match here##

<INPUT TYPE="submit" />

##tried preg_match here##

</FORM>

##tried preg_match here##

</body>
</html>

<?php }else{

##tried preg_match here##

$uac=$_POST["fieldname"];

session_start();

if ($fieldname=="loginX"){ $permission="yes";}
if ($fieldname=="login2"){ $permission="yes";}
$fieldname=$_POST["fieldname"];
session_register("permission");
session_register("fieldname");

if ($permission=="yes"){
?>
<?php include("file2.php"); ?>

<?php }else{ ?>
<?php include("error.php"); ?>
<?php } ?>
<?php } ?>[/code]


##########################
file2.php:

[code]<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?php include("file1.php"); ?>
<html xmlns="http://www.w3.org/1999/xhtml">
        <head>
      <title>Start</title>
</head>
<body>

<a href="first.php">2</a>|<a href="file3.php">3</a>|<a href="file4.php">4</a>|<a href="logout.php">logout</a>

Write variables per login:
<br />
<?php echo "$var_1"; ?><br />
<?php echo "$var2"; ?><br />
        </body>
</html>[/code]


#####################

file1.php:

[code]<?php
##tried preg_match here##(see below)       
if ($fieldname == 'loginX') {
$var_1 = "value1";
$var2 = "value2";
} elseif ($fieldname == 'login2'){
$var_1 = "value3";
$var2 = "value4";
} else
echo "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><HTML><HEAD><TITLE>403 Forbidden</TITLE></HEAD><BODY><H1>Forbidden</H1>\nYou don't have permission to access this file.</BODY></HTML>";
?>[/code]


#####################
first.php:

[code]<?php
session_start();
if ($permission=="yes") {
?>

<?php include("file2.php"); ?>

<?php }else{ ?>
<?php include("error.php"); ?>
<?php } ?>[/code]

######################
file3.php etc:
[code]<?php
session_start();
if ($permission=="yes") {
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?php include("file1.php"); ?>
<html xmlns="http://www.w3.org/1999/xhtml">
        <head>
                <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
                <title>Page 3</title>
</head>
<body>

<a href="first.php">2</a>|<a href="file3.php">3</a>|<a href="file4.php">4</a>|<a href="logout.php">logout</a>
Write variables per login:
<br />
<?php echo "$var_1"; ?><br />
<?php echo "$var2"; ?><br />       
</body>
</html>
<?php }else{ ?>
<?php include("error.php"); ?>
<?php } ?>[/code]


######################

error.php:

[code]<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
        <head>
                <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
                <title>ERROR</title>
</head>
<body>
error msg
</body>
</html>[/code]

######################

logout.php:

[code]<?php
session_start();
session_unset(permission);
session_unset(fieldname);
session_destroy();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
        <head>
                <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
                <title>Logged Out</title>
</head>
<body>
Logged Out
</body>
</html>[/code]

######################
preg_match script: (modified after using efigy's script to check for characters other than A-Z, a-z, and 0-9)

[code]<?php
function validField( $fieldname)
{
if( preg_match( "/^[a-zA-Z\d]+$/", $fieldname ) ) {
return TRUE;
} else {
print "Bad Chars\n";
}
return FALSE;
}
?>[/code]

Tried it in six places indicated in above files by: ##tried preg_match here##
If file1.php has a user (fieldname) that contains a character not allowed, they still log in.
Any entry not a fieldname in file1.php returns error.php.

Browsing directly to file1.php returns the error message in file1.php

preg_match script added to file1.php returns the error message "Bad Chars" to the very top of login.php, regardless of what is entered; allowed characters, not allowed characters, and variable matches!:

[code]<?php
 
{
if( preg_match( "/^[a-z0-9]$/i", $fieldname ) ) {
return TRUE;
} else {
print "Bad Chars\n";
}
return FALSE;
}
       
if ($fieldname == 'loginX') {
$var_1 = "value1";
$var2 = "value2";
} elseif ($fieldname == 'login2'){
$var_1 = "value3";
$var2 = "value4";
} else
echo "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><HTML><HEAD><TITLE>403 Forbidden</TITLE></HEAD><BODY><H1>Forbidden</H1>\nYou don't have permission to access this file.</BODY></HTML>";
?>[/code]

Share this post


Link to post
Share on other sites
There is nothing wrong with the regex, it's your code logic, you can't do things one way and then try to do things another way, all that will do is confuse you. Setting a standard means that you should follow some basic rule that you create so that you see exactly what is going wrong. Indenting is great start, because it will show what code is executed and the order it happens. Then using the newer SUPER GLOBALS and switching to what Registered Globals On allows will only confuse you more. Because you don't know if your testing a variable that may or may not have been set.

Here is a simple example....

// login.php

[code]<?php

session_start ();

// load the variables

define ( 'ADD_VARIABLES', true );

include ( './variables.php' );

if ( isset ( $_SESSION['permission'] ) )
{
// doesn't belong here already logged in!

// done with the session close it

session_write_close ();

// kick them to a service page

header ( 'Location: file2.php' );

// full stop

exit ();
}
else if ( isset ( $_POST['fieldname'] ) )
{
// login request

if ( ! preg_match ( "/^[a-z0-9]+$/i", $_POST['fieldname'] ) )
{
// bad login input data

$_SESSION['error'] = 'the data on the form was invalid, try again!';

// done with the session close it

session_write_close ();

// kick them back to the login page

header ( 'Location: login.php' );

// full stop

exit ();
}
else if ( ! in_array ( $_POST['fieldname'], $valid_user ) )
{
// unknown password

$_SESSION['error'] = 'sorry that is not anywhere near correct, try again!';

// done with the session close it

session_write_close ();

// kick them back to the login page

header ( 'Location: login.php' );

// full stop

exit ();
}
else
{
// valid user

$_SESSION['permission'] = '';
$_SESSION['fieldname']  =  $_POST['fieldname'];

// done with the session close it

session_write_close ();

// kick them back to the file2.php page

header ( 'Location: file2.php' );

// full stop

exit ();
}
}
else
{
// session permission = no, also not login, check for the error

if ( isset ( $_SESSION['error'] ) )
{
// assign the error to a local variable

$error = $_SESSION['error'];
}

// remove the session, we don't need it

$_SESSION = array ();

session_destroy ();
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>login</title>
</head>
<body>
<?php
if ( isset ( $error ) )
{
echo " <div align='center'>" . $error . "</div";
}
?>
<form action='login.php' method='post'>
<div align='center'>
<br />
PASSWORD
<br />
<input type='PASSWORD' name='fieldname' />
<br />
<input type='submit' value='Login' />
</div>
</form>
</body>
</html>[/code]

// variables.php

[code]<?php

// check if the include flag is set

if ( ! defined ( 'ADD_VARIABLES' ) )
{
exit ();
}

$valid_user = array ( 'loginX', 'login2' );

// if we have a valid user assign the variables

if ( isset ( $_SESSION['permission'] ) )
{
if ( $_SESSION['fieldname'] == 'loginX' )
{
$var_1 = 'value1';
$var2  = 'value2';

}
else if ( $_SESSION['fieldname'] == 'login2' )
{
$var_1 = 'value3';
$var2  = 'value4';
}
}

?>[/code]

// file2.php

[code]<?php

session_start ();

if ( ! isset ( $_SESSION['permission'] ) )
{
// doesn't belong here, not logged in!

$_SESSION['error'] = 'funny person, please login!';

// done with the session close it

session_write_close ();

// kick them to a login page

header ( 'Location: login.php' );

// full stop

exit ();
}

// load the variables, valid logged in user

define ( 'ADD_VARIABLES', true );

include ( './variables.php' );

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Start</title>
</head>
<body>
2 | <a href="file3.php">3</a> | <a href="file4.php">4</a> | <a href="logout.php">logout</a>
<br />
Write variables per login:
<br />
<?=$var_1;?>
<br />
<?=$var2;?>
<br />
</body>
</html>[/code]


// logout.php

[code]<?php

session_start ();

if ( ! isset ( $_SESSION['permission'] ) )
{
// doesn't belong here, not logged in!

$_SESSION['error'] = 'funny person, please login!';

// done with the session close it

session_write_close ();

// kick them to a login page

header ( 'Location: login.php' );

// full stop

exit ();
}

// remove the session, it's a logout request

$_SESSION = array ();

session_destroy ();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Logout</title>
</head>
<body>
<br />
You are now logged out, <a href="login.php">relogin</a>?
<br />
</body>
</html>[/code]


Notice I don't mix code with output, and the code follows a logical pattern, so I can keep track of what is happening throughout the processing. I also don't use old PHP methods, because you should never let PHP control things that you your self should be controlling in your script, because you might not be able to control a PHP.INI setting which will make your code useless where you don't have a option to change a PNP.INI setting!

me!

Share this post


Link to post
Share on other sites
You are absolutely right. I was fairly certain it was my logic that was causing the problem.

By [quote]switching to Registered Globals On[/quote] you mean my session_register statements? Actually I had seen that session_register did not need to be used anymore, but I couldn't get it to work without them.

[quote]Notice I don't mix code with output[/quote].
Here I am less clear what you mean, but I will take a stab that code=php and output=html?

I do see that you have it separated much better in your example. I also was using file includes, while you are using header location statements. It looks like a better way, but I don't know why.

Thank you for the much more than simple (to me) example.

Share this post


Link to post
Share on other sites

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.