Why WHILE Loop Fails After Paginated Page 1?

Hi,

I just joined.
I need advice. On php. I starter level student.
I learning procedural style. Mysqli. Prepared Statement. Don’t know anything else. No pdo. No oop.

Can you people check my pagination code ?
It supposed to work like this:

When you click Search button, at beginning rows_count() does action. It gets matching rows number. Like this:

$query_2 = "SELECT * FROM users WHERE first_name = ? AND marital_status = ? LIMIT $offset,$last_row_on_page";

Is query ok ?

Then the fetch_rows() fetches rows data and displays in a pagination mode.

When you click any page numbers on any pagination links, like page 2, then fetch_rows() is supposed to fetch the relevant rows again for page 2.
I fetching rows with this query:

$query_2 = "SELECT * FROM users WHERE first_name = ? AND marital_status = ? LIMIT $offset,$last_row_on_page";

Is query ok ?

I got problem here …

while($row = mysqli_fetch_array($result_2,MYSQLI_ASSOC))

It does not get into action in any pages beyond page 1 like page 2, page 2, etc.
It only manage to get into action fetching matching rows for page 1. Not passed page 1. That is my big problem.

Code I configure to display 1 row per page only in dev mode. Will switch to 10-100 later on production mode.
Since exist 5 matching rows then these rows supposed to display across many pages via pagination.

Lines I am having trouble are CAPITALISED in my code comments. Do put attention on them to understand my problem to give right solution.

//Do following if "Search" button clicked.
	if($_SERVER['REQUEST_METHOD'] === 'POST')
	{echo __LINE__; echo "<br>";//DELETE
		//Do following if "Search" button clicked.
		if(isset($_POST['search']))
		{echo __LINE__; echo "<br>";//DELETE
			rows_count(); //This function will forward script flow to fetch_rows() before halting the script.
			die();
		}
	}
	echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS FAILS TO ECHO. IT IS LINE: 24.
	//Do following if "Search" button not clicked but pagination numbered links are clicked. Eg Page 1, 2, 3, etc..
	fetch_rows(); //On PAGINATION PAGE 2, THIS FUNCTION IS NOT GETTING TRIGGERED! WHY ?
	echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 205.

Here is the full code for your convenience. You won’t understand the code without the context.

DEVMODE CONTEXT:

<?php
error_reporting(E_ALL);
?>

<!DOCTYPE HTML">
<html>

<head>
<meta name="viewport" content="width-device=width, initial-scale=1">
</head>
<body>

<?php
session_start();

if(!isset($_GET['query_type']) && empty($_GET['query_type']))
{
	die("Invalid Query!");
}
else
{
	$_SESSION['query_type'] = $_GET['query_type']; echo __LINE__; echo "<br>";//DELETE
}
echo __LINE__; echo "<br>";//DELETE

if(!isset($_GET['form_type']) && empty($_GET['form_type']))
{
	die("Invalid Form!");
}
else
{
	$_SESSION['form_type'] = $_GET['form_type']; echo __LINE__; echo "<br>";//DELETE
	
	if(!function_exists($_SESSION['form_type']))
	{
		die("Invalid Form!");
	}
	else
	{echo __LINE__; echo "<br>";//DELETE
		if(!session_id() || !isset($_SESSION['form_step']) || $_SESSION['form_step'] != 'end')
		{
			$_SESSION['form_step'] = 'start'; echo __LINE__; echo "<br>";//DELETE
			$_SESSION['form_type']();
		}
	}
}
		
//FUNCTIONS START FROM HERE
function search()
{echo __LINE__; echo "<br>";//DELETE
	function rows_count()
	{
		//Connect to Database. (DB_SERVER, BD_USERNAME, DB_PASSWORD, DB_NAME).
		$conn = mysqli_connect("localhost","root","","powerpage");
		$conn->set_charset('utf8mb4'); //Always set Charset.
		
		if($conn === false)
		{
			die("ERROR: Connection Error!. " . mysqli_connect_error());
		}
		
		$query_1 = "SELECT COUNT(id) FROM users WHERE first_name = ? AND marital_status = ?";
		$stmt_1 = mysqli_stmt_init($conn);
		if(mysqli_stmt_prepare($stmt_1,$query_1))
		{
			mysqli_stmt_bind_param($stmt_1,"ss",$_POST["first_name"],$_POST["marital_status"]);
			mysqli_stmt_execute($stmt_1);
			$result_1 = mysqli_stmt_bind_result($stmt_1,$row_count);
			mysqli_stmt_fetch($stmt_1);
			$_SESSION['row_count'] = $row_count;
			echo __LINE__; echo "<br>";//DELETE
			$_SESSION['form_step'] = 'end';
			fetch_rows();
		}
	}

	function fetch_rows()
	{	echo __LINE__; echo "<br>";//DELETE
		$form_step = $_GET['form_step'];
		
		$page_number = $_GET['page'];
		$result_per_page = $_GET['page_limit'];
		$offset = (($page_number * $result_per_page) - $result_per_page); //Offset (Row Number that 'Starts' on page).
		$last_row_on_page = ($page_number * $result_per_page); //Max Result (Row Number that 'Ends' on page).
		$previous_page = $page_number-1;
		$next_page = $page_number+1;
		
		echo "Row Start: $offset";echo "<br>";
		echo "Row End: $last_row_on_page";echo "<br>";
		
		//Connect to Database. (DB_SERVER, BD_USERNAME, DB_PASSWORD, DB_NAME).
		$conn = mysqli_connect("localhost","root","","powerpage");
		$conn->set_charset('utf8mb4'); //Always set Charset.

		if($conn === false)
		{
			die("ERROR: Connection Error!. " . mysqli_connect_error());
		}

		$query_2 = "SELECT * FROM users WHERE first_name = ? AND marital_status = ? LIMIT $offset,$last_row_on_page";
		$stmt_2 = mysqli_stmt_init($conn);
		if(mysqli_stmt_prepare($stmt_2,$query_2))
		{echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 103.
			mysqli_stmt_bind_param($stmt_2,"ss",$_POST["first_name"],$_POST["marital_status"]);
			mysqli_stmt_execute($stmt_2);
			$result_2 = mysqli_stmt_get_result($stmt_2);
			if(!$result_2)
			{
				//Close Connection.
				mysqli_close($conn);
				die("<pre>2c. Statement Fetching failed!</pre>");
			}
			else
			{echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 114.
				//Grab total number of pages to paginate.
				$row_count = $_SESSION['row_count'];
				//$total_pages = ceil($result_1/$result_per_page);
				$total_pages = ceil($row_count/$result_per_page);
				
				echo "TOTAL PAGES: $total_pages<br><br>";
				
				while($row = mysqli_fetch_array($result_2,MYSQLI_ASSOC))//On PAGE 2, PHP IGNORING THIS AND BYPASSING THIS WHOLE WHILE LOOP ON PAGE 2. IT IS LINE: 122. 
				{echo __LINE__; echo "<br>";//On PAGE 2, THIS FAILS TO ECHO. IT IS LINE: 123. PHP IGNORING IT BYPASSING IT ON PAGE 2.
					//Retrieve Values.
					$id = $row["id"];
					$first_name = $row["first_name"];
					$middle_name = $row["middle_name"];
					$surname = $row["surname"];
					$gender = $row["gender"];
					$marital_status = $row["marital_status"];
					$working_status = $row["working_status"];
					
					echo "Id: $id<br>";
					echo "First Name: $first_name<br>";
					echo "Middle Name: $middle_name<br>";
					echo "Surname: $surname<br>";
					echo "Gender: $gender<br>";
					echo "Marital Status: $marital_status<br>";
					echo "Working Status: $working_status<br>";
					echo "<br>";
					echo "<br>";
					
					$i = 1;
					while($i<=$total_pages)
					{
						if($i<$total_pages)
						{
							echo "<a href='http://localhost/power.page/pagination_test_simple_WORKING_ON_NOW.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=1&page=<?php echo $i;?>'><?php echo " $i ";?></a><?php 
						}
						elseif($i==$page_number)
						{
							echo "<a href='http://localhost/power.page/pagination_test_simple_WORKING_ON_NOW.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=1&page=<?php echo $i;?>'><?php echo "<b> $i </b>";?></a><?php 
						}
						
						$i++;
					}
					if($page_number>$total_pages)
					{
						echo "<a href='http://localhost/power.page/pagination_test_simple_WORKING_ON_NOW.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=1&page=<?php echo $previous_page;?>'><?php echo "<b> Previous </b>";?></a><?php 
					}
				}
			}
		} 
		$_SESSION['form_step'] = 'end';
	}
	?>
	
	<form action="<?php echo $_SERVER['PHP_SELF'];?>?form_type=<?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=1&page=1" method='post' enctype='plain/text'>
	<?php

	//Added '*' (asterisk) to indicate the 'Text Field' is a 'required' one.
	echo "<label for=\"first_name\">First Name *:</label>
	<input type=\"text\" name=\"first_name\" placeholder=\"First Name\" value = \"\">";?>
	<br>
	<?php
	echo "<label for=\"marital_status\">Marital Status *:</label>";
	echo "<select name=\"marital_status\">";
	echo "<option value=\"single\">Single</option>";
	echo "<option value=\"married\">Married</option>";
	echo "</select>";
	echo "<br>";
	?>
	<input type="submit" name="search" value="Search">
	<?php
	//$current_function = __FUNCTION__;
	//echo $current_function;
	
	//Do following if "Search" button clicked.
	if($_SERVER['REQUEST_METHOD'] === 'POST')
	{echo __LINE__; echo "<br>";//DELETE
		//Do following if "Search" button clicked.
		if(isset($_POST['search']))
		{echo __LINE__; echo "<br>";//DELETE
			rows_count(); //This function will forward script flow to fetch_rows() before halting the script.
			die();
		}
	}
	echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS FAILS TO ECHO. IT IS LINE: 24.
	//Do following if "Search" button not clicked but pagination numbered links are clicked. Eg Page 1, 2, 3, etc..
	fetch_rows(); //On PAGINATION PAGE 2, THIS FUNCTION IS NOT GETTING TRIGGERED! WHY ?
	echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 205.
}

