I'm trying to use this script to see if there's a registered using in my database, but I'm having trouble on line 6. I keep getting the error:
Fatal error: Call to a member function bind_param() on a non-object in
-redacted-/check_login.php on line 6
I'm stumped as to why it's failing, because I have a similar statement working on the create user function.
<?php
ini_set('display_errors', 'On');
$db = new mysqli("localhost", "root", "-redacted-", "-redacted-");
$query = $db->prepare("SELECT user FROM users WHERE username = ? AND password = ?");
$query->bind_param('ss', $_POST['username'], md5($_POST['password']));
$query->execute();
$query->bind_result($result);
$query->fetch();
if($result->num_rows == 1) {
session_start();
$_SESSION['user'] = $_POST['username'];
header("Location: 10.0.0.15/index.php");
}
?>
This is usually caused by referencing a non-existant column/table in your database schema. Hence why the prepared is the root cause of this error.
What you should do, is check over your query. Making sure you are:
not using reserved mysql keywords
referencing columns/tables that
exist within the schema
There are no syntax errors within your SQL
Query
Related
I wrote my code as simple as possible to make a simple login, because its my first time working with SQLite3 databases.
Here is my code:
<?php
$db = new SQLite3("FirstDatabase.db");
if (isset($_POST['login'])) {
$username = $_POST['user'];
$password = $_POST['pass'];
$query = $db->prepare("SELECT COUNT(`id`) FROM data WHERE `username` = '$username' AND `password` = '$password'");
$query->execute();
$count = $query->fetchColumn();
if($count = 1){
echo "Welcome $username!";
} else {
echo "Wrong credentials";
}
}
?>
I'm really confused why this is not working.. I updated all the extensions etc.
I know this is vulnerable to pretty much every type of attack, but I'm just trying to figure out the SQLite3 database connection.
Thanks! :)
This is the Error I get btw:
Fatal error: Uncaught Error: Call to undefined method SQLite3Stmt::fetchColumn() in C:\XAMPP\htdocs\PHP-Login\index.php:41 Stack trace: #0 {main} thrown in C:\XAMPP\htdocs\PHP-Login\index.php on line 41
The SQL is vulnerable to SQL injection which could be devastating to your database and your system and your health. First and foremost you should change the select to a parametrized query.
There are very good examples in the doc for using a parametrized query and binding the values, not to mention a ton of resource on this site.
The error is telling you that that there is not method fetchColumn() for a SQLite3Stmt object. The PHP: SQLite3Stmt doc confirms that. It is a method on the PDO database extension.
I was trying to validate if the username and email in my users table. The validation is working if the username or email is existing in the table it will not be stored but after the submission I only see a white screen in my browser and when I check the server logs I got this error.
PHP Fatal error: Uncaught Error: Call to undefined method
mysqli::mysqli_num_rows() in
/var/www/html/NutriCare/signup.php:86\nStack trace:\n#0 {main}\n
thrown in /var/www/html/NutriCare/signup.php on line 86
Is there something wrong in my code in database connection?
Here is the code in my config.php
<?php
$servername = "localhost";
$username = "root";
$password = "";
$db = "db";
$conn = new mysqli($servername, $username, $password, $db);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
?>
Here is the code where I validate the username and email in my signup.php and included the config.php file here
<?php
require 'config.php';
$query = "SELECT username FROM users WHERE username='$username'";
$result = mysqli_query($conn, $query);
$query2 = "SELECT email FROM users WHERE email='$email'";
$result2 = mysqli_query($conn, $query2);
if ($conn->mysqli_num_rows($result) != 0) {
?>
<script>
sweetAlert("Error!", "Username already exist!", "error");
return false;
</script>
<?php
}
if ($conn->mysqli_num_rows($result2) != 0) {
?>
<script>
sweetAlert("Error!", "Email address already exist!", "error");
return false;
</script>
<?php
}
?>
But when I remove this code to validate the email and the username the processing of storing data works with no errors.
I had included the $conn->close(); code in the end of the php file I just posted the code I put when I encountered the error.
Looking for help.
Thanks in advance.
Both of your queries to check if a row exist are incorrect.
if ($conn->mysqli_num_rows($result) != 0)
^^^^^^^
and
if ($conn->mysqli_num_rows($result2) != 0)
^^^^^^^
You don't pass the connection variable for a result set (from a query), you use the variable(s) from the query's (successful) results only.
Modify your code to read as:
if (mysqli_num_rows($result) != 0)
// ^^^^^^^ $result is all you need here
and
if (mysqli_num_rows($result2) != 0)
// ^^^^^^^^ $result2 is all you need here
NOTE: If the != logical operator does not work, use > 0 instead. The != 0 could throw a false positive.
You could also do this in one query by using the logical OR or AND operators. But, this could be out of the scope of the question.
Bear in mind that your code is open to an SQL injection. Use a prepared statement:
https://en.wikipedia.org/wiki/Prepared_statement
You can also view one of my answers that contain a few prepared statement methods:
check if row exists with mysql
Check for errors on the PHP and MySQL/query side also.
References:
http://php.net/mysqli_error
http://php.net/manual/en/function.error-reporting.php
Reference on PHP's mysqli_num_rows():
http://php.net/manual/en/mysqli-result.num-rows.php
(Disclaimer)
I provided this answer for support on the PHP/MySQL part and cannot offer support on the use of the SweetAlert script you are using in conjunction with this.
I have a table called candidates with some fields. The table contains a column named "keypass" which is the same for all users and is set as default. Using prepared statement I'm trying to first capture the value for key pass (which is the same for this example) and compare it to the user input.
the connection
<?php
$dbServerName = "localhost";
$dbUserName = "root";
$dbPassword = "";
$dbName = "candidateDB";
$conn = mysqli_connect($dbServerName,$dbUserName,$dbPassword,$dbName);
here is my code:
$stm_keypass = $conn ->prepare ("SELECT * FROM candidates WHERE keypass = ?");
$stm_keypass -> bind_param("s", $keypass);
$sql_keypass = $stm_keypass->execute();
when I run the script I get this error "Fatal error: Call to a member function bind_param() on a non-object" what is the issue? thanks
table here
"Fatal error: Call to a member function bind_param() on a non-object" here would mean your $stm_keypass was likely not created properly, and is thus not an object. Check out the docs on how to handle error detection of prepared statements and go from there.
I'm reaching out after hours of fruitlessly trying to fix a small section of code that just doesnt seem to work regardless of how i try to fetch the value and store.
I will admit I'm not the most experienced and hoping it is a small error on my part that can be easily spotted by someone with more expertise.
All other functions work as expected and fetch all the required value except one, With s the member_id field. This is a linked ID from another table (companies) however in test query the statement works fine.
Whole Code Snippet
<?php
//Error reporting - DEV ONLY
error_reporting(E_ALL);
ini_set('display_errors', 'on');
//New Connection
$mysqli = new mysqli('localhost', 'USER', 'PASSWORD', 'DATABASE');
//Connection Verification
if ($mysqli->connect_errno) {
printf("Connection Failure: %s\n", $mysqli->connect_error);
exit();
}
//Start Session and assign POST values
session_start();
$username = $_POST['username'];
$password1 = $_POST['password'];
//Query prepare, execution and bind
$stmt = $mysqli->prepare("SELECT password FROM user WHERE username='$username'");
$stmt -> execute();
$stmt -> bind_result($result);
/* Fetch the value */
$stmt -> fetch();
/* Close statement */
$stmt -> close();
//Verify password match and direct user according to result
if(password_verify($password1, $result))
{
$stmt = $mysqli->prepare("SELECT member_id FROM user WHERE username='$username'");
$stmt -> execute();
$stmt -> bind_result($company);
$_SESSION['loggedin'] = true;
$_SESSION['username'] = $username;
$_SESSION['company'] = $company;
Header("Location: home.php");
}else{
sleep(5);
Header("Location: index.php");
}
$mysqli->close();
?>
Suspected Issue Code Snippet
if(password_verify($password1, $result))
{
$stmt = $mysqli->prepare("SELECT member_id FROM user WHERE username='$username'");
$stmt -> execute();
$stmt -> bind_result($company);
$_SESSION['loggedin'] = true;
$_SESSION['username'] = $username;
$_SESSION['company'] = $company;
Header("Location: home.php");
}else{
sleep(5);
Header("Location: index.php");
}
Thank you in advance for your help!
EDIT: The issue is, there is no output from:
SELECT member_id FROM user WHERE username='$username
However in a direct query with MySQL it works so feel its a binding issue. this should be bound to $_SESSION['company'].
The other answer is somewhat examplary.
As the question is going to be closed anyway, I'd take a liberty to comment the other answer.
change the name of your second instance of $stmt to something else - $stmtTwo
There is no point in doing that, as previous statement is already closed and cannot interfere in any way.
Would I be writing PHP for 15 years, I would rather suggest to do all the mysql job in one single query, without the need of second statement at all.
add a var_dump($stmtTwo); after binding the result into $company.
That's quite a random poke. Why after binding but not anywhere else?
check your MySQL log for MySQL errors.
For 99% of php users that's mission impossible. Yet it's a matter of only two commands to have the error message right on the screen on the development server.
Is the column member_id in the user table?
That is again a random poke (what about password field?) and it's have to be addressed to the error message discussed in the previous topic anyway. There is no point in asking a programmer for that. One should ask a database, as a way more reliable source.
Add a print output inside it, to show that the password_verify function is working and allowing that code block to execute.
That's the only good point.
Recommendation for using prepared statements is right too, but for some reason it is called "Object style" which is nowhere near the point.
And yes, he finally managed to spot the typo that makes whole question offtopic - fetch() statement is absent.
I suspect that your MySQL is not firing because you're using a PREPARE statement without passing it any values.
Would I be using mysqli myself, I would have known that such a query is all right.
header should be lower case. header() and should be immediately followed by a die or exit command.
Neither is actually true.
Functions in PHP are case insensitive and there is no logic behind this point - so, no manual exit is required.
Stack Overflow is not a code review site either, but nobody cares actually, as one third of answers to those celebrated 10M questions are actually code review answers. So here it goes:
<?php
//Error reporting - ALWAYS PRESENT
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
//Error displaying - DEV ONLY
ini_set('display_errors', 'on');
//New Connection
$mysqli = new mysqli('localhost', 'USER', 'PASSWORD', 'DATABASE');
//Start Session
session_start();
//Query prepare, bind, execute and fetch
$stmt = $mysqli->prepare("SELECT member_id, password FROM user WHERE username=?");
mysqli->bind_param("s",$_POST['username']);
$stmt->execute();
$stmt->bind_result($member_id, $db_pass);
$stmt->fetch();
if(password_verify($_POST['password'], $db_pass))
{
$_SESSION['username'] = $_POST['username'];
$_SESSION['company'] = $member_id;
Header("Location: home.php");
}else{
Header("Location: index.php");
}
You have not added a Fetch statement after binding the result:
if(password_verify($password1, $result))
{
$stmt = $mysqli->prepare("SELECT member_id FROM user WHERE username='$username'");
$stmt -> execute();
$stmt -> bind_result($company);
$stmt -> fetch();
/* Close statement */
$stmt -> close();
$_SESSION['loggedin'] = true;
$_SESSION['username'] = $username;
$_SESSION['company'] = $company;
Some extra notes:
You are writing your MySQL incorrectly, it is wide open to compromise.
You are using the old MySQL style approach but with the structure of the newer OOP approach, this is just as much as security risk as original MySQL.
Old - procedural- style:
mysqli_query($link, "SELECT poops FROM bathroom WHERE smell = '$bad' LIMIT 1");
New - Object Orientated style:
mysqli->prepare("SELECT poops FROM bathroom WHERE smell = ? LIMIT 1")
mysqli->bind_param("s",$bad); //the value is placed by reference rather than directly
mysqli->execute;
Also:
header should be immediately followed by a die or exit command.
header("Location:blah.php");
exit;
I'm fairly new to PHP/MySQL and I seem to be having a newbie issue.
The following code keeps throwing me errors no matter what I change, and I have a feeling it's got to be somewhere in the syntax that I'm messing up with. It all worked at home 'localhost' but now that I'm trying to host it online it seems to be much more temperamental with spaces and whatnot.
It's a simple login system, problem code is as follows:
<?php
session_start();
require 'connect.php';
echo "Test";
//Hash passwords using MD5 hash (32bit string).
$username=($_POST['username']);
$password=MD5($_POST['password']);
//Get required information from admin_logins table
$sql=mysql_query("SELECT * FROM admin_logins WHERE Username='$username' ");
$row=mysql_fetch_array($sql);
//Check that entered username is valid by checking returned UserID
if($row['UserID'] === NULL){
header("Location: ../adminlogin.php?errCode=UserFail");
}
//Where username is correct, check corresponding password
else if ($row['UserID'] != NULL && $row['Password'] != $password){
header("Location: ../adminlogin.php?errCode=PassFail");
}
else{
$_SESSION['isAdmin'] = true;
header("Location: ../admincontrols.php");
}
mysql_close($con);
?>
The test is just in there, so I know why the page is throwing an error, which is:
`Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in 'THISPAGE' on line 12`
It seems to dislike my SQL query.
Any help is much appreciated.
EDIT:
connect.php page is:
<?php
$con = mysql_connect("localhost","username","password");
if(!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("dbname", $con);
?>
and yes it is mysql_*, LOL, I'll get to fix that too.
You should escape column name username using backtick, try
SELECT *
FROM admin_logins
WHERE `Username` = '$username'
You're code is prone to SQL Injection. Use PDO or MYSQLI
Example of using PDO extension:
<?php
$stmt = $dbh->prepare("SELECT * FROM admin_logins WHERE `Username` = ?");
$stmt->bindParam(1, $username);
if ($stmt->execute(array($_GET['name']))) {
while ($row = $stmt->fetch()) {
print_r($row);
}
}
?>
Sean, you have to use dots around your variable, like this:
$sql = mysql_query("SELECT * FROM admin_logins WHERE Username = '". mysql_real_escape_string($username)."' ");
If you use your code just like this then it's vulnerable for SQL Injection. I would strongly recommend using mysql_real_escape_string as you insert data into your database to prevent SQL injections, as a quick solution or better use PDO or MySQLi.
Besides if you use mysql_* to connect to your database, then I'd recommend reading the PHP manual chapter on the mysql_* functions,
where they point out, that this extension is not recommended for writing new code. Instead, they say, you should use either the MySQLi or PDO_MySQL extension.
EDITED:
I also checked your mysql_connect and found a weird regularity which is - if you use " on mysql_connect arguments, then it fails to connect and in my case, when I was testing it for you, it happened just described way, so, please try this instead:
$con = mysql_connect('localhost','username','password');
Try to replace " to ' as it's shown in the PHP Manual examples and it will work, I think!
If it still doesn't work just print $row, with print_r($row); right after $sql=mysql_query() and see what you have on $row array or variable.