Web Hosting Talk







View Full Version : Help with PHP PEAR


pwalters09
02-09-2010, 11:26 AM
Hi guys,

I am stuck on something very simple. I am trying to write my new script using PHP PEAR and MySQL, but for some reason when I test the script and register an account it comes up that the user already exists (there is no data in the SQL table)

PEAR is installed on the server and I get no error when including DB.php so PEAR seems to be working...

Here is the code:

register.php

<?php
require('db_connect.php'); // database connect script.
?>

<html>
<head>
<title>Register an Account</title>
</head>
<body>

<?php

if (isset($_POST['submit'])) { // if form has been submitted
/* check they filled in what they supposed to,
passwords matched, username
isn't already taken, etc. */

if (!$_POST['uname'] || !$_POST['passwd'] ||
!$_POST['passwd_again'] || !$_POST['email']) {
die('You did not fill in a required field.');
}

// check if username exists in database.

if (!get_magic_quotes_gpc()) {
$_POST['uname'] = addslashes($_POST['uname']);
}

$qry = "SELECT username FROM users WHERE username = '".$_POST['uname']."'";
$name_check = $db_object->query($qry);

if (DB::isError($name_check)) {
die($name_check->getMessage());
}

$name_checkk = $name_check->numRows();

if ($name_checkk=="1") {
die('Sorry, the username: <strong>'.$_POST['uname'].'</strong>'
. ' is already taken, please pick another one.');
}

// check passwords match

if ($_POST['passwd'] != $_POST['passwd_again']) {
die('Passwords did not match.');
}

// check e-mail format

if (!preg_match("/.*@.*..*/", $_POST['email']) ||
preg_match("/(<|>)/", $_POST['email'])) {
die('Invalid e-mail address.');
}

// no HTML tags in username, website, location, password

$_POST['uname'] = strip_tags($_POST['uname']);
$_POST['passwd'] = strip_tags($_POST['passwd']);
$_POST['website'] = strip_tags($_POST['website']);
$_POST['location'] = strip_tags($_POST['location']);

// check show_email data

if ($_POST['show_email'] != 0 & $_POST['show_email'] != 1) {
die('Nope');
}

/* the rest of the information is optional, the only thing we need to
check is if they submitted a website,
and if so, check the format is ok. */

if ($_POST['website'] != '' & !preg_match("/^(http|ftp):///", $_POST['website'])) {
$_POST['website'] = 'http://'.$_POST['website'];
}

// now we can add them to the database.
// encrypt password

$_POST['passwd'] = md5($_POST['passwd']);

if (!get_magic_quotes_gpc()) {
$_POST['passwd'] = addslashes($_POST['passwd']);
$_POST['email'] = addslashes($_POST['email']);
$_POST['website'] = addslashes($_POST['website']);
$_POST['location'] = addslashes($_POST['location']);
}

$regdate = date('m d, Y');

$insert = "INSERT INTO users (
username,
password,
regdate,
email,
website,
location,
show_email,
last_login)
VALUES (
'".$_POST['uname']."',
'".$_POST['passwd']."',
'$regdate',
'".$_POST['email']."',
'".$_POST['website']."',
'".$_POST['location']."',
'".$_POST['show_email']."',
'Never')";

$add_member = $db_object->query($insert);

if (DB::isError($add_member)) {
die($add_member->getMessage());
}

$db_object->disconnect();
?>

<h1>Registered</h1>

<p>Thank you, your information has been added to the database,
you may now <a href="login.php" title="Login">log in</a>.</p>

<?php

} else { // if form hasn't been submitted

?>
<h1>Register</h1>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<table align="center" border="1" cellspacing="0" cellpadding="3">
<tr><td>Username*:</td><td>
<input type="text" name="uname" maxlength="40">
</td></tr>
<tr><td>Password*:</td><td>
<input type="password" name="passwd" maxlength="50">
</td></tr>
<tr><td>Confirm Password*:</td><td>
<input type="password" name="passwd_again" maxlength="50">
</td></tr>
<tr><td>E-Mail*:</td><td>
<input type="text" name="email" maxlength="100">
</td></tr>
<tr><td>Website:</td><td>
<input type="text" name="website" maxlength="150">
</td></tr>
<tr><td>Location</td><td>
<input type="text" name="location" maxlength="150">
</td></tr>
<tr><td>Show E-Mail?</td><td>
<select name="show_email">
<option value="1" selected="selected">Yes</option>
<option value="0">No</option></select>
</td></tr>
<tr><td colspan="2" align="right">
<input type="submit" name="submit" value="Sign Up">
</td></tr>
</table>
</form>

<?php

}

?>
</body>
</html>


db_connect.php


<?php

require_once 'DB.php';

$db_engine = 'mysql';
$db_user = 'XXXXXXX';
$db_pass = 'XXXXXXX';
$db_host = 'localhost';
$db_name = 'XXXXXXX';

$datasource = $db_engine.'://'.
$db_user.':'.
$db_pass.'@'.
$db_host.'/'.
$db_name;

$db_object = DB::connect($datasource, TRUE);

if(DB::isError($db_object)) {
die($db_object->getMessage());
}

$db_object->setFetchMode(DB_FETCHMODE_ASSOC);

include('check_login.php');

?>


check_login.php

<?php

/* check login script, included in db_connect.php. */

session_start();