?>

What is wrong ? Why is fetch_rows() or $query_2 failing to fetch the matching rows for pages beyond page 1 ?

ECHOES
Before clicking the SEARCH button, I get echoed these line numbers as expected:

22
24
32
39
42
50

After clicking the SEARCH button I get these echoed as expected:

193
71
78
Row Start: 0
Row End: 1
103
114
TOTAL PAGES: 5

123

After paginated clicking link for ‘page 2’, I get echoed all these same line numbers I get echo before clicking the SEARCH button as if everything is starting all over again with a new query (I not intend this). That not supposed to happen.

I reckon line 200 is not taking action:

fetch_rows(); //On PAGINATION PAGE 2, THIS FUNCTION IS NOT GETTING TRIGGERED! WHY ? IT IS LINE: 200. MAIN ISSUE HERE, I SUSPECT.

You think it is line 200 the crook here ?

How to correctify the coding ?

I haven’t read all your code, but don’t forget that the LIMIT clause takes two parameters, the starting row and the number of rows to return. It doesn’t take the starting row and the ending row. It can take just the number of rows (ideal for the first page), but there isn’t a from-to option as your variable names suggest you are using.

It’s worth noting that without an ORDER BY clause, your LIMIT may not be so useful.

This section doesn’t look quite right to me, either:

$i = 1;
while($i<=$total_pages)
  {
  if($i<$total_pages)
    {
    echo "<a href='http://localhost/power.page/pagination_test_simple_WORKING_ON_NOW.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=1&page=<?php echo $i;?>'><?php echo " $i ";?></a><?php 
    }
  elseif($i==$page_number)
    {
    echo "<a href='http://localhost/power.page/pagination_test_simple_WORKING_ON_NOW.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=1&page=<?php echo $i;?>'><?php echo "<b> $i </b>";?></a><?php 
    }
  $i++;
}
				

The if and the elseif clauses don’t seem to be correct to me. Is it fair to say that it will only display the page number in bold if it’s the same as $total_pages? I can’t quite do it in my head. It seems that it will only go into the elseif clause if $i is not less than $total_pages, which in your outer while() means that it will only do it once, when it is the same as $total_pages.

Wouldn’t it be easier to just check if $i is the current page, display the bold page number, otherwise display it in normal font? In fact, as it seems that the link is identical other than having the <b> tags around the display (which I think should probably now be <strong>, but has probably changed again), why not just set a variable that is the page number either with or without the bold tags, and just have the one echo statement?

I’m not sure the above helps with your actual query.

If you’re relying on your session variables to help decide whether you’re on the first page or a later one, you shouldn’t send output to the browser before your session_start() call. That should be the very first thing you do. You have a DOCTYPE and a load of other stuff being output which, unless you have buffering enabled, may interfere with the session start.

1 Like

Thank You droopsnoot!

I forgot about the ORDER by id in my LIMIT query. Fixed it.
You ask: Why I am make page number bold that equals to the $total_pages ?
Where I did it ? I check code, I see this:

