This is something that worked a few months ago and now I don't know what I messed up when I made the mistake of trying to migrate it to a new host. It's nothing but a registration and login module and I'm trying to have a tight focus on security from the start.

"Fatal error: Call to a member function prepare() on a non-object in /home/username/domain.net/register.php on line 55"

First, my connection:

function db_connect(){
	$dbh = new PDO("mysql:host=mysql.domain.net;dbname=database", "user", "password");
	global $dbh;
	return ($dbh);
	$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	}

Then the script that dies when it's checking to see if the email address has already been used:

<?php
session_start();
include_once 'functions.php';
if (empty($_POST['token'])){
	if (empty($_SESSION['token'])){
		$token = md5(uniqid(rand(), true));
		session_register('token');
		$_SESSION['token'] = $token;
		}
	include 'join_form.php';
	die();
	}
elseif ($_POST['token'] != $_SESSION['token']){
	$token = md5(uniqid(rand(), true));
	session_register('token');
	$_SESSION['token'] = $token;
	include 'join_form.php';
	die();
	}
elseif ($_POST['token'] == $_SESSION['token']){
	$a = preg_replace('[^0-9]', '', $_REQUEST["x"]);
	$b = preg_replace('[^0-9]', '', $_REQUEST["y"]);
	$answer = preg_replace('[^0-9]', '', $_POST["math"]);
	$email_address = $_POST['email_address'];
	$username = preg_replace('[^A-Za-z0-9]', '', $_POST['username']);
	$ref = $_SESSION['referrer'];
	if((!$username) || (!$email_address)){
		echo 'You did not submit the following required information: <br /><br />';
		if(!$email_address){
			echo "We need your email address to send your password (which you can change when you log in).  This information is not shared unless you choose to do so later.<br /><br />";
			}
		if(!$username){
			echo "You need a user name.  This is the name that will be publicly used when you leave comments etc.  It doesn't have to be your real name.<br /><br />";
			}
		include 'join_form.php';
		die();
		}
	if($_SERVER['REQUEST_METHOD'] != "POST"){
		include 'head.php';
		echo "The server didn't appreciate your REQUEST.<br />";
		include 'join_form.php';
		die();
		}
	if (filter_var($email_address, FILTER_VALIDATE_EMAIL)) {
		contains_newlines($a);
		contains_newlines($b);
		contains_newlines($email_address);
		contains_newlines($username);
		contains_bad_str($a);
		contains_bad_str($b);
		contains_bad_str($email_address);
		contains_bad_str($username);
		include_once 'dbcnx.php';
		$dbh = db_connect();
		$sth = $dbh->prepare ("SELECT email_address FROM users WHERE email_address = :email");

// the line above is where my error seems to be :(

		$sth->bindParam(':email', $email_address, PDO::PARAM_STR);
		$sth->execute ();
		$count = 0;
		while ($row = $sth->fetch ()){
			$count++;
			}
		$dbh = NULL;
		$email_check = $count;
		include_once 'dbcnx.php';
		$dbh = db_connect();
		$sth = $dbh->prepare ("SELECT username FROM users WHERE username = :user");
		$sth->bindParam(':user', $username, PDO::PARAM_STR);
		$sth->execute ();
		$count = 0;
		while ($row = $sth->fetch ()){
			$count++;
			}
		$dbh = NULL;
		$username_check = $count;
		if(($email_check > 0) || ($username_check > 0)){
			include 'head.php';
			echo "Please fix the following errors: <br />";
			if($email_check > 0){
				echo "That email address has already been used.<br />";
				unset($email_address);
				}
			if($username_check > 0){
				echo "The username you have selected is already taken. Please choose a different one.<br />";
				unset($username);
				}
			}
		if (intval($a) + intval($b) == intval($answer)){
			$random_password = makeRandomPassword();
			$db_password = md5($random_password);
			$ref = $_SESSION['referrer'];
			include_once 'dbcnx.php';
			$dbh = db_connect();
			$sth = $dbh->prepare ("INSERT INTO users (email_address, username, password, signup_date, referrer) VALUES(:email, :user, :pass, now(), :ref)");
			$sth->bindParam(':email', $email_address, PDO::PARAM_STR);
			$sth->bindParam(':user', $username, PDO::PARAM_STR);
			$sth->bindParam(':pass', $db_password, PDO::PARAM_STR);
			$sth->bindParam(':ref', $ref, PDO::PARAM_STR);
			$sth->execute ();
			$sth = $dbh->prepare ("SELECT * FROM users WHERE username=:name AND password=:pass");
			$sth->bindParam(':name', $username, PDO::PARAM_STR);
			$sth->bindParam(':pass', $db_password, PDO::PARAM_STR);
			$sth->execute ();
			$count = 0;
			while ($row = $sth->fetch()){
				$count++;
				}
			if($count != 1){
				echo '<br /><br />There has been an error creating your account. Please try again. If you continue to receive this error, <a href="contact.php">contact admin</a>.<br />';
				include 'join_form.php';
				die();
				}
			else{
				$userid = $dbh->lastInsertId();
				$subject = "Registration information";
				$message = "Dear $username,
				
			Thank you for registering! You are two steps away from logging in and accessing the site. To activate your registration, please click on or paste the following URL into your browser's address bar: http://domain.net/index.php?p=activate&id=$userid&code=$db_password

			Once you activate, you will be able to login with the following information:

			Username: $username
			Password: $random_password 
			
			Please save this information.  Your password is encrypted before it's stored in our database, we can't read nor decrypt it for you.  Don't worry, you can change it later.

			Thanks!
			-tyop-

			This is an automated response, please do not reply."; 
				mail($email_address, $subject, $message, "From: tyop<admin@tyop.domain.net>\n X-Mailer: PHP/" . phpversion());
				echo 'An activation link and your login info have been sent to the address you provided.  Please check your inbox and follow the instructions.  If you don\'t see a message in your inbox, please check your junk/spam folder(s).  You can close this window.';
				}
			}
		else {
			echo "Sorry, that wasn't the right answer for human verification.  It's ok to use a calculator.<br />";
			include 'join_form.php';
			die();
			}
		}
	else {
		echo 'Please enter your email address correctly.';
		include 'join_form.php';
		die();
		}
	}
