PHP MySQL fatal error after moved to real server - php

I have tested my application in localhost and works very well, after I moved to server, the scripts related to MySQL query are die,
class Test {
public function check_duplicate_username($username, $mysqli)
{
$sql = $mysqli->prepare("SELECT username FROM `account` WHERE username=?");
$sql->bind_param('s', $username); // line 44
$sql->execute();
$res = $sql->get_result();
if($res->num_rows !== 0){
return false;
}
return true;
}
public function get_main_cate($mysqli)
{
$sql = $mysqli->query("SELECT name FROM `category` ORDER BY `id` DESC");
if($sql->num_rows > 0){
return $sql;
}else{
return false;
}
}
}
To fetch the result:
$test = new Test;
if(!$test->check_duplicate_username($email, $mysqli)){
$data['error']['email'] = 'email has been used';
}
echo '<select>';
$cat = $test->get_main_cate($mysqli);
while($obj = $cat->fetch_object()){ //line 134
echo '<option>'.$obj->name.'</option>';
}
echo '</select>';
From the error log:
PHP Fatal error: Call to a member function bind_param() on boolean in /path/to/html/root/classes/test.php on line 44
[24-Mar-2016 02:36:26 America/Chicago] PHP Fatal error: Call to a member function fetch_object() on boolean in /path/to/html/root/sign-up.php on line 134
what's wrong with this issue? Is that cause by missing of library in the server? PHP in hosting is Version 5.6.18, whereas in localhost is Version 5.6.19.

The issue seems to be that your database is empty. The error is clear:
Call to a member function fetch_object() on boolean
You tried to call the function fetch_object on a variable of type boolean. The variable on the line is called $cat and is the result of the function $cat = $test->get_main_cate($mysqli);.
Inside that function you are loading all categories and return them. If no categories are found you return false. You have to add a check if $cat is false before trying to iterate over the results, something like
$cat = $test->get_main_cate($mysqli);
if ($cat != false) {
while($obj = $cat->fetch_object()){ //line 134
echo '<option>'.$obj->name.'</option>';
}
}

Instead of checking your that your data exists with !, try using empty(). If I understand the usage correctly, this method should check for all (or most) types of invalid or empty data requests.
According to http://php.net/manual/en/function.empty.php
Returns FALSE if var exists and has a non-empty, non-zero value. Otherwise returns TRUE.
The following things are considered to be empty:
"" (an empty string)
0 (0 as an integer)
0.0 (0 as a float)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
$var; (a variable declared, but without a value)
Try changing this line:
if(!$test->check_duplicate_username($email, $mysqli))
to
if(empty($test->check_duplicate_username($email, $mysqli)))
If this doesn't work. You may just need to consider a 2-step check to verify data exists. Keep in mind I have not tested this method with your code.
Warning from source:
No warning is generated if the variable does not exist. That means empty() is essentially the concise equivalent to !isset($var) || $var == false.

Try to use this query
$sql = $mysqli->prepare('SELECT username FROM account WHERE username=?');
$sql->bind_param('s', $username); // line 44

Related

In PHP, why doesn't mysqli_num_rows return an integer for a query with 0 returned rows?

I am having a strange issue with mysqli_num_rows. Searching for this issue, I've only found people having issues where NULL is returned no matter what. I also checked the official documentation for the function, and it says it returns an integer of the number of rows returned by the query. Whenever my query returns 1 row (it never should return more), it behaves as I expect. When the query returns 0 rows, I expect the function to return 0, but it returns NULL. Why doesn't it return 0?
I know that my database connection is good and my query works correctly, because when I look for a record that's in the database, I get an integer back. I just can't figure out why this is returning NULL rather than 0.
function getArtistID($name) {
global $conn;
$query = "SELECT artist_id FROM artist WHERE artist_name LIKE '${name}'";
$result = mysqli_query($conn, $query);
if ($result->num_rows) {
$row = mysqli_fetch_assoc($result);
return $row['artist_id'];
} else {
return 0;
}
}
Here's some code that I used to reproduce a case where num_rows seems to be NULL:
<?php
error_reporting(E_ALL);
$conn = new mysqli('127.0.0.1', 'root', null, 'test');
$sql = "SELECT * FROM dual";
$result = $conn->query($sql);
if ($result === false) {
print "Error: {$conn->error}\n";
}
$n = $result->num_rows;
echo "Dump the num_rows property: ";
var_dump($n);
Output:
Error: No tables used
Notice: Trying to get property of non-object in /Users/bkarwin/Documents/SO/my.php on line 14
Dump the num_rows property: NULL
The notice is because it's invalid to access an object-oriented property of a variable that is not an object. This is a frequent source of confusion for PHP developers, and it's a byproduct of the fact that PHP is a loosely typed language, and functions like query() can return either a result object, or a boolean scalar.
The query() function actually returned a false as $result because of some error. In my code, I checked for this error, and you didn't.
When you run mysqli::query() or mysqli::prepare() or mysqli_stmt::execute(), you must check for error conditions every time.
Something about your query caused an error. It's up to you to check for the error and report it.
Update: I edited some text above to make the explanation better, but it might make some comments below seem out of place.
I just can't figure out why this is returning NULL rather than 0.
We can only guess without seeing the log output; but, it is likely the return value is null because it raised an error instead.
You need to ensure that errors are handled when calling a function, before attempting to use the return value.