elseif($i==$page_number)
{
	echo "<a href='http://localhost/power.page/pagination_test_simple_WORKING_ON_NOW.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=1&page=<?php echo $i;?>'><?php echo "<b> $i </b>";?></a><?php 						}

I ordered php to make bold that page number which matches with the page you are on. So, if you on page 5, then page number 5 will be shown in bold.

Mr droopsnoot, I just realize that, $_SESSION[‘row_count’] = 5, when I click SEARCH button. It means: 5 matching rows found.

Now, when I click PAGE 2 on pagination, the $_SESSION[‘row_count’] = 0, why is that ? It should stay 5. I am not overwriting the variable value anywhere.

This is reason why I now suspect, when I click PAGE 2 or PAGE 3 on PAGINATION section, I see zero results or no rows shown. No rows are shown beyond page 1.

If I can LEARN from YOU why the ‘_SESSION['row_count'] = 5' auto vhanges to '_SESSION[‘row_count’] = 0’, mystery finish.

You see, after clicking SEARCH button, this part of code fetches $_SESSION[‘row_count’] = 5. That is good.

$query_1 = "SELECT COUNT(id) FROM users WHERE first_name = ? AND marital_status = ?";

$stmt_1 = mysqli_stmt_init($conn);
if(mysqli_stmt_prepare($stmt_1,$query_1))
{
            mysqli_stmt_bind_param($stmt_1,"ss",$_POST["first_name"],$_POST["marital_status"]);
mysqli_stmt_execute($stmt_1);
$result_1 = mysqli_stmt_bind_result($stmt_1,$row_count);
mysqli_stmt_fetch($stmt_1);
$_SESSION['row_count'] = $row_count;

I get displayed all matching rows on PAGE 1.
Since I set to display 1 row per page, I am shown 1 matching row on PAGE 1. This is good!

You see, when I click PAGE 2 on PAGINATION part, I expect to see the 2nd matching row, but “_SESSION['row_count'] = 5" switches to "_SESSION[‘row_count’] = 0” and so no matching rows display. Why this illegal switching of values from ‘5’ to ‘0’ when I click PAGE 2 or anything ?

This illegal switching ruins the following query you see below which runs when I click PAGE 2 or any PAGE (eg PAGE 3) after PAGE 1:

$row_count = $_SESSION['row_count'];
 //$total_pages = ceil($result_1/$result_per_page);
$total_pages = ceil($row_count/$result_per_page);

Context:

$query_2 = "SELECT id,first_name,middle_name,surname,gender,marital_status,working_status FROM users WHERE first_name = ? AND marital_status = ? LIMIT $offset,$last_row_on_page";
        echo "$query_2<br>";
        $stmt_2 = mysqli_stmt_init($conn);
        if(mysqli_stmt_prepare($stmt_2,$query_2))
        {echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 111.
            mysqli_stmt_bind_param($stmt_2,"ss",$_POST["first_name"],$_POST["marital_status"]);
            mysqli_stmt_execute($stmt_2);
            $result_2 = mysqli_stmt_get_result($stmt_2);
            echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 114.
            //Grab total number of pages to paginate.
            $row_count = $_SESSION['row_count'];
            //$total_pages = ceil($result_1/$result_per_page);
            $total_pages = ceil($row_count/$result_per_page);

Do find spare time to check my original code and see if you can know why “$_SESSION[‘row_count’]” switches from “5” to “0”.

Thank You!

But that elseif() is only triggered if your first if is not true (because of the else part), and your first if checks to see if $i < $total_pages). So the only time it ever gets into the elseif() is on the last pass, when $i is the same as $total_pages, because your outer loop runs until $i equals $total_pages.

Sorry, I’m on the way out and haven’t time to read the rest of the post, I’ll read it later if no-one else has already responded.

1 Like

Thank You now!
I do will double check what you say.
Now, if you no mind, when you come home from outside, can you see which criminal part of the code overwrites my session variable I said in my last post ?

You said …
but don’t forget that the LIMIT clause takes two parameters, the starting row and the number of rows to return. It doesn’t take the starting row and the ending row. It can take just the number of rows (ideal for the first page), but there isn’t a from-to option as your variable names suggest you are using.

I now confused not knowing how to fix these lines of mine if you think they are wrong:

$page_number = $_GET['page'];
$result_per_page = $_GET['page_limit'];
$offset = (($page_number * $result_per_page) - $result_per_page); //Offset (Row Number that 'Starts' on page).
$last_row_on_page = ($page_number * $result_per_page); //Max Result (Row Number that 'Ends' on page).
		
$previous_page = $page_number-1;
$next_page = $page_number+1;
echo "Row Start: $offset";echo "<br>";
echo "Row End: $last_row_on_page";echo "<br>";

Can you help me fix this ? I scratching my head.
A code example will be good idea.

Well, the documentation for LIMIT is quite clear. Your second parameter should be your $result_per_page value, if that is the number of rows you want on each page.

Have you moved your session_start() so that it appears before all browser output?

@droopsnoot,

Let me tell you what is it all about.
I created membership (login/register, logout, account homepage, pagination, etc.) pages before with helps of course from people like you. :wink: All procedural style and mysqli only. I confused about oop and pdo. I used to mysqli. Still beginner for long time now.

The membership script in past had about 10 different pages.
My new project is that, the membership script should be all in one page. I know this not a good idea but want to build those one page sites and I fond to fiddle a little to achieve something different and uniq. So, login, logout, register, search (pagination) all in one page now.
What code I just gave in this thread is the pagination part of the one page script that I getting hiccup on for about 10 nights now! The reg & login parts already work so not bothering mentioning them and wasting your time.

I did not bother mentioning them parts in this thread to keep the code to the point where I am having this HUG frsutrating issue for nearly 10 days now going round and round. Getting nowehere.
So, there you go. Now you know full pic.

I added session start at top now just under error reporting code line on 6 different php scripts. But no luck. Result of test still same.
You see, when I encountered this problem a week ago, I derived another script from it coding it a little different or shorter and faced the same issue. So, I then derived another and so on. Now, I scratching my head with total 6 versions and all of them encounter same problem. On one I used stmt_get_result(), on another stmt_bind_result and so on. Coding just little different to see if I can get over the current issue.
Anyway, like I say, I just added the session start at the top of all 6 files right below error reporting at the top, after someone suggested it. But no luck. No change in 6 scripts behaviours.
Another person suggested I switch from form method post to get but again no luck. Issue still staring in my face with big 2 eyes like a smiley!
This is a mystery now! For over a week been going round and round to dead end. Drat!

As for writing errors in a different file or whatever someone was advising, I have never done it and so don’t know how to proceed, unless ofcourse someone can point me in the right direction with a code snippet or a link to a url. But I don’t think writing errors in a separate file will solve this issue. Will just neaten up the code a tiny bit. Not wasting time going in a different, irrelevant, direction now. Got better things to do.

I have searched all over google for a tutorial with keywords like these but no luck for over a wk now:

“pagination tutorial AND mysqli AND prepared statements AND php”

Most tutorials are in oop or pdo or mysql extension. Or, on how to build pagination that displays whole table records (all rows). They no show tutorials (mysqli, prepared statement) how to show records based on “keyword search”. That is why I am doing things by myself reading php manual and getting ideas from tutorials here and there that are based on oop or pdo or mysql extension or based on “show all table records” (whatever I can find on google).

That issue of _SESSION['row_count'] = 5** switching to **_SESSION[‘row_count’] = 0 on every page load (same page, remember!), still remains.
(Remember, this membership script is a one page script).

If I can get over this hurdle of why the God Forsaken _SESSION['row_count'] = 5** AUTO switches to **_SESSION[‘row_count’] = 0 on every same page load, then this 2-3 months project is complete!

Can’t quit now right at the end. Or I wasted 2-3 months for nothing. I no give-up guy!

Can you post the current version of the code please?

1 Like

@droopsnoot,

Sorry for the late reply. Haven’t been online lately.
Here’s the latest version you asked for:

<?php
error_reporting(E_ALL);
session_start();
?>

<!DOCTYPE HTML">
<html>

<head>
<meta name="viewport" content="width-device=width, initial-scale=1">
</head>
<body>

<?php

if(!isset($_GET['query_type']) && empty($_GET['query_type']))
{
    die("Invalid Query!");
}
else
{
    $_SESSION['query_type'] = $_GET['query_type']; echo __LINE__; echo "<br>";//DELETE
}
echo __LINE__; echo "<br>";//DELETE

if(!isset($_GET['form_type']) && empty($_GET['form_type']))
{
    die("Invalid Form!");
}
else
{
    $_SESSION['form_type'] = $_GET['form_type']; echo __LINE__; echo "<br>";//DELETE
    
if(!function_exists($_SESSION['form_type']))
{
    die("Invalid Form!");
}
else
{echo __LINE__; echo "<br>";//DELETE
    if(!isset($_SESSION['form_step']))// || $_SESSION['form_step'] != 'end')
    {
        $_SESSION['form_step'] = 'start'; echo $_SESSION['form_step'];
        echo __LINE__; echo "<br>";//DELETE
        $_SESSION['form_type']();
    }
    else
    {
        $_SESSION['form_step'] = $_GET['form_step'];
        echo __LINE__; echo "<br>"; echo $_SESSION['form_step'];//DELETE
        $_SESSION['form_type']();
    }
}
}
        
//FUNCTIONS START FROM HERE
function search()
{echo __LINE__; echo "<br>";//DELETE
    function rows_count()
    {
        //Connect to Database. (DB_SERVER, BD_USERNAME, DB_PASSWORD, DB_NAME).
        mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        $conn = mysqli_connect("localhost","root","","powerpage");
        $conn->set_charset('utf8mb4'); //Always set Charset.
        
    if($conn === false)
    {
        die("ERROR: Connection Error!. " . mysqli_connect_error());
    }
    
    $query_1 = "SELECT COUNT(id) FROM users WHERE first_name = ? AND marital_status = ?";
    $stmt_1 = mysqli_stmt_init($conn);
    if(mysqli_stmt_prepare($stmt_1,$query_1))
    {
        mysqli_stmt_bind_param($stmt_1,"ss",$_POST["first_name"],$_POST["marital_status"]);
        mysqli_stmt_execute($stmt_1);
        $result_1 = mysqli_stmt_bind_result($stmt_1,$row_count);
        mysqli_stmt_fetch($stmt_1);
        $_SESSION['row_count'] = $row_count;
        echo __LINE__; echo "<br>";//DELETE
        $_SESSION['form_step'] = 'end'; //$form_step = 'end'; WRONG
        //fetch_rows();
    }
    //Close Statement.
    mysqli_stmt_close($stmt_1);
    //Close Connection.
    mysqli_close($conn);
}

function fetch_rows()
{   echo __LINE__; echo "<br>";//DELETE
    $form_step = $_GET['form_step'];
    
    $page_number = $_GET['page'];
    $result_per_page = $_GET['page_limit'];
    $offset = (($page_number * $result_per_page) - $result_per_page); //Offset (Row Number that 'Starts' on page).
    $last_row_on_page = ($page_number * $result_per_page); //Max Result (Row Number that 'Ends' on page).
    $previous_page = $page_number-1;
    $next_page = $page_number+1;
    
    echo "Row Start: $offset";echo "<br>";
    echo "Row End: $last_row_on_page";echo "<br>";
    
    //Connect to Database. (DB_SERVER, BD_USERNAME, DB_PASSWORD, DB_NAME).
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $conn = mysqli_connect("localhost","root","","powerpage");
    $conn->set_charset('utf8mb4'); //Always set Charset.

    if($conn === false)
    {
        die("ERROR: Connection Error!. " . mysqli_connect_error());
    }

    $query_2 = "SELECT * FROM users WHERE first_name = ? AND marital_status = ? ORDER BY id LIMIT $offset,$last_row_on_page";
    $stmt_2 = mysqli_stmt_init($conn);
    if(mysqli_stmt_prepare($stmt_2,$query_2))
    {echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 111.
        mysqli_stmt_bind_param($stmt_2,"ss",$_POST["first_name"],$_POST["marital_status"]);
        mysqli_stmt_execute($stmt_2);
        $result_2 = mysqli_stmt_get_result($stmt_2);
        echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 114.
        //Grab total number of pages to paginate.
        $row_count = $_SESSION['row_count'];
        //$total_pages = ceil($result_1/$result_per_page);
        $total_pages = ceil($row_count/$result_per_page);
        
        echo "TOTAL PAGES: $total_pages<br><br>";
        
        while($row = mysqli_fetch_array($result_2,MYSQLI_ASSOC))
        {echo __LINE__; echo "<br>";
            //Retrieve Values.
            $id = $row["id"];
            $first_name = $row["first_name"];
            $middle_name = $row["middle_name"];
            $surname = $row["surname"];
            $gender = $row["gender"];
            $marital_status = $row["marital_status"];
            $working_status = $row["working_status"];
            
            echo "Id: $id<br>";
            echo "First Name: $first_name<br>";
            echo "Middle Name: $middle_name<br>";
            echo "Surname: $surname<br>";
            echo "Gender: $gender<br>";
            echo "Marital Status: $marital_status<br>";
            echo "Working Status: $working_status<br>";
            echo "<br>";
            echo "<br>";
        }   
        $i = 1;
        while($i<=$total_pages)
        {
            if($i<$total_pages)
            {
                echo "<a href='http://localhost/power.page/pagination_test_simple_WORKING_ON_NOW_1.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=<?php echo $i;?>'><?php echo " $i ";?></a><?php 
            }
            elseif($i==$page_number)
            {
                echo "<a href='http://localhost/power.page/pagination_test_simple_WORKING_ON_NOW_1.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=<?php echo $i;?>'><?php echo "<b> $i </b>";?></a><?php 
            }
            
            $i++;
        }
        if($page_number>$total_pages)
        {
            echo "<a href='http://localhost/power.page/pagination_test_simple_WORKING_ON_NOW_1.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=<?php echo $previous_page;?>'><?php echo "<b> Previous </b>";?></a><?php 
        }
    }
    //Close Statement.
    mysqli_stmt_close($stmt_2);
    //Close Connection.
    mysqli_close($conn);
    
    $_SESSION['form_step'] = 'end';
    //die();
}
?>

<form action="<?php echo $_SERVER['PHP_SELF'];?>?form_type=<?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=1" method='post' enctype='plain/text'>
<?php

//Added '*' (asterisk) to indicate the 'Text Field' is a 'required' one.
echo "<label for=\"first_name\">First Name *:</label>
<input type=\"text\" name=\"first_name\" placeholder=\"First Name\" value = \"\">";?>
<br>
<?php
echo "<label for=\"marital_status\">Marital Status *:</label>";
echo "<select name=\"marital_status\">";
echo "<option value=\"single\">Single</option>";
echo "<option value=\"married\">Married</option>";
echo "</select>";
echo "<br>";
?>
<input type="submit" name="search" value="Search">
<?php
//$current_function = __FUNCTION__;
//echo $current_function;

//Do following if "Search" button clicked.
if($_SERVER['REQUEST_METHOD'] === 'POST')
{echo __LINE__; echo "<br>";//DELETE
    //Do following if "Search" button clicked.
    if(isset($_POST['search']))
    {echo __LINE__; echo "<br>";//DELETE
        rows_count(); //This function will forward script flow to fetch_rows() before halting the script.
        fetch_rows(); //On PAGINATION PAGE 2, THIS FUNCTION IS NOT GETTING TRIGGERED! WHY ? IT IS LINE: 200. MAIN ISSUE HERE, I SUSPECT.
        echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 201.
        die;
    }
}
echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS FAILS TO ECHO. IT IS LINE: 198.
//Do following if "Search" button not clicked but pagination numbered links are clicked. Eg Page 1, 2, 3, etc..
//rows_count(); //This function will forward script flow to fetch_rows() before halting the script.
fetch_rows(); //On PAGINATION PAGE 2, THIS FUNCTION IS NOT GETTING TRIGGERED! WHY ? IT IS LINE: 200. MAIN ISSUE HERE, I SUSPECT.
echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 201.
die;
}

?>

One person argued, I got my following 2 functions:
rows_count();
fetch_rows();

nested inside the search() function and I never call the search() function.
I argued back just now that I do call the search() function or how else would PAGE 1 show me row data ?

NOTE:
Url is:
http://localhost/power.page/pagination_test_simple_WORKING_ON_NOW_01.php?form_type=search&query_type=select&form_step=start&page_limit=2&page=1

php grabs the “form_type” via $_GET to determine what type of form it must display ? Should it display Registration Form ?, Login Form ? Database Search Form ?
In this case, it’s a database Search form.
“form_type=search”.

Note these lines:

 $_SESSION['form_type'] = $_GET['form_type']; //Line 32
$_SESSION['form_step'] = $_GET['form_step']; //Line 48
$_SESSION['form_type'](); //Line 52. Calling the "search()" from this point.

So now, right at the top of the page, the search() function gets triggered.
Inside this search(), rows_count() gets triggered and counts the matching rows to decdie how many pages (PAGE1, PAGE2, etc.) to display on pagination section.
Finally, fetch_rows() function fetches the rows and displays them on PAGE 1.

When you click PAGE 2 or any after PAGE 1, the rows_count() does not trigger again as matching rows count has already been determined while you were on PAGE 1. And so only the fetch_rows() triggers and it should fetch the matching rows for PAGE 2 or whatever page you are in but the fetch_rows() fails to fetch any rows because it wrongfully assumes there are no matching rows for PAGE 2, 3, etc. due to:
_SESSION['row_count'] = 5; auto switching to: _SESSION[‘row_count’] = 0;
when you clicked over to PAGE 2 or any page beyond PAGE 1.
Note, the value must not switch from “5” to “0” here or “0” is fed here:
$total_pages = ceil($row_count/$result_per_page);

In short droopsnoot, try to figure-out what the value of:
$_SESSION[‘row_count’]
auto switches when you headover to any PAGE (eg. PAGE 2, PAGE 3, PAGE 4) beyond PAGE 1.
Then I can solve this issue ASAP.

Your LIMIT parameters are still incorrect. Your second parameter should not be the last row that you want to retrieve, it should be the number of rows you want to retrieve.

Also there’s a random quote in here:

<!DOCTYPE HTML">

and your form enctype is invalid - it should be “text/plain” rather than “plain/text”.

You don’t close the <form> tag anywhere I can see.

Doubt these little HTML things are anything to do with your problem.

Hang on though, why are your rows_count() and fetch_rows() functions defined inside the search() function? What’s the point?

This one page script has many faces, my friend.
Note, it is a single page script.
Which is meaning: reg, login, search, blah, blah all in same one single page. Ok ?

Concentrate on this url format …
URL
http://localhost/power.page/pagination_test_simple_WORKING_ON_NOW_1.php?form_type=search&query_type=select&form_step=end&page_limit=2&page=1

form_type=search
form_type=login
form_type=personal_details

If form_type is ‘search’ then you’d be shown a search form/box. Like google boy.
If form_type is ‘login’ then you’d be shown a login form. Like hotmail girl.
If form_type is ‘personal_details’ then you’d be shown a submission form to submit your personal details. Like facebook bad boy.
If form_type is ‘link_submission’ then you’d be shown a submission form to submit your link. Like google boy.

So based on the ‘form_type’, you’d get shown appropriate webform (reg, login, personal_details, search db).

And so, by now, you realize, the same one page has many different faces (login, reg, submit details, submit link, search links, etc.) based on the “form_type” mentioned in the url.

Now, let’s forget about “personal_details”, “login” & “reg” cos (because) their parts/functions (personal_details(),login(), registration()) are working fine over here.
So now we look disappointedly at the search(). Which gone all crazy.
Now when form_type is ‘search’ you’d see a webform to make db queries. Let’s call this “member search”. Right now, I’m trying to build pagination for this “member search” feature.

Usually, when you create a pagination, you just code it in linear form.
I thought good to go if neatened up by adding the code in functions and then call the appropriate function as needed. This way, less code. Neater code.
I did manage to build the pagination in linear form. Then thought best to add the code in functions and call the functions when needed and shorten the code. That’s when I messed things up. And am stuck for forthnight now. Just about.

Like I said to you before, the search() gets triggered if the url contains “form_type=search”.
This rows_count() first counts all the matching rows to determine how many pages’ links to generate in our pagination section.
Then this fetch_rows() does the action by grabbing & displaying the matching rows.
fetch_rows() finds 5 row matches. Hence, shows 12345 pages on the pagination section cos I set it to show 1 row per page only (in dev mode).
fetch_rows() works here on PAGE 1 as it manages to display row 0 data.
It adds the value to _SESSION['row_count']. Then when you click PAGE 2/3/4/5 then this stupid _SESSION[‘row_count’] value idiotically auto switches it’s value to “0”. And so now, on PAGE 2/3/4/5 the fetch_rows() finds $_SESSION[‘row_count’] = 0 and assumes it should fetch zero rows. And fetches none. That is the problem.

Your Question:
Why rows_count() and fetch_rows() are inside the search() ?
It cos their codes are part of my search feature’s code.
Where do you want me to place them ? Inside login() or registration() ? That would be irrelevant as rows_count() and fetch_rows() are codes to build PAGINATION for the search feature and not for the registration or login feature.
You know what. I can do bring these 2 functions out of the search() but if in the future I need to make updates then I’d get confused to which part of the script do them 2 functions (rows_count() & fetch_rows() belong to. I’d then have to go through all the lengthy codes and remind myself they belong to the search feature. To avoid all this time-waste, I just added the 2 functions inside the search().
categorized things a little bit.

Anyway, when you clickover to PAGE 2,3,4,5 the search() does trigger as I intend. Also it triggers the rows_count() and fetch_rows() functions (when you clickover to PAGE 2,3,4 or 5). It is just that, the fetch_rows() function finds $_SESSION[‘row_count’] = 0 when PAGE 2/3/4/5 loads. That is why no matching rows get displayed on screen on pages 2/3/4/5.

Now tell me mr droopsnoot, what is making the _SESSION['row_count'] = 5 switch to _SESSION[‘row_count’] = 0 when PAGE 2/3/4/5 is loaded ?

Remember, when you are in this PAGE 1 url:

http://localhost/power.page/pagination_test_simple_WORKING_ON_NOW_1.php?form_type=search&query_type=select&form_step=end&page_limit=2&page=1

the $_SESSION[‘row_count’] = 5.
And so, the relevant row is fetched.

But, when you are in this PAGE 2/3/4/5, then all of a sudden for no reason, the big bad value becomes: $_SESSION[‘row_count’] = 0.
Hence, no matching rows get fetched for PAGE 1 onwards.

You mind to see if you can do learn what is causing this variable value to mess about auto switching from 5 to 0 ?
As for me, it’s nearly 2wks and I stuck in this quick-sand for long time now!

NOTE: $_SESSION[‘form_type’] = search.
And so, this following line triggers the search():

$_SESSION['form_type'](); 

@droopsnoot,

Do reply to my previous post before replying to this one.

You did not like me adding rows_count() and fetch_rows() inside search(). And so, I got them both out.
But still no luck.
You try:

<?php
error_reporting(E_ALL);
session_start();
?>

<!DOCTYPE HTML">
<html>

<head>
<meta name="viewport" content="width-device=width, initial-scale=1">
</head>
<body>

<?php

if(!isset($_GET['query_type']) && empty($_GET['query_type']))
{
    die("Invalid Query!");
}
else
{
    $_SESSION['query_type'] = $_GET['query_type']; echo __LINE__; echo "<br>";//DELETE
}
echo __LINE__; echo "<br>";//DELETE

if(!isset($_GET['form_type']) && empty($_GET['form_type']))
{
    die("Invalid Form!");
}
else
{
    $_SESSION['form_type'] = $_GET['form_type']; echo __LINE__; echo "<br>";//DELETE
    
if(!function_exists($_SESSION['form_type']))
{
    die("Invalid Form!");
}
else
{echo __LINE__; echo "<br>";//DELETE
    if(!isset($_SESSION['form_step']))// || $_SESSION['form_step'] != 'end')
    {
        $_SESSION['form_step'] = 'start'; echo $_SESSION['form_step'];
        echo __LINE__; echo "<br>";//DELETE
        $_SESSION['form_type']();
    }
    else
    {
        $_SESSION['form_step'] = $_GET['form_step'];
        echo __LINE__; echo "<br>"; echo $_SESSION['form_step'];//DELETE
        $_SESSION['form_type']();
    }
}
}
        
//FUNCTIONS START FROM HERE
function search()
{echo __LINE__; echo "<br>";//DELETE
    function rows_count()
    {
        //Connect to Database. (DB_SERVER, BD_USERNAME, DB_PASSWORD, DB_NAME).
        mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        $conn = mysqli_connect("localhost","root","","powerpage");
        $conn->set_charset('utf8mb4'); //Always set Charset.
        
    if($conn === false)
    {
        die("ERROR: Connection Error!. " . mysqli_connect_error());
    }
    
    $query_1 = "SELECT COUNT(id) FROM users WHERE first_name = ? AND marital_status = ?";
    $stmt_1 = mysqli_stmt_init($conn);
    if(mysqli_stmt_prepare($stmt_1,$query_1))
    {
        mysqli_stmt_bind_param($stmt_1,"ss",$_POST["first_name"],$_POST["marital_status"]);
        mysqli_stmt_execute($stmt_1);
        $result_1 = mysqli_stmt_bind_result($stmt_1,$row_count);
        mysqli_stmt_fetch($stmt_1);
        $_SESSION['row_count'] = $row_count;
        echo __LINE__; echo "<br>";//DELETE
        $_SESSION['form_step'] = 'end'; //$form_step = 'end'; WRONG
        //fetch_rows();
    }
    //Close Statement.
    mysqli_stmt_close($stmt_1);
    //Close Connection.
    mysqli_close($conn);
}

function fetch_rows()
{   echo __LINE__; echo "<br>";//DELETE
    $form_step = $_GET['form_step'];
    
    $page_number = $_GET['page'];
    $result_per_page = $_GET['page_limit'];
    $offset = (($page_number * $result_per_page) - $result_per_page); //Offset (Row Number that 'Starts' on page).
    $last_row_on_page = ($page_number * $result_per_page); //Max Result (Row Number that 'Ends' on page).
    $previous_page = $page_number-1;
    $next_page = $page_number+1;
    
    echo "Row Start: $offset";echo "<br>";
    echo "Row End: $last_row_on_page";echo "<br>";
    
    //Connect to Database. (DB_SERVER, BD_USERNAME, DB_PASSWORD, DB_NAME).
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $conn = mysqli_connect("localhost","root","","powerpage");
    $conn->set_charset('utf8mb4'); //Always set Charset.

    if($conn === false)
    {
        die("ERROR: Connection Error!. " . mysqli_connect_error());
    }

    $query_2 = "SELECT * FROM users WHERE first_name = ? AND marital_status = ? ORDER BY id LIMIT $offset,$last_row_on_page";
    $stmt_2 = mysqli_stmt_init($conn);
    if(mysqli_stmt_prepare($stmt_2,$query_2))
    {echo __LINE__; echo "<br>";
        mysqli_stmt_bind_param($stmt_2,"ss",$_POST["first_name"],$_POST["marital_status"]);
        mysqli_stmt_execute($stmt_2);
        $result_2 = mysqli_stmt_get_result($stmt_2);
        echo __LINE__; echo "<br>";
        //Grab total number of pages to paginate.
        $row_count = $_SESSION['row_count'];
		GLOBAL $row_count;
        //$total_pages = ceil($result_1/$result_per_page);
        $total_pages = ceil($row_count/$result_per_page);
        
        echo "TOTAL PAGES: $total_pages<br><br>";
        
        while($row = mysqli_fetch_array($result_2,MYSQLI_ASSOC))
        {echo __LINE__; echo "<br>";
            //Retrieve Values.
            $id = $row["id"];
            $first_name = $row["first_name"];
            $middle_name = $row["middle_name"];
            $surname = $row["surname"];
            $gender = $row["gender"];
            $marital_status = $row["marital_status"];
            $working_status = $row["working_status"];
            
            echo "Id: $id<br>";
            echo "First Name: $first_name<br>";
            echo "Middle Name: $middle_name<br>";
            echo "Surname: $surname<br>";
            echo "Gender: $gender<br>";
            echo "Marital Status: $marital_status<br>";
            echo "Working Status: $working_status<br>";
            echo "<br>";
            echo "<br>";
        }   
        $i = 1;
        while($i<=$total_pages)
        {
            if($i<$total_pages)
            {
                echo "<a href='http://localhost/power.page/stack.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=<?php echo $i;?>'><?php echo " $i ";?></a><?php 
            }
            elseif($i==$page_number)
            {
                echo "<a href='http://localhost/power.page/stack.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=<?php echo $i;?>'><?php echo "<b> $i </b>";?></a><?php 
            }
            
            $i++;
        }
        if($page_number>$total_pages)
        {
            echo "<a href='http://localhost/power.page/stack.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=<?php echo $previous_page;?>'><?php echo "<b> Previous </b>";?></a><?php 
        }
    }
    //Close Statement.
    mysqli_stmt_close($stmt_2);
    //Close Connection.
    mysqli_close($conn);
    
    $_SESSION['form_step'] = 'end';
    //die();
}
?>

<form action="<?php echo $_SERVER['PHP_SELF'];?>?form_type=<?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=1" method='POST' enctype='text/plain'>
<?php

//Added '*' (asterisk) to indicate the 'Text Field' is a 'required' one.
echo "<label for=\"first_name\">First Name *:</label>
<input type=\"text\" name=\"first_name\" placeholder=\"First Name\" value = \"\">";?>
<br>
<?php
echo "<label for=\"marital_status\">Marital Status *:</label>";
echo "<select name=\"marital_status\">";
echo "<option value=\"single\">Single</option>";
echo "<option value=\"married\">Married</option>";
echo "</select>";
echo "<br>";
?>
<input type="submit" name="search" value="Search">
<?php
//$current_function = __FUNCTION__;
//echo $current_function;

//Do following if "Search" button clicked.
if($_SERVER['REQUEST_METHOD'] === 'POST')
{echo __LINE__; echo "<br>";//DELETE
    //Do following if "Search" button clicked.
    if(isset($_POST['search']))
    {echo __LINE__; echo "<br>";//DELETE
        rows_count(); //This function will forward script flow to fetch_rows() before halting the script.
        fetch_rows(); //On PAGINATION PAGE 2, THIS FUNCTION IS NOT GETTING TRIGGERED! WHY ? IT IS LINE: 200. MAIN ISSUE HERE, I SUSPECT.
        echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 201.
        die;
    }
}
echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS FAILS TO ECHO. IT IS LINE: 198.
//Do following if "Search" button not clicked but pagination numbered links are clicked. Eg Page 1, 2, 3, etc..
//rows_count(); //This function will forward script flow to fetch_rows() before halting the script.
fetch_rows(); //On PAGINATION PAGE 2, THIS FUNCTION IS NOT GETTING TRIGGERED! WHY ? IT IS LINE: 200. MAIN ISSUE HERE, I SUSPECT.
echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 201.
die;
}

?>

No, just on their own as separate function definitions. I accept that it’s valid and legal syntax to have those functions defined inside the search() function definition, I just don’t see how it helps.

Change the names to make it more obvious, then. Or use separate scripts and include them as required.

I’ve no real idea. The layout of your code is horribly complicated to me, and it’s quite difficult to figure out exactly what goes where.

I’ve copied your code to my machine (and obviously changed things to use a database I have), and when I run it I get all sorts of things that I don’t imagine I should get. I expect that’s because you’ve excluded so much code from it. That’s a good thing, because if you’ve lumped everything into one massive file, there’s no way I’d pick my way through it. But I do wonder if you have extracted too much. For example in this part:

//Do following if "Search" button clicked.
if($_SERVER['REQUEST_METHOD'] === 'POST')
{echo __LINE__; echo "<br>";//DELETE
    //Do following if "Search" button clicked.
    if(isset($_POST['search']))
    {echo __LINE__; echo "<br>";//DELETE
        rows_count(); //This function will forward script flow to fetch_rows() before halting the script.
        fetch_rows(); //On PAGINATION PAGE 2, THIS FUNCTION IS NOT GETTING TRIGGERED! WHY ? IT IS LINE: 200. MAIN ISSUE HERE, I SUSPECT.
        echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 201.
        die;
    }
}
echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS FAILS TO ECHO. IT IS LINE: 198.
//Do following if "Search" button not clicked but pagination numbered links are clicked. Eg Page 1, 2, 3, etc..
//rows_count(); //This function will forward script flow to fetch_rows() before halting the script.
fetch_rows(); //On PAGINATION PAGE 2, THIS FUNCTION IS NOT GETTING TRIGGERED! WHY ? IT IS LINE: 200. MAIN ISSUE HERE, I SUSPECT.
echo __LINE__; echo "<br>";//On PAGINATION PAGE 2, THIS GETS ECHOED. IT IS LINE: 201.
die;
}

it’s running the code for page 2, 3, 4 and so on when I just open the page, because it’s not called as POST. So it doesn’t make debugging any easier.

Maybe if you split the code out into separate files for each individual function, it’d be easier to figure out what is going wrong with it.

1 Like

In what way have you “got them both out”?

function search()
{echo __LINE__; echo "<br>";//DELETE
    function rows_count()
    {

They’re no different to before.

And why is your LIMIT clause still using the wrong syntax? That’s another change I made to try to run this on my machine, along with fixing the html errors.

1 Like

When you call fetch_rows() for page 2, 3, 4 and so on, your if clause (I quoted it above) already knows that the request-method is not “POST”. So this bit of code:

  mysqli_stmt_bind_param($stmt_2,"ss",$_POST["first_name"],$_POST["marital_status"]);

is not going to have any variables to use, $_POST will be empty. You need to store the parameters somewhere for the subsequent pages.

1 Like

Blushing!
Sorry, I had probly sleep in eyes.
Here you go …

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
session_start();

//I WAS TOLD $_POST VALUES ARE LIKELY TO BE EMPTY ON PAGINATION PAGE 1,2,3,4,5. WAS ADVISED TO ADD THIS FOLLOWING CODE TO CHECK
echo "<pre>SESSION:\n".print_r($_SESSION, 1)."</pre>";
echo "<pre>POST:\n".print_r($_POST, 1)."</pre>";
?>

<!DOCTYPE HTML">
<html>

<head>
<meta name="viewport" content="width-device=width, initial-scale=1">
</head>
<body>

<?php

if(!isset($_GET['query_type']) && empty($_GET['query_type']))//'query_type' tells the script whether it is an INSERT or SELECT or UPDATE sql query. From this the script determines which type of form to display and what prepared statements lines to use.
{
    die("Invalid Query!");
}
else
{
    $_SESSION['query_type'] = $_GET['query_type']; 
	echo __LINE__; echo "<br>";//DELETE
}
echo __LINE__; echo "<br>";//DELETE

if(!isset($_GET['form_type']) && empty($_GET['form_type']))//'form_type' tells the script which form to display. (Login, Reg, Submit Personal Details, Submit Link).
{
    die("Invalid Form!");
}
else
{
    $_SESSION['form_type'] = $_GET['form_type']; 
	echo __LINE__; echo "<br>";//DELETE
    
	if(!function_exists($_SESSION['form_type']))
	{
		die("Invalid Form!");
	}
	else
	{echo __LINE__; echo "<br>";//DELETE
		if(!isset($_SESSION['form_step']))// || $_SESSION['form_step'] != 'end')
		{
			$_SESSION['form_step'] = 'start'; echo $_SESSION['form_step'];
			echo __LINE__; echo "<br>";//DELETE
			$_SESSION['form_type']();
		}
		else
		{
			$_SESSION['form_step'] = $_GET['form_step'];
			echo __LINE__; echo "<br>"; echo $_SESSION['form_step'];//DELETE
			$_SESSION['form_type']();
		}
	}
}

function search()
{
	echo __LINE__; echo "<br>";//DELETE
	//Do following if "Search" button clicked.
	if($_SERVER['REQUEST_METHOD'] === 'POST') //Doing following means "Search" button clicked AND pagination numbered links are NOT clicked. Eg page 2, 3, etc.
	{echo __LINE__; echo "<br>";//DELETE
		//Do following if "Search" button clicked.
		if(isset($_POST['search']))
		{echo __LINE__; echo "<br>";//DELETE
			rows_count();
			fetch_rows(); 
			echo __LINE__; echo "<br>";
			die;
		}
	}
	else //Doing following means "Search" button not clicked but pagination numbered links are clicked. Eg page 2, 3, etc.
	{
		echo __LINE__; echo "<br>";//DELETE
		//Do following if "Search" button not clicked but pagination numbered links are clicked. Eg Page 2, 3, etc..
		//rows_count(); //SHOULD I RUN THIS FUNCTION AGAIN FROM PAGE 2,3,4, ETC OR NOT ?
		fetch_rows();
		echo __LINE__; echo "<br>";//DELETE
	}
}


function rows_count()
{
	mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
	$conn = mysqli_connect("localhost","root","","powerpage");
	$conn->set_charset('utf8mb4'); //Always set Charset.
	
	if($conn === false)
	{
		die("ERROR: Connection Error!. " . mysqli_connect_error());
	}

	$query_1 = "SELECT COUNT(id) FROM users WHERE first_name = ? AND marital_status = ?";
	$_SESSION["first_name"] = $_POST["first_name"];//ADDED THIS NEW LINE.
	$_SESSION["marital_status"] = $_POST["marital_status"];//ADDED THIS NEW LINE.
	$stmt_1 = mysqli_stmt_init($conn);
	if(mysqli_stmt_prepare($stmt_1,$query_1))
	{
		//mysqli_stmt_bind_param($stmt_1,"ss",$_POST["first_name"],$_POST["marital_status"]);//SUBSTITUTED THIS LINE FOR THE LINE BELOW.
		mysqli_stmt_bind_param($stmt_1,"ss",$_SESSION["first_name"],$_SESSION["marital_status"]);//SUBSTITUTED TO THIS LINE FROM THE LINE ABOVE.
		mysqli_stmt_execute($stmt_1);
		$result_1 = mysqli_stmt_bind_result($stmt_1,$row_count);
		mysqli_stmt_fetch($stmt_1);
		$_SESSION['row_count'] = $row_count;
		echo __LINE__; echo "<br>";//DELETE
		$_SESSION['form_step'] = 'end';
		//fetch_rows();
	}
	//Close Statement.
	mysqli_stmt_close($stmt_1);
	//Close Connection.
	mysqli_close($conn);
}

function fetch_rows()
{   echo __LINE__; echo "<br>";//DELETE
    $form_step = $_GET['form_step'];
    
    $page_number = $_GET['page'];
    $result_per_page = $_GET['page_limit'];
    $offset = (($page_number * $result_per_page) - $result_per_page); //Offset (Row Number that 'Starts' on page).
    $last_row_on_page = ($page_number * $result_per_page); //Max Result (Row Number that 'Ends' on page).
    $previous_page = $page_number-1;
    $next_page = $page_number+1;
    
    echo "Row Start: $offset";echo "<br>";
    echo "Row End: $last_row_on_page";echo "<br>";
    
    //Connect to Database. (DB_SERVER, BD_USERNAME, DB_PASSWORD, DB_NAME).
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $conn = mysqli_connect("localhost","root","","powerpage");
    $conn->set_charset('utf8mb4'); //Always set Charset.

    if($conn === false)
    {
        die("ERROR: Connection Error!. " . mysqli_connect_error());
    }

    $query_2 = "SELECT * FROM users WHERE first_name = ? AND marital_status = ? ORDER BY id LIMIT $offset,$last_row_on_page";
    $stmt_2 = mysqli_stmt_init($conn);
    if(mysqli_stmt_prepare($stmt_2,$query_2))
    {echo __LINE__; echo "<br>";
		//mysqli_stmt_bind_param($stmt_2,"ss",$_POST["first_name"],$_POST["marital_status"]);//SUBSTITUTED THIS LINE FOR THE LINE BELOW.
        mysqli_stmt_bind_param($stmt_2,"ss",$_SESSION["first_name"],$_SESSION["marital_status"]);//SUBSTITUTED TO THIS LINE FROM THE LINE ABOVE.
        mysqli_stmt_execute($stmt_2);
        $result_2 = mysqli_stmt_get_result($stmt_2);
        echo __LINE__; echo "<br>";
        //Grab total number of pages to paginate.
        $row_count = $_SESSION['row_count'];
		//$total_pages = ceil($result_1/$result_per_page);
        $total_pages = ceil($row_count/$result_per_page);
        
        echo "TOTAL PAGES: $total_pages<br><br>";
        
        while($row = mysqli_fetch_array($result_2,MYSQLI_ASSOC))
        {echo __LINE__; echo "<br>";
            //Retrieve Values.
            $id = $row["id"];
            $first_name = $row["first_name"];
            $middle_name = $row["middle_name"];
            $surname = $row["surname"];
            $gender = $row["gender"];
            $marital_status = $row["marital_status"];
            $working_status = $row["working_status"];
            
            echo "Id: $id<br>";
            echo "First Name: $first_name<br>";
            echo "Middle Name: $middle_name<br>";
            echo "Surname: $surname<br>";
            echo "Gender: $gender<br>";
            echo "Marital Status: $marital_status<br>";
            echo "Working Status: $working_status<br>";
            echo "<br>";
            echo "<br>";
        }   
        $i = 1;
        while($i<=$total_pages)
        {
            if($i<$total_pages)
            {
                echo "<a href='http://localhost/power.page/stack.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=<?php echo $i;?>'><?php echo " $i ";?></a><?php 
            }
            elseif($i==$page_number)
            {
                echo "<a href='http://localhost/power.page/stack.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=<?php echo $i;?>'><?php echo "<b> $i </b>";?></a><?php 
            }
            
            $i++;
        }
        if($page_number>$total_pages)
        {
            echo "<a href='http://localhost/power.page/stack.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=<?php echo $previous_page;?>'><?php echo "<b> Previous </b>";?></a><?php 
        }
    }
    //Close Statement.
    mysqli_stmt_close($stmt_2);
    //Close Connection.
    mysqli_close($conn);
    
    $_SESSION['form_step'] = 'end';
	echo $_POST["first_name"];// THESE ARE FAILING TO ECHO!
	echo $_POST["marital_status"];// THESE ARE FAILING TO ECHO!
    //die();
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>?form_type=<?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=1" method='POST' enctype='text/plain'>
<?php

//Added '*' (asterisk) to indicate the 'Text Field' is a 'required' one.
echo "<label for=\"first_name\">First Name *:</label>
<input type=\"text\" name=\"first_name\" placeholder=\"First Name\" value = \"\">";?>
<br>
<?php
echo "<label for=\"marital_status\">Marital Status *:</label>";
echo "<select name=\"marital_status\">";
echo "<option value=\"single\">Single</option>";
echo "<option value=\"married\">Married</option>";
echo "</select>";
echo "<br>";
?>
<input type="submit" name="search" value="Search">
</form>

I will read your other comments then try updating to your advice.
You welcome to play around with this latest code above.
Do read comments in the code. I updated a little for you to be understanding my intentions.

Thank You

@droopsnoot,

Oops! I forgot to change the following on my latest code and so do disregard it.

$last_row_on_page = ($page_number * $result_per_page); //Max Result (Row Number that 'Ends' on page).

With the updated code, that you see on previous post, where I separated the rows_count() and fetch_rows() outside of search(),
I experience a new problem. This time, after clicking the SEARCH button, no results are shown even on PAGE 1 now!

@droopsnoot,

Any chance you can manage do short this code a little bit more so no looking cluttered ?

Ok, let’s assume my search() loads on page 2,3,4,5 etc. and all these form inputs vanish. This meaning, values of _post['first_name'] & _post[‘marital_status’] are vanishing as soon as I load page 2.
To prevent this disappearancing act, I added these:

$_SESSION["first_name"] = $_POST["first_name"];//ADDED THIS NEW LINE.
$_SESSION["marital_status"] = $_POST["marital_status"];//ADDED THIS NEW LINE.

Added the _POSTs to _SESSIONs.

Look here again I did it also so not forgotten atall this part …

//mysqli_stmt_bind_param($stmt_1,"ss",$_POST["first_name"],$_POST["marital_status"]);//SUBSTITUTED THIS LINE FOR THE LINE BELOW.

mysqli_stmt_bind_param($stmt_1,"ss",$_SESSION["first_name"],$_SESSION["marital_status"]);//SUBSTITUTED TO THIS LINE FROM THE LINE ABOVE.

Now update looks like this …
Note URGENT:
I have dragged out rows_count() and fetch_rows() out of search() function as was advised to separate them.
Now what ? This time I get displayed no results even on PAGE 1!!!
Last time the issue was PAGE 1 was showing the search results but not any page after PAGE 1. Not page 2/3/4/5.
This time, it’s worst. Even PAGE 1 doesn’t show any results! I am lost now. Totally!

CODE

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
session_start();

//I WAS TOLD $_POST VALUES ARE LIKELY TO BE EMPTY ON PAGINATION PAGE 1,2,3,4,5. WAS ADVISED TO ADD THIS FOLLOWING CODE TO CHECK.
echo "<pre>SESSION:\n".print_r($_SESSION, 1)."</pre>";
echo "<pre>POST:\n".print_r($_POST, 1)."</pre>";
?>

<!DOCTYPE HTML">
<html>

<head>
<meta name="viewport" content="width-device=width, initial-scale=1">
</head>
<body>

<?php

if(!isset($_GET['query_type']) && empty($_GET['query_type']))//'query_type' tells the script whether it is an INSERT or SELECT or UPDATE sql query. From this the script determines which type of form to display and what prepared statements lines to use.
{
    die("Invalid Query!");
}
else
{
    $_SESSION['query_type'] = $_GET['query_type']; 
	echo __LINE__; echo "<br>";//DELETE
}
echo __LINE__; echo "<br>";//DELETE

if(!isset($_GET['form_type']) && empty($_GET['form_type']))//'form_type' tells the script which form to display. (Login, Reg, Submit Personal Details, Submit Link).
{
    die("Invalid Form!");
}
else
{
    $_SESSION['form_type'] = $_GET['form_type']; 
	echo __LINE__; echo "<br>";//DELETE
    
	if(!function_exists($_SESSION['form_type']))
	{
		die("Invalid Form!");
	}
	else
	{echo __LINE__; echo "<br>";//DELETE
		if(!isset($_SESSION['form_step']))// || $_SESSION['form_step'] != 'end')
		{
			$_SESSION['form_step'] = 'start'; echo $_SESSION['form_step'];
			echo __LINE__; echo "<br>";//DELETE
			$_SESSION['form_type']();
		}
		else
		{
			$_SESSION['form_step'] = $_GET['form_step'];
			echo __LINE__; echo "<br>"; echo $_SESSION['form_step'];//DELETE
			$_SESSION['form_type']();
		}
	}
}

function search()
{
	echo __LINE__; echo "<br>";//DELETE
	//Do following if "Search" button clicked.
	if($_SERVER['REQUEST_METHOD'] === 'POST') //Doing following means "Search" button clicked AND pagination numbered links are NOT clicked. Eg page 2, 3, etc.
	{echo __LINE__; echo "<br>";//DELETE
		//Do following if "Search" button clicked.
		if(isset($_POST['search']))
		{echo __LINE__; echo "<br>";//DELETE
			rows_count();
			fetch_rows(); 
			echo __LINE__; echo "<br>";
			die;
		}
	}
	else //Doing following means "Search" button not clicked but pagination numbered links are clicked. Eg page 2, 3, etc.
	{
		echo __LINE__; echo "<br>";//DELETE
		//Do following if "Search" button not clicked but pagination numbered links are clicked. Eg Page 2, 3, etc..
		//rows_count(); //SHOULD I RUN THIS FUNCTION AGAIN FROM PAGE 2,3,4, ETC OR NOT ?
		fetch_rows();
		echo __LINE__; echo "<br>";//DELETE
	}
}


function rows_count()
{
	mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
	$conn = mysqli_connect("localhost","root","","powerpage");
	$conn->set_charset('utf8mb4'); //Always set Charset.
	
	if($conn === false)
	{
		die("ERROR: Connection Error!. " . mysqli_connect_error());
	}

	$query_1 = "SELECT COUNT(id) FROM users WHERE first_name = ? AND marital_status = ?";
	$_SESSION["first_name"] = $_POST["first_name"];//ADDED THIS NEW LINE.
	$_SESSION["marital_status"] = $_POST["marital_status"];//ADDED THIS NEW LINE.
	$stmt_1 = mysqli_stmt_init($conn);
	if(mysqli_stmt_prepare($stmt_1,$query_1))
	{
		//mysqli_stmt_bind_param($stmt_1,"ss",$_POST["first_name"],$_POST["marital_status"]);//SUBSTITUTED THIS LINE FOR THE LINE BELOW.
		mysqli_stmt_bind_param($stmt_1,"ss",$_SESSION["first_name"],$_SESSION["marital_status"]);//SUBSTITUTED TO THIS LINE FROM THE LINE ABOVE.
		mysqli_stmt_execute($stmt_1);
		$result_1 = mysqli_stmt_bind_result($stmt_1,$row_count);
		mysqli_stmt_fetch($stmt_1);
		$_SESSION['row_count'] = $row_count;
		echo __LINE__; echo "<br>";//DELETE
		$_SESSION['form_step'] = 'end';
		//fetch_rows();
	}
	//Close Statement.
	mysqli_stmt_close($stmt_1);
	//Close Connection.
	mysqli_close($conn);
}

function fetch_rows()
{   echo __LINE__; echo "<br>";//DELETE
    $form_step = $_GET['form_step'];
    
    $page_number = $_GET['page'];
    $result_per_page = $_GET['page_limit'];
    $offset = (($page_number * $result_per_page) - $result_per_page); //Offset (Row Number that 'Starts' on page).
    $last_row_on_page = ($page_number * $result_per_page); //Max Result (Row Number that 'Ends' on page).
    $previous_page = $page_number-1;
    $next_page = $page_number+1;
    
    echo "Row Start: $offset";echo "<br>";
    echo "Row End: $last_row_on_page";echo "<br>";
    
    //Connect to Database. (DB_SERVER, BD_USERNAME, DB_PASSWORD, DB_NAME).
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $conn = mysqli_connect("localhost","root","","powerpage");
    $conn->set_charset('utf8mb4'); //Always set Charset.

    if($conn === false)
    {
        die("ERROR: Connection Error!. " . mysqli_connect_error());
    }

    $query_2 = "SELECT * FROM users WHERE first_name = ? AND marital_status = ? ORDER BY id LIMIT $offset,$last_row_on_page";
    $stmt_2 = mysqli_stmt_init($conn);
    if(mysqli_stmt_prepare($stmt_2,$query_2))
    {echo __LINE__; echo "<br>";
		//mysqli_stmt_bind_param($stmt_2,"ss",$_POST["first_name"],$_POST["marital_status"]);//SUBSTITUTED THIS LINE FOR THE LINE BELOW.
        mysqli_stmt_bind_param($stmt_2,"ss",$_SESSION["first_name"],$_SESSION["marital_status"]);//SUBSTITUTED TO THIS LINE FROM THE LINE ABOVE.
        mysqli_stmt_execute($stmt_2);
        $result_2 = mysqli_stmt_get_result($stmt_2);
        echo __LINE__; echo "<br>";
        //Grab total number of pages to paginate.
        $row_count = $_SESSION['row_count'];
		//$total_pages = ceil($result_1/$result_per_page);
        $total_pages = ceil($row_count/$result_per_page);
        
        echo "TOTAL PAGES: $total_pages<br><br>";
        
        while($row = mysqli_fetch_array($result_2,MYSQLI_ASSOC))
        {echo __LINE__; echo "<br>";
            //Retrieve Values.
            $id = $row["id"];
            $first_name = $row["first_name"];
            $middle_name = $row["middle_name"];
            $surname = $row["surname"];
            $gender = $row["gender"];
            $marital_status = $row["marital_status"];
            $working_status = $row["working_status"];
            
            echo "Id: $id<br>";
            echo "First Name: $first_name<br>";
            echo "Middle Name: $middle_name<br>";
            echo "Surname: $surname<br>";
            echo "Gender: $gender<br>";
            echo "Marital Status: $marital_status<br>";
            echo "Working Status: $working_status<br>";
            echo "<br>";
            echo "<br>";
        }   
        $i = 1;
        while($i<=$total_pages)
        {
            if($i<$total_pages)
            {
                echo "<a href='http://localhost/power.page/stack.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=<?php echo $i;?>'><?php echo " $i ";?></a><?php 
            }
            elseif($i==$page_number)
            {
                echo "<a href='http://localhost/power.page/stack.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=<?php echo $i;?>'><?php echo "<b> $i </b>";?></a><?php 
            }
            
            $i++;
        }
        if($page_number>$total_pages)
        {
            echo "<a href='http://localhost/power.page/stack.php?form_type=";?><?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=<?php echo $previous_page;?>'><?php echo "<b> Previous </b>";?></a><?php 
        }
    }
    //Close Statement.
    mysqli_stmt_close($stmt_2);
    //Close Connection.
    mysqli_close($conn);
    
    $_SESSION['form_step'] = 'end';
	echo $_POST["first_name"];// THESE ARE FAILING TO ECHO!
	echo $_POST["marital_status"];// THESE ARE FAILING TO ECHO!
    //die();
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>?form_type=<?php echo $_SESSION['form_type'];?>&query_type=<?php echo $_SESSION['query_type'];?>&form_step=end&page_limit=2&page=1" method='POST' enctype='text/plain'>
<?php

//Added '*' (asterisk) to indicate the 'Text Field' is a 'required' one.
echo "<label for=\"first_name\">First Name *:</label>
<input type=\"text\" name=\"first_name\" placeholder=\"First Name\" value = \"\">";?>
<br>
<?php
echo "<label for=\"marital_status\">Marital Status *:</label>";
echo "<select name=\"marital_status\">";
echo "<option value=\"single\">Single</option>";
echo "<option value=\"married\">Married</option>";
echo "</select>";
echo "<br>";
?>
<input type="submit" name="search" value="Search">
</form>

I am curious to see how much droopsnoot can become kind to neaten up my code by keeping it procedural stylish and mysqli and no pdo as I know no pdo or know no oop. And keeping it at prepared statement like I shown above. :wink:

Why is your form enctype “text/plain”? What does that achieve that leaving it out would not?

1 Like