@idrisalisylbd idrisalisylbd As you can see there many “big boys” in this forum who know a lot more than I do… I do what I know and that can always be improved upon… I suppose you are looking for something like this.
These are the changes I made to your sample code.
I added a MySQLi Object-Oriented connection at the top of the page as well as
session_start();
so search values can be saved instead of using
$_GET
as I really can’t stand any
$_GET
values being passed to a query. I also defined
$pagename
to be used in the pagination code. More on this in a bit. Other factors I left alone.
<?php
session_start();
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(E_ALL);
$conn = new mysqli("localhost", "root","","buzz");
mysqli_set_charset($conn,'utf8mb4');
$pagename = $_SERVER['PHP_SELF'];
Now these “big dogs” have shown us a pretty cool way of building your query using $comparison
but I just went with your $col_
approach though I only used 1 main query and defined how fields are being compared by. Maybe not as cool but it works.
$compareby =($match == "exact" ? "=" : "LIKE");
So moving ahead, we need to build an array of search values, 1 for each field you are querying against so In the section where you are building your $col_
array we can also build an array $searchvalues
… There is also the need to add %
around your search term when using your “fuzzy” LIKE
condition so I defined $fuzzy
like so it will be %
or blank.
$fuzzy = (!empty($match) && $match == "fuzzy" ? "%" : '');
Note: I define array variables as arrays before adding values to them. This for
section now looks like this. Also note by placing %
on both sides of the term allows for partial work searching such as og
would match with frog
. See image above were I add random words for testing…
$col_ = array();
$searchvalues = array();
$fuzzy = (!empty($match) && $match == "fuzzy" ? "%" : '');
for($i=0;$i!==$table_columns_number;$i++)
{
$col_[$i] = ${$table}[$i];
$searchvalues[] = $fuzzy.$search.$fuzzy;
}
We also define the page and offset before the query.
$page = (!empty($_GET['pg']) ? intval($_GET['pg']) : 1);
$offset = ($page*$limit)-$limit;
We now build the query adding the $compareby
variable where needed much like you already had. Note I changed your count query to call COUNT(*) as 'cnt'
so it will return a single record with the count defined to the field ‘cnt’.
$compareby =($match == "exact" ? "=" : "LIKE");
$sql_count = "SELECT COUNT(*) as 'cnt' from $table WHERE $col_[0] ".$compareby." ?";
$sql = "SELECT * from $table WHERE $col_[0] ".$compareby." ?";
for($i=1;$i!==$table_columns_number;$i++)
{
$sql_count .= " OR $col_[$i] ".$compareby." ?";
$sql .= " OR $col_[$i] ".$compareby." ?";
}
$sql .= " ORDER BY `id` DESC LIMIT ".$limit." OFFSET ".$offset;
These queries can now be prepared and executed like so.
////////////////////////////////////////
$bindString = str_repeat("s",$table_columns_number);
////////////////////////////////////////
$query_count = $conn->prepare($sql_count);
$query_count->bind_param($bindString, ...$searchvalues);
$query_count->execute();
$result_count = $query_count->get_result();
$row_count = $result_count->fetch_assoc();
$rows_count = $row_count['cnt'];
//echo $rows_count;
////////////////////////////////////////
$query = $conn->prepare($sql);
$query->bind_param($bindString, ...$searchvalues);
$query->execute();
$result = $query->get_result();
You could now use while
and print_r()
the table rows to see the results (but I’ll use the while
statement in the display section).
while($row = $result->fetch_assoc()){
echo "<pre>";
print_r($row);
echo "</pre>";
}
Your display table can be dynamic based off those field
arrays you made. The fields however may not be the best for showing as headings. One option is to build a headings array for all fields in your tables with the field names as KEYs => Displayed Name as the value. I place this right below your $links
field arrays so new fields can be added at any time.
$headings = array(
'id' => "ID"
,'date_and_time' => "Date and Time"
,'domain' => "Domain"
,'url' => "URL"
,'title' => "Title"
,'header' => "Header"
,'meta_keyword' => "Meta Keyword"
,'meta_description' => "Meta Description"
,'description' => "Description"
,'keyword' => "Keyword"
,'keyphrase' => "Key Phrase"
);
You are identifying your field
array with (${$table})
so we write an IF condition to check if this is an array and we wrap the display in this condition as our display is built off the selected array.
if(is_array(${$table})):
endif;
Inside this we can build our table using foreach
to loop through (${$table}) field and use the $headings
array to get the display heading based on the field in the <th>
columns.
We can use the variable set by the “count” query $rows_count
in another IF condition to tell use if there are results to loop through.much like we did for the headings only this time the field is paired with $row
to give us the value for the <td>
cells.
if(is_array(${$table})):
echo '<table class="queuelist">
<tr>'."\r";
foreach((${$table}) as $field):
echo '<th>'.$headings[$field].'</th>'."\r";
endforeach;
echo '</tr>'."\r";
if(!empty($rows_count)):
while($row = $result->fetch_assoc()){
echo '<tr>'."\r";
foreach((${$table}) as $field):
echo '<td>'.$row[$field].'</td>'."\r";
endforeach;
echo '</tr>'."\r";
}
endif;
echo '</table>'."\r";
endif;
Now lets see about getting your <form>
working. There were some changes made like changing the action
attribute to post and changing input names for consistency to the code being used and adding the name ‘web_search’ to your submit button.
I am not sure if you realize what limit
represents on your form and how applies to your query. This is going to the number of records queried for and shown on a “page”. If it were even possible grab 1000000 records and display them on a page without the server crashing, I don’t know if anyone could or would want to scroll through that many records. A reasonable cutoff might be 100 records per page.
Using foreach()
and range()
you can biuld your <option>
s in a more dynamic way. In Fact for the fun of it I made a version with 3 steps. You see range allows you to set a start and end number plus a step by value. For example; 1 to 9 by 2
will give you 1,3,5,7,9. The next step I did was 10 to 25 by 5
then I did 30 to 100 by 10
. These give you more options for viewing.
foreach(range(1,9,2) as $r):
$selected_records_shown = (isset($_SESSION['limit']) && $_SESSION['limit'] == $r ? ' selected="selected"' : '');
echo '<option value="'.$r.'"'.$selected_records_shown.'>'.$r.'</option>'."\r";
endforeach;
foreach(range(10,25,5) as $r):
$selected_records_shown = (isset($_SESSION['limit']) && $_SESSION['limit'] == $r ? ' selected="selected"' : '');
echo '<option value="'.$r.'"'.$selected_records_shown.'>'.$r.'</option>'."\r";
endforeach;
foreach(range(30,100,10) as $r):
$selected_records_shown = (isset($_SESSION['limit']) && $_SESSION['limit'] == $r ? ' selected="selected"' : '');
echo '<option value="'.$r.'"'.$selected_records_shown.'>'.$r.'</option>'."\r";
endforeach;
I am not sure why your form is in a function but to get values back into the function so you can have checked="checked"
etc they need to be passed when the function is called and picked up in the same way.
search_form($table,$match,$search,$table,$limit);
and
function search_form($table,$match,$search,$index,$limit)
then those variables are present in the function.
So now we can now process the form and sure you can could set the post value directly to a variable like $table = $_POST['table'];
but because we are using $_GET
for pagination any information that was set by POST would now be gone as new $_GET
instances are presented. So what I did is save the 4 search values to session so they will remain as the page reloads.
We check $_POST['table']
against the $tables
array of defined tables and set defaults if not defined correctly before setting to session. These 4 search values are wrapped in the button name IF condition. Note: I also unset($_GET['pg']);
so the query is NOT looking for example page 5 when a NEW search might only have 1 page of records.
if($_SERVER['REQUEST_METHOD']=='POST' && isset($_POST['web_search'])):
$_SESSION['table'] = (!empty($_POST['table']) && in_array($_POST['table'], $tables) ? $_POST['table'] : 'links_crawls');
$_SESSION['search'] = (!empty($_POST['search']) ? $_POST['search'] : '');
$_SESSION['match'] = (!empty($_POST['match']) ? $_POST['match'] : 'fuzzy');
$_SESSION['limit'] = (!empty($_POST['limit']) ? $_POST['limit'] : 1);
unset($_GET['pg']);
endif;
I also add a Clear
button to the form and when pressed triggers this section of code to unset()
those session values so you can start again.
if($_SERVER['REQUEST_METHOD']=='POST' && isset($_POST['clear_search'])):
unset($_SESSION['table']);
unset($_SESSION['search']);
unset($_SESSION['match']);
unset($_SESSION['limit']);
unset($_GET['pg']);
header("location: ".$pagename);
exit;
endif;
Because session value may or may not be set I do not use them directly in the query. I set variables “like” the hard coded ones you had with the session values if available or default values. Now after searching and reloading the page your search is still active allowing for pagination.
$table = (!empty($_SESSION['table']) ? $_SESSION['table'] : 'links_crawls');
$search = (!empty($_SESSION['search']) ? $_SESSION['search'] : '');
$match = (!empty($_SESSION['match']) ? $_SESSION['match'] : 'fuzzy'); //exact fuzzy
$limit = (!empty($_SESSION['limit']) ? $_SESSION['limit'] : 1);
Those 4 search terms are required for the query so we wrap the query code section with the IF condition checking that these variables are not empty.
if(!empty($table) && !empty($search) && !empty($match) && !empty($limit)):
//Query
endif;
I’ll save pagination code for another chapter of this novel.