SQLSTATE[HY093]: Invalid parameter number: parameter was not defined # - php

I am writing some code to interact with a login database on phpmyadmin through the following code.
However, I get the following error, it doesn't specify which line the error occurs at. It's been bugging me for 3 days, and my researches didn't lead to any solution. Just in case : SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
Can someone help me pinpoint the problem please?
Thank you in advance.
<?php
session_start();
$user_name = "test" ;
$user_password = "test";
/* Login to database */
$DB_name = "adaming_login_db";
$DB_user = "root";
$DB_pass = "";
$DB_host = "localhost";
try
{
$DB_con = new PDO("mysql:host={$DB_host};dbname={$DB_name}",$DB_user,$DB_pass);
$DB_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
echo $e->getMessage();
}
class USER
{
private $db;
public function __construct($DB_con)
{
$this->db = $DB_con;
}
public function login($user_name,$user_password)
{
try
{
$stmt = $this->db->prepare("SELECT * FROM login_info WHERE user_name = :$user_name AND user_password = :$user_password");
$stmt->execute(array(':user_name'=>$user_name, ':user_password'=>$user_password));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() > 0)
{
if($user_password == $userRow['user_password'] && $user_name == $userRow['user_name'] )
{
$_SESSION['user_session'] = $userRow['user_id'];
echo "Success";
return true;
}
else
{
echo "Failed";
return false;
}
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
}
$user = new USER($DB_con);
$user->login($user_name,$user_password);
?>

You need to remove dollar signs from your query. Change:
$stmt = $this->db->prepare("SELECT * FROM login_info WHERE user_name = :$user_name AND user_password = :$user_password");
to
$stmt = $this->db->prepare("SELECT * FROM login_info WHERE user_name = :user_name AND user_password = :user_password");

Related

Connection is not defined

I have the following code
<?php
$host = "localhost";
$dbname = "hawkI";
$user = "root";
$password = "";
$userExist = false;
$userIP = null;
$userHasFinish = null;
$userLastPage = null;
try {
$dbh = new PDO('mysql:host='.$host.';dbname='.$dbname, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
function getIPforBDD(){
return $_SERVER['REMOTE_ADDR'];
}
function UpdateUserProfile()
{
$requete = "SELECT * FROM users WHERE ip = ".getIPforBDD();
$result = $dbh->query($requete);
if($resultat->rowCount() == 0)
exit();
foreach($result as $ligne)
{
$userIP = $ligne['ip'];
$userhasFinish = $ligne['finish'];
$userLastPage = $ligne['lastPage'];
}
}
function CheckUserPosition()
{
UpdateUserProfile();
if(!$userExist)
AddUser();
return GetUserStatus();
}
function GetUserStatus()
{
$page;
if($userHasFinish)
$page = "end.php";
else
$page = $userLastPage;
return $page;
}
function AddUser()
{
$requete = "INSERT INTO users (ip, finish, lastPage) VALUES (".getIPforBDD().", ".false.", questionnaire_initial.php)";
$result = $dbh->query($requete);
}
function SavePageInBDD($page){
$requete = "UPDATE users SET lastPage = '.$page.' WHERE ip = ".getIPforBDD();
$result = $dbh->query($requete);
}
?>
But, I have a problem when I use it
( ! ) Notice: Undefined variable: dbh in C:\wamp64\www\HawkI\bdd.php
on line 66
I do not understand correctly how PHP work it's the first time I use it, but I tried to make
global $dbh = new PDO('mysql:host='.$host.';dbname='.$dbname, $user, $password);
That doesn't work too.
Also, it seems that value that are put outside of functions are not global like it would be in js, how can I make something accessible from everywhere (like file that include that file)
Thanks
Better way would be to do something like this:
function getDB(){
$dbh = null;
try {
$dbh = new PDO('mysql:host='.$host.';dbname='.$dbname, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
return $dbh;
}
And than in your functions do this:
function AddUser()
{
$dbh = getDB();
if(!is_null($dbh)){
$requete = "INSERT INTO users (ip, finish, lastPage) VALUES (".getIPforBDD().", ".false.", questionnaire_initial.php)";
$result = $dbh->query($requete);
}
}
To use $dbh inside a function, you need to include global keyword inside the function scope.
You can find the global keyword explanation here http://php.net/manual/en/language.variables.scope.php#language.variables.scope.global
function AddUser()
{
global $dbh;
$requete = "INSERT INTO users (ip, finish, lastPage) VALUES (".getIPforBDD().", ".false.", questionnaire_initial.php)";
$result = $dbh->query($requete);
}
You may use like this
$host = "localhost";
$dbname = "hawkI";
$user = "root";
$password = "";
$userExist = false;
$userIP = null;
$userHasFinish = null;
$userLastPage = null;
$dbh = NULL;
function db () {
try {
if ($GLOBALS['dbh']===NULL){
$GLOBALS['dbh'] = new PDO('mysql:host='.$host.';dbname='.$dbname, $user, $password);
}
return $GLOBALS['dbh'];
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}
function SavePageInBDD($page){
$dbh = db();
$requete = "UPDATE users SET lastPage = '.$page.' WHERE ip = ".getIPforBDD();
$result = $dbh->query($requete);
}

PHP & SQL : Throws fatal error when $_Request are filled

I just started learning, but why is it that when I don't fill the info in the URL it connects to the database, but when I fill it in it gives a fatal error?
Ex. when I type
http://ehlien.com/php/signup.php?firstname=Mohamed&lastname=Mohamed&username=alpha&email=mohamed.mohd#hotmail.com&password=mohamed
It throws:
Fatal error: Uncaught exception 'Exception' with message 'Failed to connect to database' in /home/torokage/public_html/php/classes/DB.class.php:22 Stack trace: #0 /home/torokage/public_html/php/signup.php(35): DB->connect() #1 {main} thrown in /home/torokage/public_html/php/classes/DB.class.php on line 22
But when I type
http://ehlien.com/php/signup.php
It gives me my error I set up:
{"status":"400","message":"Please fill in the missing information..."}
I don't have a lot of knowledge on php and mysql, just trying to figure it out on my own and through some tutorials but I can't get this to work to continue...
CODE, signup.php:
<?php
require('classes/User.class.php');
require('classes/DB.class.php');
require('classes/Connection.class.php');
$firstname = null;
$lastname = null;
$username = null;
$email = null;
$password = null;
$repassword = null;
if (empty($_REQUEST["firstname"]) ||
empty($_REQUEST["lastname"]) ||
empty($_REQUEST["username"]) ||
empty($_REQUEST["email"]) ||
empty($_REQUEST["password"]))
{
$returnError["status"] = "400";
$returnError["message"] = "Please fill in the missing information...";
echo json_encode($returnError);
return;
}
$firstname = htmlentities($_REQUEST["firstname"]);
$lastname = htmlentities($_REQUEST["lastname"]);
$username = htmlentities($_REQUEST["username"]);
$email = htmlentities($_REQUEST["email"]);
$password = md5(htmlentities($_REQUEST["password"]));
$DB = new DB(Connection::$db_host, Connection::$db_name, Connection::$db_user, Connection::$db_pass);
$DB->connect();
$checkUsername = $DB->checkIfUsernameExists($username);
if (!empty($checkUsername))
{
$returnError["status"] = "400";
$returnError["message"] = "That username has already been taken. Please try again...";
echo json_encode($returnError);
return;
}
$checkEmail = $DB->checkIfEmailExists($email);
if (!empty($checkEmail))
{
$returnError["status"] = "400";
$returnError["message"] = "That email has already been taken. Please try again...";
echo json_encode($returnError);
return;
}
$signUpUser = $DB->signUpUser($firstname, $lastname, $username, $email, $password);
if ($signUpUser)
{
$userDetails = $DB->getUserDetails($username);
$user["status"] = "200";
$user["message"] = "Success! You have now been registered.";
$user["ID"] = $userDetails["ID"];
$user["firstname"] = $userDetails["firstname"];
$user["lastname"] = $userDetails["lastname"];
$user["username"] = $userDetails["username"];
$user["email"] = $userDetails["email"];
}
else
{
$user["status"] = "400";
$user["message"] = "Sorry, this account has already been taken. Please try again...";
}
$DB->disconnect();
echo json_encode($user);
?>
DB.class.php
<?php
class DB {
protected $db_host = null;
protected $db_name = null;
protected $db_user = null;
protected $db_pass = null;
protected $db_conn = null;
protected $db_resu = null;
// Constructor
function __construct($db_host, $db_name, $db_user, $db_pass) {
$this->db_host = $db_host;
$this->db_name = $db_name;
$this->db_user = $db_user;
$this->db_pass = $db_pass;
}
// Connect to database
public function connect() {
$this->db_conn = new MySQLi($this->db_host, $this->db_name, $this->db_user, $this->db_pass);
if (mysqli_connect_errno())
throw new Exception("Failed to connect to database");
$this->db_conn->set_charset("utf8");
}
// Disconnect from database
public function disconnect() {
if ($this->db_conn != null)
$this->db_conn->close();
}
// Check if username exists
public function checkIfUsernameExists($username) {
$result = mysql_query("SELECT USERNAME FROM USERS WHERE EMAIL = '$username'");
if(mysql_num_rows($result) == 0){
return false;
} else {
return true;
}
}
// Check if email exists
public function checkIfEmailExists($email) {
$result = mysql_query("SELECT EMAIL FROM USERS WHERE EMAIL = '$email'");
if(mysql_num_rows($result) == 0){
return false;
} else {
return true;
}
}
// Get user informationd
public function getUserDetails($username) {
$command = mysql_query("SELECT * FROM USERS WHERE USERNAME = '$username'");
$value = array();
$result = $this->db_conn->query($command);
if ($result != null && (mysqli_num_rows($result) >= 1)) {
$row = $result->fetch_array(MYSQLI_ASSOC);
if (!empty($row)) {
$value = $row;
}
}
return $value;
}
// Sign up new user
public function signUpUser($firstname, $lastname, $username, $email, $password) {
$command = "INSERT INTO USERS SET FIRSTNAME=?, LASTNAME=?, USERNAME=?, EMAIL=?, PASSWORD=?";
$sql = $this->db_conn->prepare($command);
if (!$sql)
throw new Exception($sql->error);
$sql->bind_param("sssss", $firstname, $lastname, $username, $email, $password);
$value = $sql->execute();
return $value;
}
}
?>
When you didn't use any value or parameters, it's showing the error set up by you because it couldn't pass the validation step set up by you.
But when you are passing the values or parameters, it passes your validation and tries to connect with the database first as per this code of yours:
$DB = new DB(Connection::$db_host, Connection::$db_name, Connection::$db_user, Connection::$db_pass);
$DB->connect();
But it throws an exception: Failed to connect to database meaning that your database connection credentials are wrong and thus, can not connect with the database.
You may get more friendly error message by changing inside the public function connect() of DBclass to this:
// Connect to database
public function connect() {
try {
$this->db_conn = new MySQLi($this->db_host, $this->db_name, $this->db_user, $this->db_pass);
$this->db_conn->set_charset("utf8");
} catch (Exception $e ) {
echo "Failed to connect to database";
echo "Error: " . $e->message; // remove when in live...
}
}

Register user PHP

I am trying to create a PHP script to register users. It connects my xCode with a mySQL database.
I am getting the following error:
8ee52684907bd42381d94f74f3c4d321b17c5285 Notice: Trying to get
property of non-object in
/Applications/XAMPP/xamppfiles/htdocs/SwiftAppAndMYSQL/db/MySQLDAO.php
on line 76
Fatal error: Uncaught exception 'Exception' in
/Applications/XAMPP/xamppfiles/htdocs/SwiftAppAndMYSQL/db/MySQLDAO.php:76
Stack trace: #0
/Applications/XAMPP/xamppfiles/htdocs/SwiftAppAndMYSQL/scripts/registerUser.php(63):
MySQLDAO->registerUser('email', 'gui', 'Maia', '8ee52684907bd42...',
'\x99\x99S'eXqs\xE0\xC4\x80[\xB1\x07y...') #1 {main} thrown in
/Applications/XAMPP/xamppfiles/htdocs/SwiftAppAndMYSQL/db/MySQLDAO.php
on line 76
This is my registerUser script
<?php
require ("../db/MySQLDAO.php");
require ("../db/Conn.php");
$returnValue = array();
if (
empty($_REQUEST["userEmail"]) ||
empty($_REQUEST["userPassword"]) ||
empty($_REQUEST["userFirstName"]) ||
empty($_REQUEST["userLastName"])) {
$returnValue["status"] = "400";
$returnValue["message"] = "Missing required information";
echo json_encode($returnValue);
return;
}
$userEmail = htmlentities($_REQUEST["userEmail"]);
$userPassword = htmlentities($_REQUEST["userPassword"]);
$userFirstName = htmlentities($_REQUEST["userFirstName"]);
$userLastName = htmlentities($_REQUEST["userLastName"]);
$salt = openssl_random_pseudo_bytes(16);
$secure_password = sha1($userPassword . $salt);
echo $secure_password;
$dao = new MySQLDAO(Conn::$dbhost, Conn::$dbuser, Conn::$dbpass, Conn::$dbname);
$dao->openConnection();
$userDetails = $dao->getUserDetails($userEmail);
if(!empty($userDetails))
{
$returnValue["status"] = "400";
$returnValue["message"] = "Please choose different email address";
echo json_encode($returnValue);
return;
}
$result = $dao->registerUser($userEmail, $userFirstName, $userLastName, $secure_password, $salt);
if ($result) {
$userDetails = $dao->getUserDetails($userEmail);
$returnValue["status"] = "200";
$returnValue["message"] = "Sucessfully registered new user";
$returnValue["userId"] = $userDetails["user_id"];
$returnValue["userFirstName"] = $userDetails["first_name"];
$returnValue["userLastName"] = $userDetails["last_name"];
$returnValue["userEmail"] = $userDetails["email"];
} else {
$returnValue["status"] = "400";
$returnValue["message"] = "Could not register user with provided information";
}
$dao->closeConnection();
echo json_encode($returnValue);
?>
My DAO object goes bellow:
<?php
class MySQLDAO {
private $dbpassword;
var $dbhost = null;
var $dbuser = null;
var $dbpass = null;
var $conn = null;
var $dbname = null;
var $result = null;
function __construct($dbhost, $dbuser, $dbpassword, $dbname) {
$this->dbhost = $dbhost;
$this->dbuser = $dbuser;
$this->dbpass = $dbpassword;
$this->dbname = $dbname;
}
public function openConnection() {
$this->conn = new mysqli($this->dbhost, $this->dbuser, $this->dbpass, $this->dbname);
if (mysqli_connect_error())
throw new Exception("Could not stabilish connection with database");
$this->conn->set_charset("utf8");
}
public function closeConnection() {
if ($this->conn != null)
$this->conn->close();
}
public function getUserDetails($email){
$returnValue = array();
$sql = "select * from users where email= '".$email."'";
$result = $this->conn->query($sql);
if ($result != null && (mysqli_num_rows($result) >= 1 )){
$row = $result->fetch_array(MYSQLI_ASSOC);
if (!empty($row)){
$returnValue = $row;
}
}
return $returnValue;
}
public function registerUser($email, $first_name, $last_name, $password, $salt) {
$sql = "insert unto users set email=?, first_name=?, last_name=?, user_password=?, salt=?";
$statement = $this->conn->prepare($sql);
if (!$statement){
throw new Exception($statement->error);
}
$statement->bind_param("sssss", $email, $first_name, $last_name, $password, $salt);
$returnValue = $statement->execute();
return $returnValue;
}
}
My connection class
<?php
class Conn {
public static $dbhost = "localhost";
public static $dbuser = "root";
public static $dbpass = "";
public static $dbname = "SwiftApp";
}
?>
There is one possible error I can spot:
This SQL query has a typo, it should be into, not unto, resulting in a syntax error:
$sql = "insert unto users set email=?, first_name=?, last_name=?, user_password=?, salt=?";
$statement = $this->conn->prepare($sql);
The syntax error results in $mysqli->prepare() returning false.
If this is the case the next block can't work.
if (!$statement){
throw new Exception($statement->error);
}
If $statement is false, it isn't an object, so $statement->error doesn't work and the error Trying to get property of non-object is thrown.
This should report the desired result:
/// corrected query
$sql = "insert into users set email=?, first_name=?, last_name=?, user_password=?, salt=?";
$statement = $this->conn->prepare($sql);
if (!$statement){
/// corrected error reporting
throw new Exception($this->conn->error);
}

Function returns boolean not string

What I want is to return MYSQL query in a array however my code returns a bool(true).
Here is the code from code.php
require('model.php');
$id = $_POST['id'];
$password = $_POST['password'];
$user = new user();
$row = $user->check_user($id, $password);
var_dump($row);
Here is the code from model.php
class config {
public $dbhost = "localhost";
public $dbuser = "root";
public $dbpass = "";
public $dbused = "dbname";
function dbconn() {
$conn = mysqli_connect($this->dbhost,$this->dbuser,$this->dbpass,$this->dbused);
if(mysqli_connect_errno()) {
printf("Connection failed: " . mysqli_connect_error());
exit();
}
return $conn;
}
}
class user {
function check_user($id, $pass) {
$config = new config();
$conn = $config->dbconn();
$query = $conn->prepare("SELECT id, password, status FROM e_users WHERE id = ? AND password = ?");
$query->bind_param('is', $id, $pass);
try {
$query->execute();
return $query->fetch();
} catch(PDOException $e) {
die($e->getMessage());
}
}
}
I think the problem is in the $query->fetch(); because I tried return 'test'; and it works fine. Even return an array works fine.
Can anyone help me?
As The Blue Dog pointed out, fetch() returns a status flag, not the row itself. But fetch_assoc() will return a row.
Have a look here:
http://php.net/manual/en/mysqli-stmt.fetch.php
If you work with fetch, you need to bind the variables:
$stmt->bind_result($mySelectedValue_1, $mySelectedValue_2);
Here are examples with fetch_assoc():
http://php.net/manual/de/mysqli.quickstart.prepared-statements.php
So this should work fine:
$row = $res->fetch_assoc();

PHP Select with PDO Call to a member function prepare() on a non-object error

I'm getting a Call to a member function prepare() on a non-object error in my PHP when using PDO to select data that was sent via an AJAX call.
Searching around on StackOverflow I've found many answers to this error, but none work to fix my problem.
The weird part is that the other PHP files use the same PDO calls and work successfully, but this one is giving me the non-object error only.
To note, the PDO connection is identical to the other pages where it works, so I know that's not causing the problem.
Also, I have tested that the AJAX data sent is being received, and that is working too.
PHP Code
$mysql_user = "NotTelling";
$mysql_password = "DefinatelyNotThis";
try
{
$dbh = new PDO("mysql:host=somehost;dbname=somename", $mysql_user, $mysql_password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$username = $_POST['username'];
$inPword = $_POST['password'];
$lat = $_POST['lat'];
$lon = $_POST['lon'];
$loggedin = "";
$password_hash = "";
$loggedinstatus = "";
$pts = "";
function getLoginInfo()
{
$sth = $dbh -> prepare('SELECT pword, loggedin, points FROM login WHERE uname = :uname');
$sth->bindParam(':uname', $username, PDO::PARAM_STR);
while($row = $sth->fetch(PDO::FETCH_ASSOC))
{
echo $row['pword'];
echo $row['loggedin'];
echo $row['points'];
}
$password_hash = $fetch['pword'];
$loggedinstatus = $fetch['loggedin'];
$pts = $fetch["points"];
if($password_hash === null || $loggedinstatus === null || $pts === null)
{
die(json_encode(array("message" => "none")));
}
else
{
return "more";
}
}
function checkLoginCreds()
{
if(crypt($inPword, $password_hash) === $password_hash)
{
switch($loggedinstatus)
{
case "no":
$sel = $dbh->prepare("UPDATE login SET loggedin='yes' WHERE uname = ?");
$sel->execute(array($username));
return "AllGood";
break;
defaut:
return "alreadyin";
break;
}
}
else
{
return "BadLogin";
}
}
if(getLoginInfo() === "more")
{
echo json_encode(array("message" => checkLoginCreds()));
}
getLoginInfo();
}
catch(PDOException $e)
{
echo $e->getMessage();
file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
}
Finally, here's the output when I var_dump() the PDO connection.
object(PDO)#1 (0) {}
For this to work, you need to use the global variable scope, explained here: http://php.net/manual/en/language.variables.scope.php
$mysql_user = "NotTelling";
$mysql_password = "DefinatelyNotThis";
try
{
$dbh = new PDO("mysql:host=somehost;dbname=somename", $mysql_user, $mysql_password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$username = $_POST['username'];
$inPword = $_POST['password'];
$lat = $_POST['lat'];
$lon = $_POST['lon'];
$loggedin = "";
$password_hash = "";
$loggedinstatus = "";
$pts = "";
function getLoginInfo()
{
global $dbh, $username, $password_hash, $loggedinstatus, $pts;
$sth = $dbh -> prepare('SELECT pword, loggedin, points FROM login WHERE uname = :uname');
$sth->bindParam(':uname', $username, PDO::PARAM_STR);
while($row = $sth->fetch(PDO::FETCH_ASSOC))
{
echo $row['pword'];
echo $row['loggedin'];
echo $row['points'];
}
$password_hash = $fetch['pword'];
$loggedinstatus = $fetch['loggedin'];
$pts = $fetch["points"];
if($password_hash === null || $loggedinstatus === null || $pts === null)
{
die(json_encode(array("message" => "none")));
}
else
{
return "more";
}
}
function checkLoginCreds()
{
global $dbh, $inPword, $password_hash, $loggedinstatus, $username;
if(crypt($inPword, $password_hash) === $password_hash)
{
switch($loggedinstatus)
{
case "no":
$sel = $dbh->prepare("UPDATE login SET loggedin='yes' WHERE uname = ?");
$sel->execute(array($username));
return "AllGood";
break;
defaut:
return "alreadyin";
break;
}
}
else
{
return "BadLogin";
}
}
if(getLoginInfo() === "more")
{
echo json_encode(array("message" => checkLoginCreds()));
}
getLoginInfo();
}
catch(PDOException $e)
{
echo $e->getMessage();
file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
}
But this can get messy very quickly.
I suggest you put the variables in an array or using OOP for a more robust solution: http://php.net/manual/en/language.oop5.php
This is how you can define it in a class..
class someClass {
private $db;
public function __construct(){
$this->dbconnect();
}
private function dbconnect() {
try { //try connection
$dbh = new PDO('mysql:host=localhost;dbname=somenane', 'usernane', 'pass');
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->dbh = $dbh;
} catch (Exception $e) { //connection failed
die("Oh no! It seems we took too long to respond");
}
}
public function getLoginInfo() {
$sth = $this->dbh->prepare('SELECT pword, loggedin, points FROM login WHERE uname = :uname');
$sth->bindParam(':uname', $username, PDO::PARAM_STR);
//cont the code
}
}
Not sure if it's good enough..but it will work..

Categories