I don't understand why mysqli_fetch_array returns NULL

Hi… Below is a code snip for reading a db and assigning it into a variable via mysqli_fetch_array. I can check the sql result $loginResult and it has record values. But when I do a mysqli_fetch_array into $loginMember that returns a NULL. I can’t quite figure out why. Any hints on what I should try?

	$sql = "SELECT *
		FROM {$dbinfo[pre]}members
		WHERE email = '{$wpUserEmail}' 
		LIMIT 1
		";

	$loginResult = mysqli_query($db,$sql); 
	$loginRows = mysqli_num_rows($loginResult); // Rows from query
	if($loginRows) {
		try
		{
			**// I can check $loginResult at this point and it has record values**
			
			$loginMember = mysqli_fetch_array($loginResult);
                        **// $loginMember returns NULL**

When you say code snip… is there anything else going on between the rows of this code? or is this a block of code as-is?

What comes after this block? Does $loginMember get reused?

Here’s the entire code block… I removed other code to simplify it and it still shows NULL for $loginMember (line 57 >> $loginMember = mysqli_fetch_array($loginResult):wink:

function myStartSession() {
    if(!session_id()) {
        session_start();
    }
	define('BASE_PATH', $_SERVER['DOCUMENT_ROOT'] . '/store'); // Define the base path where PhotoStore is located.
	define('INIT_SMARTY',false); // Use Smarty
}
add_action('init', 'myStartSession');


function photoStoreLoginGet() {
	global $userdata;
	$userRoles= wp_get_current_user()->roles; 
	if (is_user_logged_in()) {
		$wpUserEmail = wp_get_current_user()->user_email; 
		if ( !($_SESSION['loggedIn'] == 1 and $wpUserEmail == $_SESSION['photoStore']['email']) 
			or ($wpUserEmail == $_SESSION['photoStore']['email'] and $_SESSION['photoStore']['verified'] == null)){  
			if (function_exists('photoStoreLogin')) {
				photoStoreLogin($wpUserEmail);
			}
		}
	}
}
add_action('wp_loaded', 'photoStoreLoginGet');


function photoStoreLogin($wpUserEmail) {
	require_once BASE_PATH.'/assets/includes/initialize.wp.php';
	$setCurrency = new currencySetup;
	$activeCurrencies = $setCurrency->getActiveCurrencies();

	/*
	* Include manager language file
	*/
	if(file_exists(BASE_PATH."/assets/languages/" . $config['settings']['lang_file_mgr'] . "/lang.manager.php"))
		include(BASE_PATH."/assets/languages/" . $config['settings']['lang_file_mgr'] . "/lang.manager.php");
	else
		include(BASE_PATH."/assets/languages/english/lang.manager.php");

	/*
	* Check login details for login
	*/
	$_SESSION['photoStore']['email'] = $wpUserEmail;
	$_SESSION['loggedIn'] = 0;
	$sql = "SELECT *
		FROM {$dbinfo[pre]}members
		WHERE email = '{$wpUserEmail}' 
		LIMIT 1
		";

	$loginResult = mysqli_query($db,$sql); 
	$loginRows = mysqli_num_rows($loginResult); // Rows from query
	if($loginRows) {
		try
		{
			// d($loginResult);  Debug shows array values for $loginResults here
			$loginMember = mysqli_fetch_array($loginResult);
			// d($loginMember);  Debug shows NULL for $loginMember here
		}
		catch(Exception $e) {
			$_SESSION['photoStore']['verified'] = null; // The session assign/login failed. Set to null so it can be tried again
		}
	} else {
		$_SESSION['photoStore']['verified'] = 3;  // 'no recored'
	}
	if($db) mysqli_close($db); // Close any database connections
}

if you only uncomment the second of your calls to d() (the one that d’s $loginMember), do you still get Null? what happens if you just flat out print_r($loginMember) instead?

I’m concerned about your comments on those lines - mysql_results cant be natively converted to strings, and if d() is iterating the result set to output the debug messages, then fetch_array will find nothing, because the set has already been iterated through by d() and exhausted the result.

BRILLIANT! Thank you so much @m_hutley. I just couldn’t figure that one out, but you nailed it. I never would have imagined doing a debug dump on the sql result would push the pointer.

Out of curiosity, would there be a better way of doing the sqli fetch that wouldn’t be interfered with by a debug?

1 Like

You’ve already done it.
The num_rows call validates the size of the result without pushing a pointer, and you can debug the result set during the useful iteration of a set by examining the result of each iteration.

So, lets take a more generic case that would have more than 1 row (LIMIT 1 guarantees thats not the case in this instance).
Validation of the size of the result set is governed by num_rows;
Validation of the data in each result of the result set would be handled by examining the output in situ - something to the tune of…

while($row = mysqli_fetch_array($result) {
   d($row);
   //Do other things with $row.
}

Note that playing with $row has no bearing on our result set - the pointer is only advanced by fetching the next result in the set, and $row is a local array copy of that data.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.