mysqli_query() expects parameter 2 to be string, object given in - php

The above error keeps coming up instead of redirecting to index.php
The code should start an admin user session on index.php.
It was originally based on MySQL then I used MYSqli
<?php
$a = $_POST["username"];
$b = $_POST["password"];
$conn = new mysqli("localhost", "root", "", "...");
$query = $conn->query("SELECT * FROM users WHERE username='$a' AND password='$b' AND isadmin=1");
$result = mysqli_query($conn, $query) or die(mysqli_error($conn));
$num_rows = mysqli_num_rows($result);
session_start();
if ($result)
{
$_SESSION["admin"] = $_POST["username"];
header ("Location: index.php");
}
elseif (!$result)
{
$_SESSION["gatekeeper"] = $_POST["username"];
header ("Location: index.php");
}
else
{

Your main error is that you call the query() method twice. Both $conn->query and mysqli_query() are the same thing, and when you pass the result of one to the other you get this cryptic error.
Another issue is that your connection for mysqli is not up to the standards. See https://phpdelusions.net/mysqli/mysqli_connect to learn more about connecting. You should also enable error reporting with mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); instead of manually checking for errors with or die(mysqli_error($conn));
You should use parameterized prepared statements instead of manually building your queries. They are provided by PDO or by MySQLi. Never trust any kind of input! Even when your queries are executed only by trusted users, you are still in risk of corrupting your data.
Never store passwords in clear text or using MD5/SHA1! Only store password hashes created using PHP's password_hash(), which you can then verify using password_verify(). Take a look at this post: How to use password_hash and learn more about bcrypt & password hashing in PHP
I haven't fixed all of your issues, I leave that as an exercise for you, but this should act as a guide on what the proper mysqli code should look like.
<?php
session_start();
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli("localhost", "root", "", "...");
$conn->set_charset('utf8mb4');
$stmt = $conn->prepare('SELECT * FROM users WHERE username=? AND password=? AND isadmin=1');
$stmt->bind_param('ss', $_POST["username"], $_POST["password"]);
$stmt->execute();
$result = $stmt->get_result();
$firstRow = $result->fetch_assoc(); // See https://phpdelusions.net/mysqli/check_value
if ($firstRow) {
$_SESSION["admin"] = $_POST["username"];
exit(header("Location: index.php")); // Always `exit()` after `header('Location: ...');`
} elseif (!$result) {
$_SESSION["gatekeeper"] = $_POST["username"];
exit(header("Location: index.php")); // Always `exit()` after `header('Location: ...');`
}

You don't need to call $conn->query when assigning the $query variable. Just assign the string. The next line executes the query.
$query = "SELECT * FROM users WHERE username='$a' AND password='$b' AND isadmin=1";
Your code executes the query, then tries to execute the result again as if it were a query string.

Related

PHP Error when I validate if the username and email already existed in the table

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.

MySQL Row Isn't Found But It's There

I'm using PHP to try and select a single row from a table in my MySQL database. I've run the query manually inside phpMyAdmin4 and it returned the expected results. However, when I run the EXACT same query in PHP, it's returning nothing.
$query = "SELECT * FROM characters WHERE username=".$username." and charactername=".$characterName."";
if($result = $mysqli->query($query))
{
while($row = $result->fetch_row())
{
echo $row[0];
}
$result->close();
}
else
echo "No results for username ".$username." for character ".$characterName.".";
And when I test this in browser I get the "No results..." echoed back. Am I doing something wrong?
This isn't a duplicate question because I'm not asking when to use certain quotes and backticks. I'm asking for help on why my query isn't working. Quotes just happened to be incorrect, but even when corrected the problem isn't solved. Below is the edited code as well as the rest of it. I have removed my server information for obvious reasons.
<?PHP
$username = $_GET['username'];
$characterName = $_GET['characterName'];
$mysqli = new mysqli("REDACTED","REDACTED","REDACTED");
if(mysqli_connect_errno())
{
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "SELECT * FROM `characters` WHERE `username`='".$username."' and `charactername`='".$characterName."'";
if($result = $mysqli->query($query))
{
while($row = $result->fetch_row())
{
echo $row[0];
}
$result->close();
}
else
echo "No results for username ".$username." for character ".$characterName.".";
$mysqli->close();
?>
It's failing: $mysqli = new mysqli("REDACTED","REDACTED","REDACTED"); because you didn't choose a database.
Connecting to a database using the MySQLi API requires 4 parameters:
http://php.net/manual/en/function.mysqli-connect.php
If your password isn't required, you still need an (empty) parameter for it.
I.e.: $mysqli = new mysqli("host","user", "", "db");
Plus, as noted.
Your present code is open to SQL injection. Use mysqli_* with prepared statements, or PDO with prepared statements.
Footnotes:
As stated in the original post. Strings require to be quoted in values.
You need to add quotes to the strings in your query:
$query = "SELECT *
FROM characters
WHERE username='".$username."' and charactername='".$characterName."'";

SELECT statement not working - mysqli

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;

Mysqli_real_escape_string() or addslashes() in a forum context

I'm making a forum in php and MySql, so I need to insert and select data from my data base. I'm using mysqli to connect to my db. Something like this:
$link=mysqli_connect("fake_server", "fake_user", "fake_pass", "fake_db");
$user=mysqli_real_escape_string($link, $_POST['user']);
$pass=hash("sha256", mysqli_real_escape_string($link, $_POST['pass']));
$combo=mysqli_fetch_array(mysqli_query($link, "SELECT 1 FROM users WHERE user='$user' AND pwd='$pass'"));
if($combo==0){
// ERROR
} else {
// CORRECT
}
mysqli_close($link);
The problem is the next one:
Everybody say that mysqli_real_escape_string() is MUCH better than addslashes() for insert, but I want users can use single and double quotes in their topics. Myqsli_real_escape_string() removes them but addslashes() doesn't. What can I do in this context?
You should use prepared statements, http://php.net/manual/en/mysqli.quickstart.prepared-statements.php. In the future please provide your code in your question. Here's how you can use your current code with prepared statements:
$link=mysqli_connect("fake_server", "fake_user", "fake_pass", "fake_db");
$user=$_POST['user'];
$pass=hash("sha256", $_POST['pass']);
$stmt = $link->prepare("SELECT 1 FROM users WHERE user = ? AND pwd = ?");
$stmt->bind_param("ss", $user, $pass);
$combo=mysqli_fetch_array($stmt->execute());
if($combo==0){
// ERROR
} else {
// CORRECT
}
mysqli_close($link);
Further reading on the topic:
How can I prevent SQL injection in PHP?mysqli or PDO - what are the pros and cons?
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28Parameterized_Queries.29http://php.net/manual/en/mysqlinfo.api.choosing.php
Use a parameterized query with PDO and forget worrying about escaping your queries.
Edit
Your test code:
$link=mysqli_connect("fake_server", "fake_user", "fake_pass", "fake_db");
$user=mysqli_real_escape_string($link, $_POST['user']);
$pass=hash("sha256", mysqli_real_escape_string($link, $_POST['pass']));
$combo=mysqli_fetch_array(mysqli_query($link, "SELECT 1 FROM users WHERE user='$user' AND pwd='$pass'"));
if($combo==0){
// ERROR
} else {
// CORRECT
}
mysqli_close($link);
The PDO version:
$pdo = new PDO('mysql:host=fake_server;dbname=fake_db', 'fake_user', 'fake_pass');
$query = $pdo->prepare("SELECT 1 FROM users WHERE user='?' AND pwd='?'");
$query->execute(array($_POST('user'), hash('sha256', $_POST('pass')));
if ($combo = $query->fetch ()) {
// CORRECT
// $combo would contain an array containing your select fields
} else {
// ERROR
}

Jquery/PHP ajax login system

I'm setting up a blog type page for my business. Brand new to MySQL and PHP. Set up this login system. For some reason have no idea why the login is dropping. Suppose to check for errors then return 'good' through php if the email and password is right. If php returns good then it's suppose to redirect to the blog page.
Been dealing with this for a few months need desperate help please. Thank you.
Here is the php code that goes along with the jquery.
Link to test site is here.
test.toddprod.com/login
Would really appreciated the help.
Thanks
<?php
#fake mysql connection first
DEFINE ('DB_USER','usernamegoeshere');
DEFINE ('DB_PASSWORD','passwordhere');
DEFINE ('DB_HOST','hostnamehere');
DEFINE ('DB_NAME','andtheotherthinghere');
$dbc = mysql_connect (DB_HOST, DB_USER, DB_PASSWORD) or die ('Could not connect to MySQL');
$db = mysql_select_db(DB_NAME, $dbc) or die('Could not select database.'.mysql_error());
$e = $_POST['email'];
$pass = $_POST['pass'];
$q = 'SELECT user_id from toddprod where email="'.$e.'" and pass= SHA1("'.$pass.'")';
$r = mysql_query($db, $q);
if( mysql_num_rows($r)==1 ){
setcookie ( 'user_id', $r);
setcookie ( 'email', '$e');
setcookie ( 'logged-in', 'true');
echo 'good';
}
else if (mysql_num_rows($r)==0) {
echo 'Your '.$e.' with password '.$pass;
};
mysql_close ($db);
?>
Umm there's a number of things I see wrong here...
First of all your query should be sanitized...
$email = mysql_real_escape_string ($_POST['email']); // escape the email
$pass = SHA1(mysql_real_escape_string ($_POST['pass'])); // escape and encrypt the pass
// now you can put it into the query safely
$query = "SELECT user_id from toddprod where email = '$email' and pass = '$pass' ";
Next you're executing the query wrong, the mysql_query function takes two arguments, the query and the database connection. You're passing the wrong arguments, you're passing the query and the result of the mysql_select_db function which is just a boolean value. So you have to $dbc not $db into that query, and even then you're passing the arguments in the wrong order. The query goes first, than the connection. So it should be...
$result = mysql_query($query, $dbc);
Next you're trying to set the return value from the mysql_query function as your cookie but that value is a resource, not the userid that you need. You have to actually read the value from the resource like this.
$row = mysql_fetch_array($result);
$userid = $row["user_id"];
setcookie('user_id', $userid);
Moving on... when you're setting the email cookie, you have the variable in single quotes, so the cookie will actually contain $e and not the actual email because single quotes store strings litterly (without parsing the variables). So you should either use double quotes, or no quotes at all. So either one of the following is fine...
setcookie('email', "$e");
setcookie('email', $e);
Last but not least, you should not have the semicolon at the end of your if-statement, and you again you need to pass the connection not the database-selection result into the mysql_close function, so it should be
mysql_close($dbc);
There, hope this gets you somewhere, try out these changes and if the problem persists i'd be happy to help you further.
Here are links that will help you out:
http://www.php.net/manual/en/function.mysql-query.php
http://www.php.net/manual/en/function.mysql-fetch-array.php
http://www.php.net/manual/en/function.mysql-real-escape-string.php
Edit:
Here, I have fixed the code according to the problems I found. Try it out, I could not test it so it might have some small syntax errors here and there, but it should give you something to compare with. Also for the future, I would suggest that you name your variables semantically/properly so it's easier for others to pickup and it will also keep you from getting confused like you were passing $db instead of $dbc into a few of your functions.
<?php
// keep the function names in lowercase, no reason, just looks better to me
define('DB_USER', 'usernamegoeshere');
define('DB_PASSWORD', 'passwordhere');
define('DB_HOST', 'hostnamehere');
define('DB_NAME', 'andtheotherthinghere');
// connect to the mysql server
$conn = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) or die ('Could not connect to MySQL');
// select the database, you don't need to store the result, it just returns true or false
mysql_select_db(DB_NAME, $conn) or die('Could not select database.' .mysql_error());
// escape the input
$email = mysql_real_escape_string($_POST['email']);
$pass = sha1(mysql_real_escape_string($_POST['pass']));
// create the query
$query = "SELECT user_id FROM toddprod WHERE email = '$email' AND pass = '$pass'";
// execute the query
$result = mysql_query($query, $conn);
$usercount = mysql_num_rows($result);
if($usercount == 1){
// read the results and get the user_id
$row = mysql_fetch_array($result);
$userid = $row['user_id'];
// set the cookies
setcookie('user_id', $userid);
setcookie('email', $email);
setcookie('logged-in', 'true');
// echo success message
echo 'good';
}elseif($usercount == 0) {
echo "You're $email with password $pass";
}
mysql_close($conn);
?>
First things first, you MUST sanitise user input with mysql_real_escape_string():
$e = mysql_real_escape_string ($_POST['email']);
$pass = mysql_real_escape_string ($_POST['pass']);
Read up a bit on SQL injection, you'll be very glad you did.
As for the main problem, could you provide a bit more context? How are you checking to see if the user is logged in?

Categories