die();
?>

and just in case I've gone blind, here's the relevant form:

<?php
session_start();
$token = $_SESSION['token'];
$x = rand(0,23);
$y = rand(0,23);
echo '<form action="index.php?p=register&amp;x=' . $x . '&amp;y=' . $y . '" method="post" name="register">'; 
?>
<br />
	<input type="hidden" name="token" id="token" value="<?php echo $token; ?>" />
	<table>
		<tr>
			<td>
				Email Address
			</td>
			<td>
				<input id="email_address" name="email_address" maxlength="32" />
			</td>
		</tr>
		<tr>
			<td>
				Username
			</td>
			<td>
				<input id="username" name="username" maxlength="23" />
			</td>
		</tr>
		<tr>
			<td>
<?php 
echo "What is " . $x . "+" . $y . "? ";
?>
			</td>
			<td>
				<input class="formstuff" type="text" name="math" id="math" size="5" maxlength="3"><br />
			</td>
		</tr>
		<tr>
			<td>
				&nbsp;
			</td>
			<td>
				<input type="submit" value="register" />
			</td>
		</tr>
	</table>
</form>

Plz r 2 b helping of I :D

Recommended Answers

All 8 Replies

I'm guessing that your db connection is failing. Have you verified it?

I can connect with the same credentials via phpmyadmin. I've checked on the host's control panel and I'm using the correct hostname (it's not localhost), the hosts allowed access are correct, database name, database user and password are all correct. If it was an issue connecting to the database then I would expect a different error.

I have an idea and will feel foolish if this is the issue. I'll try manually adding the first user via phpmyadmin then see if the registration form will work after that. I'm sure I'll have more problems though lol. It's been months since I've been able to write code, stupid illness and meds.

Nope, that didn't work.

Add

try {
    $dbh = new PDO( ... );
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

just to be sure.

Curious why are you making $dbh global and also returning it from the function. That seems redundant and prone to causing some confusing behavior later.

Just to make sure, I wrote a short form and script where I can manually enter host, user, pass, and db name and it verifies that I can connect just fine. The user has full privileges as well. I also verified that $email_address isn't null, I can echo it just before the line that's giving me the error.

LOL! Thank you, it was the stupid redundancy. I didn't even think of nor notice that. It's always the weird little junk that catches me. I'm not even sure how that got in there, I think my girlfriend was trying to adapt some of it for her own things and she saved over my stuff. We are both trying to get out of certain old habits and I'm glad I didn't learn too much of the wrong way before learning the right way.

Also, thank you for the reminder to use try/catch, it's something I tend to forget.

Glad you got it sorted.

Thank the flying spaghetti monster for you, Ezzaral. I've been here for quite a while, years if you include my time as just a guest. Many of your responses to others have helped me immensely and set me on the right path. You are as helpful as James Golick, competent as Joe Damato, and as nice understanding as Gina Trapani.

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.