SQL SELECT returns array but PHP considers that as null

I'm selecting something in mySQL via PHP and that command returns some array (which is right), but when I put that returning SELECT inside if condition and ask if it is returning null than PHP says it is returning null (which is not right, because it is returning array)
include '../db.php'; // my config
function select($command) {
global $db;
$sql = "".$command."";
$sqlDone = $db -> prepare($sql);
$sqlDone -> execute();
$data = $sqlDone -> fetchAll();
return $data;
}
$select = "SELECT likes.ID, likes.ID_user, likes.ID_post FROM likes WHERE likes.ID_user = '53' AND likes.ID_post = '2'"
if (select($select) == null) { // goes throw this
print_r(select($select)); // returns array
} else {
echo 'not null';
}
I tried to use !is_null and it doesn't work anyway.
I tried to put that select command with same values directly inside phpmyadmin and it returns array, so I'm confused. Can you help me out?
PDO's fetchAll() returns an array, if there are no results, it returns an empty array (not NULL).
Just use empty()
$return = select($select); //put this into a variable, because if you don't, you'll query the database twice and may get different results.
if (empty($return)) { // goes throw this
print_r($return); // returns array
} else {
echo 'not null';
}
Side note, your function doesn't really do anything special. You could achieve the same thing with this:
$return = $db->prepare($select)->execute()->fetchAll();
If you used a PDO wrapper, it could be even shorter. For example, using my own wrapper GrumpyPDO, you would use
$return = $db->all($select);
then if you had variables to pass to the query, you would do
$select = "SELECT likes.ID, likes.ID_user, likes.ID_post FROM likes WHERE likes.ID_user = ? AND likes.ID_post = ?"
$return = $db->all($select, [$userid, $postid]);

My function returns false after moving to a new server

