Php file is slow

Discussion in 'PHP' started by Clue, Dec 13, 2008.

  1. #1
    Hello this might sound wierd but i have php files on my site, and the load time is slow, when i enter login.php its show everyting but stil its loading 1-2 sec in the status bar in iexplorer. please help
    Source code is:

    <?PHP
    // retrieve the submitted values
    $username1 = @$HTTP_POST_VARS["username"];
    $password1 = @$HTTP_POST_VARS["password"];
    $rememberMe = @$HTTP_POST_VARS["rememberMe"];
    
    // make sure that rememberMe has a value
    if ($rememberMe == "rememberMe"){
    	$rememberMe = "1";
    }else{
    	$rememberMe = "0";
    }
    
    // let the config.php file connect to the database
    include("config.php");
    
    // check it the username exist
    $query = "Select * from ".$DBprefix."signup where username='$username1'";
    $result = mysql_query($query); 
    if ($row = mysql_fetch_array($result)){ 
    	// check if his account is activated, if not skip to this if's else case
    	if ($row["actnum"] == "0"){
    		// and check if his account is not loccked, if not skip to this if's else case
    		if ($row["numloginfail"] <= 5){
    			// finally we check the database to see if the password is correct, if not skip to this if's else case
    			if ($row["password"] == $password1){
    				// we determin the date for the lastlogin - field.
    				$datetime = date("d-m-Y G:i ");
    				// and we update that field
    				$query = "UPDATE ".$DBprefix."signup Set lastlogin = '$datetime' where username='$username1'";  
    				$result = mysql_query($query); 
    				// now that the correct password is used to log-in, reset the numloginfail-field to 0
    				$query = "UPDATE ".$DBprefix."signup Set numloginfail = '0' where username='$username1'";  
    				$result = mysql_query($query); 
    				// tell we want to work with sessions
    				session_start();
    				// remove al the data from the session (auto logoff)
    				session_unset();
    				// remove the session itself
    				session_destroy();
    				// put the password in the session
    				@ session_register("pass");
    				$HTTP_SESSION_VARS["pass"] = $password1;
    				// put the username in the session
    				@ session_register("id");
    				$HTTP_SESSION_VARS["id"] = $username1;
    				// send the the cookie if needed
    				if($rememberMe=="1"){
    				setcookie("rememberCookieUname",$username1,(time()+604800));
    				setcookie("rememberCookiePassword",md5($password1),(time()+604800));
    				}
    				// go to the secured page.
    				header("Location: members/index.html");
    			}
    			else{
    				// else the password is incorrect. Therofore we have to update the numloginfield and lastloginfail field
    				// first we set $datetime to the current time in a format that we can use to calculate with.
    				$datetime = date("d")*10000000000 + date("m")*100000000 + date("Y")*10000 + date("G")*100 + date("i");
    				// then we check if the last log-in fail was less than 5 minutes ago.
    				if ($row["lastloginfail"] >= ($datetime-5)){
    					// if it is  we update both the numloginfail & the lastloginfail fields.
    					$query = "UPDATE ".$DBprefix."signup Set numloginfail = numloginfail + 1 where username='$username1'";  
    					$result = mysql_query($query); 
    					$query = "UPDATE ".$DBprefix."signup Set lastloginfail = '$datetime' where username='$username1'";  
    					$result = mysql_query($query); 
    				}
    				else{
    					// if it is more than 5 minutes ago, just set the lastloginfail field.
    					$query = "UPDATE ".$DBprefix."signup Set lastloginfail = '$datetime' where username='$username1'";  
    					$result = mysql_query($query); 
    				}
    		// and ofcourse we tell the user that his log-in failed.
    		makeform($incorrectLogin);}
    		}
    		// if the numloginfail value is larger than 5 that means there someone tryed to break the password by brute force
    		// we will now check how long ago the lock was engaged. it is is more than half an hour ago is, then we will unlock the account
    		// and ask the user to login 1 more time to validate it is really him.
    		else {
    			$datetime = date("d")*10000000000 + date("m")*100000000 + date("Y")*10000 + date("G")*100 + date("i");
    			if ($row["lastloginfail"] <= ($datetime-30)){
    				// set the numloginfail value to 5 so the user has 1 change to enter his password.
    				$query = "UPDATE ".$DBprefix."signup Set numloginfail = '5' where username='$username1'";  
    				$result = mysql_query($query); 
    				// ask the user to enter his username/password once again. Also we set the username field
    				// to the name the username entered in the first login of this user. By doing this the makeform function
    				// disables the username-field.
    				makeform($underAttackReLogin, "$username1");
    			}
    			else{
    			// if it is less than 30 minutes ago ask the user to wait untill the lock is released again.
    				echo $underAttackPleaseWait;
    			}
    		}
    	}
    	// if the actnum is other than 0 that means the account has not been activated yet.
    	else{
    	makeform($accountNotActivated);
    	}
    }
    // if the username does not exist we check it is filled in.
    else{
    	// if it isn't filled we assum that this is the page load and we show the form without an error.
    	if ($username1 == ""){	
    		makeform("");
    	}
    	else {
    	// if the form is filled it that means that the username does not exist. Therefore we show the form
    	// with an error. We can not change the numloginfail or lastloginfail fields for the brute forece attack
    	// because the attack isn't pointed at one user.
    		makeform($incorrectLogin);
    	}
    }
    
    // this function shows the form.
    // ....m($errormessage="", ... indicates an optionale argument for this function, same for $username.
    function makeform($errormessage="", $username2 = ""){
    
    ?>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <title>Memonice - LOG-IN</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta name="description" content="Something you whant to remember, then this is the place to put it!"> 
    <meta name="keywords" content="Write, memos, save notes, save url, notepad, memopad, easy and fun, write note, write memos"> 
    
    <style type="text/css">
    <!--
    .style1 {font-size: 9px}
    .style2 {color: #FFFFFF}
    .style4 {font-size: 12px}
    .style5 {font-size: x-small}
    -->
    </style>
    </head>
    <body>
    <h1 align="center">&nbsp;</h1>
    <h1 align="center">&nbsp;</h1>
    <h1 align="center">&nbsp;</h1>
    <h1 align="center">Login</h1>
    <div>
      <div align="center">
        <?PHP 
    // First we check if the errormessage variable is empty, if it is. we print the error message
    if ($errormessage != ""){echo "<font color=\"#FF0000\"><strong>$errormessage</strong></font><br>";} ?>
      </div>
    </div>
    <div>
      <form name="form1" method="post" action="login.php">
        <p align="center">Username: 
          <input name="username" type="text" id="username" value=<?PHP
    	// this code allow's us to put a value in the username-field.
    	// this is so users can't login under a other name when there 
    	// password is asked.
    	echo "\"$username2\"";
    	// this disables the field if the $username2 variable is NOT empty.
    	if ($username2 != ""){echo "DISABLED";}
    	?>>
          <br>
        <span class="style1">.</span><br>
          Password: 
          <input name="password" type="password" id="password">
          <br>
        <span class="style1">.</span><br>
          <span class="style2">......      </span>
          <input type="checkbox" name="rememberMe" value="rememberMe">
          Remember me<br>
          <span class="style1">.</span><br>
          <input type="submit" value="LOG IN">
        <span class="style2">    ......</span></p>
        <p align="center"><span class="style2">...</span><a href="forgot.php">Forgot password</a> <br>
          <a href="signup.php">Get an account</a></p>
      </form>
    <p class="style4" style=" position: absolute; bottom: 0; left: 0; width: 100%; text-align: center;"><span class="style5">Copyright &copy; 2008, <a href="mailto:staff@memonice.com">Contact</a></span></p>
    </div>
    </body>
    </html>
    <?php } ?>
    PHP:
     
    Clue, Dec 13, 2008 IP
  2. xrvel

    xrvel Notable Member

    Messages:
    918
    Likes Received:
    30
    Best Answers:
    2
    Trophy Points:
    225
    #2
    Is it hosted? It could be your internet connection.

    Do not use "@" too many. I read somewhere that it makes your script slow.

    Use mysql_fetch_array / mysql_fetch_assoc correctly. In your previous example i guess you can use mysql_fetch_assoc instead.
     
    xrvel, Dec 13, 2008 IP
  3. jestep

    jestep Prominent Member

    Messages:
    3,659
    Likes Received:
    215
    Best Answers:
    19
    Trophy Points:
    330
    #3
    You should combine database queries where you can. There are several places above that can be combined.

    Also, $HTTP_POST_VARS is going to be unusable in php6, you should switch to $_POST.

    A lot of this script looks like it was written for php3 which may be causing some speed issues. Try using microtime() to debug different sections of your script. I would start with the mysql queries first.

    Here' show to find the slow sections of a script.

    
    $time_start = microtime(true); //put above code to be checked
    $time_end = microtime(true); //put after code to be checked
    $execution_time = $time_end - $time_start;
    
    PHP:
     
    jestep, Dec 13, 2008 IP
  4. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #4
    let's see, they covered using $_POST, good start... Another quick speedup would be swapping your use of double quotes for singles when you aren't injecting variables. We can swap the rememberMe if statement for a inlined conditional, and pass numerics instead of values (though honestly you might be better off using boolean instead)... and really there's no reason to be running that as two separate declarations.

    Slowdown could also be in your config.php...

    Hmm. Four 'space' tabs instead of hard tabs - slower parsing but like all of the above nothing that would REALLY drag it to a crawl.

    On first execute, the sheer volumn of comments would drag it to a crawl, but if it's caching at all that's less of a concern. A lot of that is excess unneeded verbosity.

    Though you have one HUGE problem, not sanitizing your inputs before sending them to mySQL. Wide open to code injections there.

    You also seem to be calling the database a couple more times than is needed - you can nab lastlogin and numloginfail in one fell swoop... the mySQL calls are probably the slowest part, so the less calls you make, particularly in writes, the better.

    For the most part you have a lot of PHP4 - and even PHP3 code in there... Most of it being recommended to be no longer used, and all of it being three to four lines of code to accomplish what one line should be doing (assuming PHP5 is on your host)

    I would NOT be storing the password as session data and most CERTAINLY not as a cookie.

    The actual passing method is, well, first not secure, and second you are loading one file to send a redirect to load a second (members/index.html) - that's two full handshakes so of course it's going to be slow. That whole thing is not only not secure, but combined with passing the actual password, even as MD5 to the client as a cookie? WAY too easy to pwn.

    Let's see... continuing through... I'd probably use $_SERVER['REQUEST_TIME'] instead of that overly complex date handler for lastloginfail.... though that may mean changing the field type in your database of what lastloginfail is.

    The makeform method could also use a little 'help'... If I was to write what you have there now without 'major' functionality changes, it would probably go something like this:

    <?PHP
    
    function sanitize($str){
    	if (get_magic_quotes_gpc()) $str=stripslashes($str);
    	if (function_exists('mysql_real_escape_string')) {
    		return mysql_real_escape_string($str);
    	} else return addslashes($str);
    }
    
    // retrieve the submitted values
    $username=sanitize($_POST['username']);
    $password=sanitize($_POST['password']);
    $rememberMe=($_POST['rememberME']=='rememberMe');
    
    // config.php connects to database
    include('config.php');
    
    // check it the username exist
    $query="SELECT * FROM ".$DBprefix."signup
    	WHERE username='$username'
    ";
    $result=mysql_query($query); 
    
    if ($row=mysql_fetch_array($result)) { 
    	// is account activated?
    	if ($row['actnum']==0) {
    		if ($row['numloginfail']<=5) { // Account not locked
    			if ($row['password']==$password) {
    				$datetime = date("d-m-Y G:i ");
    				/*
    					plug into log current date and time
    					and set login failures to zero
    				*/
    				$query="UPDATE ".$DBprefix."signup 
    					SET lastlogin='$datetime',
    						numloginfail=0
    					WHERE username='$username'
    				";	
    				$result = mysql_query($query); 
    				
    				session_start();
    				session_unset();
    				session_destroy();
    				$_SESSION['id']=$username;
    				$_SESSION['pass']=$password;
    				
    				if ($rememberMe) {
    					setcookie("rememberCookieUname",$username,(time()+604800));
    					setcookie("rememberCookiePassword",md5($password),(time()+604800));
    				}
    				
    				header("Location: members/index.html");
    				
    			} else { // password incorrect
    				$query="
    					UPDATE ".$DBprefix."signup
    					SET numloginfail=numloginfail+1,
    						",( // if less than five minutes, update lastloginfail time
    							(($row['lastloginfail']-$_SERVER['REQUEST_TIME'])<300) ?
    							"lastloginfail='$_SERVER['REQUEST_TIME']'" : ""
    						),"
    					WHERE username='$username1'
    				";	
    				$result = mysql_query($query); 
    				showForm($incorrectLogin);
    				
    			} else if (($row['lastloginfail']-$_SERVER['REQUEST_TIME'])>1800) { // login failed 
    				// if more than 30 minutes give 1 chance to enter password correct
    				$query="UPDATE ".$DBprefix."signup
    					SET numloginfail=5
    					WHERE username='$username1'
    				";  
    				$result = mysql_query($query); 
    				// when showing the login form, pre-fill in username
    				showForm($underAttackReLogin, "$username1");
    			}	else {
    				echo $underAttackPleaseWait;
    			}
    			
    		} else {
    			// you have no handler for if the account is locked!
    		}
    			
    	} else { // account not activated
    		showForm($accountNotActivated);
    	}
    	
    } else { // username not found
    
    	if ($username1 == "") { // if was blank, throw a blank form
    		showForm("");
    	}	else showForm($incorrectLogin);
    	
    }
    
    function showForm($errormessage='',$username='') {
    echo '
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html
    	xmlns="http://www.w3.org/1999/xhtml"
    	lang="en"
    	xml:lang="en"
    ><head>
    
    <meta
    	http-equiv="Content-Type"
    	content="text/html; charset=iso-8859-1"
    />
    
    <meta
    	name="description"
    	content="Something you whant to remember, then this is the place to put it!"
    /> 
    
    <meta
    	name="keywords"
    	content="Write, memos, save notes, save url, notepad, memopad, easy and fun, write note, write memos"
    /> 
    
    <title>
    	Memonice - LOG-IN
    </title>
    
    <link 
    	type="text/css"
    	rel="stylesheet"
    	href="screenLogin.css"
    	media="screen,projection,tv"
    />
    
    </head><body>
    
    ';
    
    // First we check if the errormessage variable is empty, if it is. we print the error message
    if ($errormessage != "") echo '
    	<div class="errorMessage">',$errormessage,'</div>
    ';
    
    echo '
    	<form name="form1" method="post" action="login.php">
    		<div class="fieldsetWrapper"><fieldset>
    			<legend><span>Login</span></legend>
    			<label for="username">
    				Username: 
    				<input 
    					id="username"
    					name="username"
    					type="text"
    					value="',$username,
    					(($username!='') ? ' disabled="disabled"' : ''),' 
    				/>
    			</label><br />
    			<label for="password">
    				Password:
    				<input 
    					id="password"
    					name="password"
    					type="password"
    				/>
    			</label><br />
    			<label for="rememberMe">
    				<input 
    					id="rememberMe"
    					name="rememberMe"
    					type="checkbox"
    					value="rememberMe"
    				/>
    				Remember me
    			</label><br />
    			<input 
    				type="submit"
    				value="LOG IN"
    			/><br />
    			<a href="forgot.php">Forgot password?</a><br />
    			<a href="signup.php">Get an account.</a>
    		</fieldset></div>
    	</form>
    	<div id="footer">
    		&copy; 2008 <a href="mailto:staff@memonice.com">Contact</a>
    	</div>
    </body></html>
    ';
    }
    
    ?>
    Code (markup):
    completely untested mind you, but would definately be better since we go from over 8k of code to 4.6k.
     
    deathshadow, Dec 13, 2008 IP
  5. xxKillswitch

    xxKillswitch Peon

    Messages:
    331
    Likes Received:
    8
    Best Answers:
    0
    Trophy Points:
    0
    #5
    You can also try using mysql_fetch_object and load results as objects. I've heard its faster than loading arrays. But I think death covered all others above.
     
    xxKillswitch, Dec 13, 2008 IP
  6. Clue

    Clue Peon

    Messages:
    2
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #6
    thanks for the feedbak i will look in to all that you have said above!
     
    Clue, Dec 16, 2008 IP