if (!isset($_SESSION['username']) || !isset($_SESSION['password'])) {
$logged_in = 0;
return;
} else {

// remember, $_SESSION['password'] will be encrypted.

if(!get_magic_quotes_gpc()) {
$_SESSION['username'] = addslashes($_SESSION['username']);
}

// addslashes to session username before using in a query.
$qry = "SELECT password FROM users WHERE username = '".$_SESSION['username']."'";
$pass = $db_object->query($qry);

if(DB::isError($pass) || $pass->numRows() != 1) {
$logged_in = 0;
unset($_SESSION['username']);
unset($_SESSION['password']);
// kill incorrect session variables.
}

$db_pass = $pass->fetchRow();

// now we have encrypted pass from DB in
//$db_pass['password'], stripslashes() just incase:

$db_pass['password'] = stripslashes($db_pass['password']);
$_SESSION['password'] = stripslashes($_SESSION['password']);

//compare:

if($_SESSION['password'] == $db_pass['password']) {
// valid password for username
$logged_in = 1; // they have correct info
// in session variables.
} else {
$logged_in = 0;
unset($_SESSION['username']);
unset($_SESSION['password']);
// kill incorrect session variables.
}
}

// clean up
unset($db_pass['password']);

$_SESSION['username'] = stripslashes($_SESSION['username']);

?>

Can anyone help me?

Thanks

Driver01
02-09-2010, 12:04 PM
Stab in the dark as I can't see much wrong. remove the quotes:

if ($name_checkk=="1")

I presume thats the condition its breaking on?

pwalters09
02-09-2010, 12:21 PM
it is where the error is but that is not the error, but i now think it is a problem with the server because it works fine on another server :)

mattle
02-09-2010, 12:48 PM
Try running the query on the db directly...

(btw, you should always validate user-submitted data before putting it in a query...what If I logged in as:';DELETE FROM users; See manual for mysql_real_escape_string() for more info)


$qry = "SELECT username FROM users WHERE username = '".$_POST['uname']."'";
print_r($qry);
Now take the output of that print_r() and cut and paste it into your MySQL command line and examine the results...

pwalters09
02-09-2010, 02:01 PM
SQL injections do not work on the script :)

Login script


<?php

require_once ("libs.inc.php");
require ("lang/en.lang");
require 'backend/db_connect.php';

if($logged_in == 1) {
$smarty->display ("header.html");
$smarty->display ("errors/alreadyloggedin.html");
$smarty->display ("login.html");
$smarty->display ("footer.html");
die();
}

$smarty->display ("header.html");

if (isset($_POST['submit'])) { // if form has been submitted

/* check they filled in what they were supposed to and authenticate */
if(!$_POST['uname'] | !$_POST['passwd']) {
$smarty->display ("header.html");
$smarty->display ("errors/missingfield.html");
$smarty->display ("login.html");
$smarty->display ("footer.html");
die();
}

// authenticate.

if (!get_magic_quotes_gpc()) {
$_POST['uname'] = addslashes($_POST['uname']);
}

$qry = "SELECT username, password FROM users WHERE username = '".$_POST['uname']."'";
$check = $db_object->query($qry);

if (DB::isError($check) || $check->numRows() == 0) {
$smarty->display ("header.html");
$smarty->display ("errors/usernamenotexist.html");
$smarty->display ("login.html");
$smarty->display ("footer.html");
die();
}

$info = $check->fetchRow();

// check passwords match

$_POST['passwd'] = stripslashes($_POST['passwd']);
$info['password'] = stripslashes($info['password']);
$_POST['passwd'] = md5($_POST['passwd']);

if ($_POST['passwd'] != $info['password']) {
$smarty->display ("header.html");
$smarty->display ("errors/wrongpass.html");
$smarty->display ("login.html");
$smarty->display ("footer.html");
die();
}

// if we get here username and password are correct,
//register session variables and set last login time.

$date = date('m d, Y');

$qry = "UPDATE users SET last_login = '$date' WHERE username = '".$_POST['uname']."'";
$update_login = $db_object->query($qry);

$_POST['uname'] = stripslashes($_POST['uname']);
$_SESSION['username'] = $_POST['uname'];
$_SESSION['password'] = $_POST['passwd'];
$db_object->disconnect();

header('Location: members.php');

}else{

$smarty->display ("login.html");

}

$smarty->display ("footer.html");

?>


It is definately a server issue because it works on my SQL server, so I just have to reconfigure my other server :)

Try running the query on the db directly...

(btw, you should always validate user-submitted data before putting it in a query...what If I logged in as:';DELETE FROM users; See manual for mysql_real_escape_string() for more info)


$qry = "SELECT username FROM users WHERE username = '".$_POST['uname']."'";
print_r($qry);
Now take the output of that print_r() and cut and paste it into your MySQL command line and examine the results...

mattle
02-09-2010, 03:33 PM
SQL injections do not work on the script :)



Sorry, I overlooked your addslashes() calls. Typically, you would use a DBMS-specific function, however. From the addslashes() manual:

It's highly recommeneded to use DBMS specific escape function (e.g. mysqli_real_escape_string() (http://www.php.net/manual/en/mysqli.real-escape-string.php) for MySQL or pg_escape_string() (http://www.php.net/manual/en/function.pg-escape-string.php) for PostgreSQL)Also, Pear:: DB has been superceded by Pear:: MDB2 (http://pear.php.net/package/DB). Furthermore, MDB2 uses old reference assignments ($a =& $b) which raise E_STRICT errors in current versions of PHP, a reporting level that PHP6 will include in E_ALL, btw. I would recommend you modernize and use PDO (http://php.net/manual/en/book.pdo.php) if you need a driver-switchable DB library.

You also might want to look into using prepared statements anyway--in which most DB abstraction layers will not only safety any passed variables but DB-depending (including MySQL) can perform query optimization as well.

Either way, the meat of my post remains true. Execute the generated query at the DB command line and you'll find out what's going on.