I got php fatal error after transfer server with php v5.6.19, before that I had no problem at all with following script
Fetch data from db table:
function get_department_list($mysqli)
{
$sql = $mysqli->query("SELECT * FROM `dept` ORDER BY `dept_id` ASC");
if($sql->num_rows > 0){
return $sql;
}else{
return false;
}
}
Populate data in HTML:
<ul class="department overflow-scroll text-center">
<?php
$shop = new Shop;
$depts = $shop->get_department_list($mysqli);
while($dept = $depts->fetch_object()){
echo '<li>'.$dept->dept_name.'</li>';
}
?>
</ul>
In the end I got an error:
Fatal error: Call to a member function fetch_object() on boolean in C:\xampp\htdocs\project\include\header.php on line 206
First, you are returning a boolean from your function. So, no wonder PHP says you so.
Second, you should keep the matters separated. a function that works with mysqli should keep all mysqli stuff inside. An return just an array, that can be used anywhere without the need to call mysqli functions again.
function get_department_list($mysqli)
{
$sql = $mysqli->query("SELECT * FROM `dept` ORDER BY `dept_id` ASC");
return $sql->fetch_all();
}
And then use not while but foreach
foreach ($depts as $dept) ...
Besides (and more for the people who may chance to land on this question looking for an answer to their question) you should always set proper error reporting for mysqli, like it shown in this answer
Update your while loop for that case when you get false from $shop->get_department_list() call
updated while like this check for $depts if any data then get $dept:
while($depts && $dept = $depts->fetch_object()){

How to check no. of rows returned when using MYSQLI_STMT_PREPARE and MYSQLI_FETCH_ARRAY?

I thought I could use MYSQLI_STMT_NUM_ROWS and MYSQLI_STMT_STORE_RESULTto check for no. of rows returned. (see commented lines ///1///, ///2///, ///3///)
But it doesn't seem to in the context below.
This codes does work (without the commented lines), but I am trying to add an extra check, to confirm that no more than 1 record is returned. (even though this should always be the case, as the email field in the table is unique, but it doesn't hurt to do the check anyway).
Can anyone shed some light on what I'm doing wrong?
This is the error I get below (line 86 if the WHILE ... line):
An error occurred in script 'L:\includes\login_functions.inc.php' on line 86: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given
NOTE:
This a stripped down version of the original code.
$form_email and $form_pass are originated from form input.
Code is procedural, because I like it that way.
<?php
// Prepared statement.
$prep_sel = 'SELECT user_id, first_name, user_level, pass FROM users WHERE email=? and active is null';
// Initialise connection.
$stmt_sel = mysqli_stmt_init($dbc);
// Check if there are any DB connection problems.
....
// Prepare statement, bind parameters (an integer and a string) and execute the statement
if (mysqli_stmt_prepare($stmt_sel, $prep_sel)) {
mysqli_stmt_bind_param($stmt_sel, 's', $form_email);
mysqli_stmt_execute($stmt_sel);
///1///mysqli_stmt_store_result($stmt_sel);
}
///2///if (mysqli_stmt_num_rows($stmt_sel) == 1) { // one record found.
// Get the results.
$result = mysqli_stmt_get_result($stmt_sel);
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
// Now check if the passwords match.
if (password_verify($form_pass, $row['pass'])) {
return array(true, $row);
} else {
$errors[] = 'the details you provided does not match our records';
$errors[] = 'your account has not been activated';
}
}
///3///}
/* close statement */
mysqli_stmt_close($stmt_sel);
?>
After calling mysqli_stmt_store_result(), the MySQL driver will not permit you to operate on a result set until all rows are fetched or the result set is freed and the statement closed. So a subsequent call to mysqli_stmt_get_result() will return false, and probably result in an error like
Commands out of sync; you can't run this command now
which you may check with echo mysqli_error($dbc);
Transferring the statement's result set with mysqli_stmt_get_result() will give you access to its num_rows property, so you actually don't need to use mysqli_stmt_store_result(). Instead just rely on mysqli_stmt_get_result() before checking the number of rows returned:
if (mysqli_stmt_prepare($stmt_sel, $prep_sel)) {
mysqli_stmt_bind_param($stmt_sel, 's', $form_email);
mysqli_stmt_execute($stmt_sel);
// Transfer the result set here:
$result = mysqli_stmt_get_result($stmt_sel);
// Then check rows returned on the $result obj
// using mysqli_num_rows(), not mysqli_stmt_num_rows()
if (mysqli_num_rows($result) == 1) {
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
// Check your password, etc....
}
}
else {
// More than 1, do whatever you need to handle this
}
// Close it
mysqli_stmt_close($stmt_sel);
}
function authenticateUser($email, $password){
$stmt = $db->prepare("SELECT user_id, first_name, user_level, pass FROM users WHERE email=? and active is null");
$stmt->bind_param('s', $email);
$stmt->execute();
$res = $stmt->get_result();
if($res->num_rows > 0){
$hash = $res->fetch_object()->pass;
if(password_verify($password, $hash)){
return true;
}
}
return false;
}
call the function
if(authenticateUser($_POST['email'], $_POST['password'])){
//do something
}
else{
echo "Invalid Email/Password";
}

Query empty if included

I have been performing a query inside my page -- say, page.php -- where I run a simple query.
Pseudo-code:
$request_unavailble = mysqli_query($mysqli, "SELECT * FROM my_table WHERE availble='0'");
When this is performed from within page.php, I get all results where availble is set to 0. However, if I run this from within a seperate included file, the data returns empty. In fact, mysqli_num_rows returns 0 when included.
What's going wrong, here?
Edit
The following function was added as an include (both as a function and alone)
function compte_messagerie()
{
$requetes_messagerie = mysqli_query($mysqli, "SELECT * FROM ".DB_PREFIX."messagerie WHERE lu='0'");
if(mysqli_num_rows($requetes_messagerie) == 0)
{
echo '<a id="messagerie" href="messagerie">'.AUCUN_NOUVEAU."</a>";
}
else if(mysqli_num_rows($requetes_messagerie) == 1)
{
echo '<a id="messagerie" href="messagerie">';
echo '<span>'.mysqli_num_rows($requetes_messagerie)."</span> ";
echo MESSAGES_SINGULIER."</a>";
}
else
{
echo '<a id="messagerie" href="messagerie">';
echo '<span>'.mysqli_num_rows($requetes_messagerie)."</span> ";
echo MESSAGES_PLURIEL."</a>";
}
}
When porting your query into a function, the MySQLi connection object in $mysqli went out of scope, and was therefore invalid inside the function. With display_errors enabled, I would expect you to see errors like:
Notice: undefined variable $mysqli
Warning: mysqli_query() expects parameter 1 to be resource, null given
The cleanest solution is to pass $mysqli into your function as a parameter, making it available to the function's scope
// Expect the MySQLi resource as a parameter...
function compte_messagerie($mysqli)
{
$requetes_messagerie = mysqli_query($mysqli, "SELECT * FROM ".DB_PREFIX."messagerie WHERE lu='0'");
if(mysqli_num_rows($requetes_messagerie) == 0)
{
echo '<a id="messagerie" href="messagerie">'.AUCUN_NOUVEAU."</a>";
}
// etc.....
}
Try this. Please check if the available table is require string value or integer.
$request_unavailble = mysqli_query("SELECT * FROM my_table WHERE availble= 0 ");
while($rows = mysqli_fetch_assoc($request_unavailble)){ // <- this will check if there some data fetch
// You put some code here
}

Categories