I see this question come through here quite frequently and I just happened to finish another login script so I figured I would post it and you can take what you want from it. If you have any questions, feel free to ask.

<?php
session_start();

//include pdo mysql db connection, try to keep login info out of docroot
include("../common/db/connection.php");
$arrErrors = array(); //array to collect errors

//if form was submitted
if(isset($_POST['action']) && trim($_POST['action']) == "login")
{
    //if txtUser is blank
    if(!isset($_POST['txtUser']) || trim($_POST['txtUser']) == "") 
    {   
        $arrErrors[] = "user name or email address is blank";
    }   
    //if pass was blank
    if(!isset($_POST['txtPass']) || trim($_POST['txtPass']) == "") 
    {   
        $arrErrors[] = "password is blank";
    }   

    //if there were no errors thus far
    if(count($arrErrors) == 0)
    {   
        //form validator class to determine if txtUser is email or username
        include("lib/FormValidator.php");
        $validate = new FormValidator();

        //standard email validation
        $strColName = $validate->isEmail($_POST['txtUser'])?"email":"username";

        //start pdo prepare and query
        $objStatement = $objDB->prepare("select userpk, pass from user where " . $strColName . " = ?");
        $objStatement->execute(array($_POST['txtUser']));
        $arrResult = $objStatement->fetchAll(PDO::FETCH_ASSOC);

        //if response from database is not a valid response
        if(!is_array($arrResult) || count($arrResult) == 0)
        {
            $arrErrors[] = "0 records found with that information";
        }
        //else if password is not valid
        else if(md5($_POST['txtPass']) != $arrResult[0]["pass"])
        {
            $arrErrors[] = "0 records found with that information";
        }
        //else another check on the errors array, probably not needed
        else if(count($arrErrors) == 0)
        {
            //if done right, userpk should be all you need to maintain state for standard security
            $_SESSION['user'] = $arrResult[0]["userpk"];
        }

        //check to make sure that the userpk is in valid format, no reason it shouldn't be but you know
        if(isset($_SESSION['user']) && is_numeric($_SESSION['user']) && $_SESSION['user'] > 0)
        {
            header("location: index.php");
        }
        //if for some strange reason the userpk is not valid, clear all session and send error to user
        else if(count($arrErrors) == 0)
        {
            $_SESSION['user'] = NULL;
            $_SESSION = array();

            $arrErrors[] = "there was an unknown error regarding this login";
        }
    }
}

//buffer class manages html head, template header, footer and buffers output for me
include("lib/Buffer.php");
$buffer = new Buffer();
?>
<form action="/login.php" method="post">
<input type="hidden" name="action" value="login" />
<table cellpadding="0" cellspacing="0">
    <?php
    //output errors to user
    if(count($arrErrors) > 0)
    {
    ?>
        <tr><td style="color:red;">
        <span style="font-size:14px; font-weight:bold;">Please correct the following errors</span><br />
        <?php
            foreach($arrErrors as $error)
            {
                echo $error . "<br />";
            }
        ?>
        </td></tr>
    <?php
    }
    ?>
    <tr>
        <td>
            Username or Email Address<br />
            <input type="text" name="txtUser" id="txtUser"<?php echo isset($_POST['txtUser']) && trim($_POST['txtUser']) != ""?' value="' . trim($_POST['txtUser']) . '"':''; ?> />
        </td>
    </tr>
    <tr><td>&nbsp;</td></tr>
    <tr>
        <td>
            Password<br />
            <input type="password" name="txtPass" id="txtPass" />
        </td>
    </tr>
    <tr><td>&nbsp;</td></tr>
    <tr>
        <td>
            <input type="submit" name="btnSubmit" id="btnSubmit" value="Login" />
        </td>
    </tr>
</table>
</form>
<?php
//notify buffer class to save the contents of this page
$buffer->closePage();

//all is well, we are ready to ouput to the browser
$buffer->outPut();
?>
                                                                                                           121,1         Bot

You are using classes, but you do not include the class files... you call $objDB and $objStatement but at no point in the code above do I see these being declared.

If someone came across this script and tried to use it, they will not have much success.

Member Avatar for diafol
//include pdo mysql db connection, try to keep login info out of docroot
include("../common/db/connection.php");

I assumed PDO referenced via this include. May be wrong. However couldn't see other classes included, e.g.

include("lib/FormValidator.php");

I apologise if they're there - got code-blindness! A few refs are made to lib directory files. Could they be zipped and included in another post - or are they third party scripts? Perhaps a link to said files would be useful.

That said, I like it.

//include pdo mysql db connection, try to keep login info out of docroot
include("../common/db/connection.php");

I assumed PDO referenced via this include.

right, it's just a simple one liner:

$objDB = new PDO('mysql:host=localhost;dbname=dbname', "username", "password");
include("lib/FormValidator.php");

This actually is not complete yet since it will mold around what I need when I need it, but this is how it is at the moment:

<?php
class FormValidator
{
    public $arrErrors = array();

    function __construct()
    {

    }

    function isEmail($strEmail, $strFieldName = false)
    {
        if(!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $strEmail))
        {
            if($strFieldName != false)
            {
                $this->arrErrors[$strFieldName] = "invalid";
            }
            return false;
        }
        else
        {
            return true;
        }
    }
}
?>

The way I envision this is being able to respond to a spot check here and there as well as several checks in a row and just collect the errors at the end.

You are using classes, but you do not include the class files... you call $objDB and $objStatement but at no point in the code above do I see these being declared.

If someone came across this script and tried to use it, they will not have much success.

My point was not to provide a cut and paste solution for anyone who needs one but rather some direction for someone who may have a specific question or two. And if anyone is interested in other peripherals that I have attached, they are free to ask.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.