How to stop URL query string from repeating? - php

I'm using a URL query string to filter MySQL search results. When a user clicks on one of the links the query along with another variable is passed to the application, which then builds and executes a SQL query to the database.
The filtering works - the user can filter by genre, platform and can also sort at the same time, but the problem is that every time they click on a link it adds another variable at the end of $query.
For example if the user types in example and selects as filter, the genre action, the query looks like this:
keywords=example&genre=action
But lets say they then click on the adventure genre, the query then looks like this:
keywords=example&genre=action&genre=adventure
Is there a way to get the query to replace a variable if it isalready set?
$query = mysql_real_escape_string(htmlentities(trim($_SERVER[QUERY_STRING])));
<div id="filter_nav">
<ul id="nav_form">
<li><h3 id="h3">Genre: </h3>
<li>Fighting</li>
<li>Role-Playing</li>
<li>Action</li>
</ul>
<ul id="nav_form">
<li><h3 id="h3">Platform: </h3>
<li>PS3</li>
<li>Xbox 360</li>
<li>Gamecube</li>
</ul>
</div>
';
echo '
<ul id="sorting_form">
<li><h3 id="h3">SORT BY: </h3>
<li>Title</li>
<li>Date</li>
<li>Rating</li>
</ul>
';
function search_results($keywords){
$returned_results = array();
$where = "";
$keywords = preg_split('/[\s]+/', $keywords);
$total_keywords = count($keywords);
foreach($keywords as $key=>$keyword){
$where .= "title LIKE '%$keyword%'";
if($key != ($total_keywords - 1)){
$where .= " AND ";
}
}
if (isset($_GET['platform']) && !empty($_GET['platform'])){
$platform = mysql_real_escape_string(htmlentities(trim($_GET['platform'])));
$where .= " AND platform='$platform'";
}
if (isset($_GET['genre']) && !empty($_GET['genre'])){
$genre = mysql_real_escape_string(htmlentities(trim($_GET['genre'])));
$where .= " AND genre='$genre'";
}
if (isset($_GET['order']) && !empty($_GET['order'])){
$order = mysql_real_escape_string(htmlentities(trim($_GET['order'])));
$where .= " ORDER BY $order DESC";
}
$results ="SELECT * FROM games WHERE $where ";

Using your code it can be done de-constructing the query string using parse_url and rebuilding it using http_build_query for every link.
However, personally I would just go for a form with 3 select boxes where the previously selected values are pre-selected.
You could put all your selection options in one multi-dimensional array and do a double loop.
Example:
<?php
$options = array(
"genre" => array("Fighting", "Role-Playing", ...),
...
);
foreach $options as $key => $value)
{
?>
<select name="<?php echo $key; ?>">
<?php
foreach ($value as $item)
{
// echo option for item and mark it selected if necessary
}
?>
</select>
<?php
}
?>

Modify every <a> tag like:
Fighting
to
Fighting
I.e remove '.$query.' part.

Related

how to find correct row or similar row from the mysql if user entered string or keywords into search field?

Below is my PHP code which find the result from mysql table what is typed by user search to search field. It is also finds if user has typed something randomly and find the matching row fetch from the database and show to user. But there is one problem it will fetch the record from the databse as they are sequentially store into the database. but i want is it will show the result which matches the most of the keywords or sentence which is type by user. for example user searching for "search and pagination with php" and all the records are fetch from the database
results:
1. PHP RSS Feed Read and List2.DropDown with Search using jQuery 3.PHP CRUD with Search and Pagination 4.PHP MySQL Date Range Search with jQuery DatePicker"
This is how my code is working. But i want is that result 3rd should be came 1st positon beacuse it matches the greater number of keywords matching and others should also came after that because it have some matching keywords. I have also attached the screenshot of same result screenshot.
If we are searching something in google we are search just randomly. everyone searching type is different but topic is same so google will return the exact result even if type in another way or spelling is typed wrong. How can I do that or what are changes I have to make in code. and If I want to add auto suggestions like google then How can I do that. I want a search field which works like google or StackOverflow for finding the result which has similar or matching results in PHP.
<?php
$conn = mysqli_connect("localhost", "root", "", "blog_samples");
$with_any_one_of = "";
$with_the_exact_of = "";
$without = "";
$starts_with = "";
$search_in = "";
$advance_search_submit = "";
$queryCondition = "";
if(!empty($_POST["search"])) {
$advance_search_submit = $_POST["advance_search_submit"];
foreach($_POST["search"] as $k=>$v){
if(!empty($v)) {
$queryCases = array("with_any_one_of","with_the_exact_of","without","starts_with");
if(in_array($k,$queryCases)) {
if(!empty($queryCondition)) {
$queryCondition .= " AND ";
} else {
$queryCondition .= " WHERE ";
}
}
switch($k) {
case "with_any_one_of":
$with_any_one_of = $v;
$wordsAry = explode(" ", $v);
$wordsCount = count($wordsAry);
for($i=0;$i<$wordsCount;$i++) {
if(!empty($_POST["search"]["search_in"])) {
$queryCondition .= $_POST["search"]["search_in"] . " LIKE '%" . $wordsAry[$i] . "%'";
} else {
$queryCondition .= "title LIKE '" . $wordsAry[$i] . "%' OR description LIKE '" . $wordsAry[$i] . "%'";
}
if($i!=$wordsCount-1) {
$queryCondition .= " OR ";
}
}
break;
}
}
}
}
$orderby = " ORDER BY id desc";
$sql = "SELECT * FROM links " . $queryCondition;
$result = mysqli_query($conn,$sql);
?>
<html>
<head>
<title>Advanced Search using PHP</title>
<script>
function showHideAdvanceSearch() {
if(document.getElementById("advanced-search-box").style.display=="none") {
document.getElementById("advanced-search-box").style.display = "block";
document.getElementById("advance_search_submit").value= "1";
} else {
document.getElementById("advanced-search-box").style.display = "none";
document.getElementById("with_the_exact_of").value= "";
document.getElementById("without").value= "";
document.getElementById("starts_with").value= "";
document.getElementById("search_in").value= "";
document.getElementById("advance_search_submit").value= "";
}
}
</script>
</head>
<body>
<h2>Advanced Search using PHP</h2>
<div>
<form name="frmSearch" method="post" action="index.php">
<input type="hidden" id="advance_search_submit" name="advance_search_submit" value="<?php echo $advance_search_submit; ?>">
<div class="search-box">
<label class="search-label">With Any One of the Words:</label>
<div>
<input type="text" name="search[with_any_one_of]" class="demoInputBox" value="<?php echo $with_any_one_of; ?>" />
</div>
<div>
<input type="submit" name="go" class="btnSearch" value="Search">
</div>
</div>
</form>
<?php while($row = mysqli_fetch_assoc($result)) { ?>
<div>
<div><strong><?php echo $row["title"]; ?></strong></div>
<div class="result-description"><?php echo $row["description"]; ?></div>
</div>
<?php } ?>
</div>
</body>
</html>
trial 2
You can compare the results of the search the user inputs and the query results before displaying them. Compare how many words are similar for each result from the array and print the one that has the most first.
$advance_search_submit
$wordsAry[$i]
You could easily use both variables to compare how many words in wordsAry are similar to advance_search_submit and store them in a displayResults array in order of which have more words in common.
Or
Could do the same thing but compare it to the title of the results.
$results
$wordsAry[$i]
Comparing these two variables in a similar way to above. Compare words to result (contains) and save them in order in another array to be displayed.

PHP - echo data from tables using their relationship

Good day :)
I have 2 tables - one containing the main headings and another which contains the subheadings and related paragraphs, which are related with a foreign key on TitleID and LinkID as shown here:
The idea is that I create a number of divs containing the main titles - from sectionamain with the related subcontent from sectiona, linked thru LinkID and TitleID.
<?php
function confirm_query($result_set) {
if (!$result_set) {
die("Database query failed.");
}
}
function get_practices() {
global $connection;
$query = "SELECT * FROM sectionamain ";
$query .= "LEFT JOIN sectiona ";
$query .= "ON sectiona.HeadingID = sectionamain.TitleID ";
$query .= "ORDER BY sectionamain.TitleID ASC";
$A_list = mysqli_query($connection, $query);
confirm_query($A_list);
return $A_list;
}
function display_practices() {
$output = "<div class=\"container inner\">\n";
$A_set = get_practices();
while ($list_A = mysqli_fetch_assoc($A_set)) {
$output .= "<div class=\"info\">\n";
$output .= "<div class=\"wrap\">\n";
$output .= "<h1 class=\"showcontent\" id=";
$output .= "". htmlentities($list_A["TitleID"]) ."";
$output .= ">";
$output .= htmlentities($list_A["MainTitle"]);
$output .= "</h1>\n";
$output .= "<div class=\"content\" id=\"content".htmlentities($list_A["TitleID"]) ."\">\n";
*** code would go here -
put items from sectiona with LinkID = 1 where TitleID = 1, etc until all data is sorted
$output .="</div>\n</div>\n</div>\n";
};
mysqli_free_result($A_set);
$output .= "</div>\n";
return $output;
}
?>
The end result would be something as shown below:
<h1>Main Title 1</h1>
<h3>Sub 1 with LinkID 1<h1>
<h3> ... </h3>
<h3>Sub n with LinkID 1</h3>
...
<h1>Main Title n</h1>
<h3>Sub 1 with LinkID n<h1>
<h3> ... </h3>
<h3>Sub n with LinkID n</h3>
Thank you in advance
xx
To solve your grouping issue, it's a matter of creating a data structure in an array. Since the database will give rows with repeating information, use this repeated information as a key in an array.
<?php
function get_practices() {
global $connection;
// It's good practice to specify which fields you want to get from the database.
// for clarity, I'm using heredoc format.
$query = >>>SECTIONAQUERY
SELECT am.TitleID, am.MainTitle, a.HeadingID, a.title, a.content
FROM sectionamain am
LEFT JOIN sectiona a
ON a.HeadingID = am.TitleID
ORDER BY sectionamain.TitleID ASC
SECTIONAQUERY;
$A_list = mysqli_query($connection, $query);
confirm_query($A_list);
return $A_list;
}
/**
* group_items
*
* takes database results and groups them by ID
*
* #param mysqli_result
* #return array
*/
function group_items($db_results) {
$data = array();
while($row = mysqli_fetch_assoc($db_results)) {
$title_id = htmlentities($row['TitleID']);
// group Main Title by title id
$data[$title_id]['title'] = htmlentities($row['MainTitle']);
// group data by title id
$data[$title_id]['data'][] = array(
'HeadingID' => htmlentities($row['HeadingID']),
'title' => htmlentities($row['title']),
'content' => htmlentities($row['content'])
);
}
return $data;
}
Then in your view, you could have something like this:
<?php
$A_list = get_practices();
$data = group_items($A_list);
// or, alternatively, $data = group_items(get_practices());
// now, go into "html mode" instead of in PHP,
// using PHP only for looping and variable substitution:
?>
<html>
<head>
...
</head>
<body>
<div>Your header stuff</div>
<div class="info">
<div class="wrap">
<?php foreach($data as $row): ?>
<h1 class="showcontent" id="<?= $row['title'] ?>"></h1>
<?php foreach($row['data'] as $sub_row): ?>
<h3><?= $sub_row['title'] ?></h3>
<div class="content"><?= $sub_row['content'] ?></div>
<!-- bonus: link to a new page? -->
<div><?= $sub_row['title'] ?></div>
<?php endforeach; ?>
<?php endforeach; ?>
</div>
</div>
</body>
</html>
Note, I personally would not stick output into a function; that's mixing logic and presentation. By using PHP's built-in templating, you don't have to worry about escaping quotes. Just use the <?= ?> syntax to drop in PHP variables. Use an include statement instead of calling the function. (or, you could always have the function include a partial view.)
Hope this addressed your question!

Order list of options based on MySQL query - PHP

I am presenting a list of options to the user based on a database query. The results are being fetched correctly however they are currently unordered and I would like to display them in alphabetical order in the option list. I have tried several solutions so far with "ORDER BY" on the query level however with no success. Is there a simple way to achieve this? (The list contains 1000+ results) The code is as follows:
<?php
$user_id = $_SESSION['user_id'];
$sql = "SELECT * FROM add_bulding WHERE description<>''";
$query = $this->db->query($sql);
$building_title = $query->result_array();
?>
<div>
<select>
<option value="">Select Building</option>
<?php foreach ($building_title as $value) { ?>
<option value = "<?php echo $value['id']; ?>">
<?php echo $value['title']; ?>
</option>
<?php
}
?>
</select>
</div>
Try changing your query to:
$sql = "SELECT * FROM add_bulding WHERE description<>'' ORDER BY title DESC";
Sounds like you want a query like:
SELECT id, title FROM add_bulding WHERE description<> ORDER BY title desc
Alternately, you can sort it in php:
<?php
$tmp = array();
foreach ($building_title as $value){
$tmp[$value['id']] = $value['title'];
}
ksort($tmp);
foreach ($tmp as $k => $v) {
print "<option value=\"" + $k + "\">" + $v + "</option>\n";
}
?>
However, in either case, be sure to sanitize your values so you don't end up with XSS problems.
Try this query :
$sql = "SELECT * FROM add_bulding WHERE description<>'' ORDER BY title";
If you want to get title data with alphabetical order then you can write 'ASC' or do not need to write any after ORDER BY title.
But you want to get title data with descending order then you need to write 'DESC' after ORDER BY title
I hope you will get solution.

retrieving array values from checkbox and dynamically building a query to select content

I have the following html file to send data in form of an associative array. The form is dynamically submitted using Jquery Ajax(no submit button need).
<html>
<form id="checkboxform" method="GET">
<input type="checkbox" name="navi[key1]" value="value1" <?php echo array_key_exists("value1",$navi)?"checked":""; ?>> Item1
<input type="checkbox" name="navi[key2]" value="value2" <?php echo array_key_exists("value2",$navi)?"checked":""; ?>> Item2
<input type="checkbox" name="navi[key3]" value="value3" <?php echo array_key_exists("value3",$navi)?"checked":""; ?>> Item3
</form>
</html>
Then I have the following php file to process the form and select data from Mysql database. The query is dynamically generated depending on which input field that are checked by the user.
<?php
if(isset($_GET['navi'])):
$navi=$_GET['navi'];
//foreach
foreach($navi as $key =>$value):
$query=$key."="."'".$value."'";
endforeach;
// run the query using PDO
$content = $db->getRows("SELECT * FROM products WHERE $query");
endif;
?>
My question is the following, how do add "OR" after the "$query" variable provided that the user selects more than one checkbox. Whick will generate a query that looks like this:
SELECT * FROM products WHERE key1='value1' OR key2='value2' OR key3='value3'
my code generates the following query without OR and its not correct.
SELECT * FROM products WHERE key1='value1' key2='value2' key3='value3'
thank you
You can try this -
$query = array();
foreach($navi as $key =>$value):
$query[] = $key."="."'".$value."'"; // store in array
endforeach;
// run the query using PDO
$content = $db->getRows("SELECT * FROM products WHERE " . implode(' OR ', $query)); // implode with OR
To prevent injection I would use prepare and bindValue like this, from code of previous answer (I haven't tried it but you can get the idea) :
$query = array();
$params = array();
foreach ($navi as $key =>$value):
// store in array
$query[] = $key . '=' . ':' . $key;
// store values to bind them
$params[':' . $key] = $value;
endforeach;
// run the query using PDO
$query = $db->prepare('SELECT * FROM products WHERE ' . implode(' OR ', $query));
// bind params
foreach ($params as $key => $value) :
$query->bindValue($key, $value);
endforeach;
// get rows
$query->execute();
$content = $query->fetchAll();

php - get specific variable from a foreach

I have a functioning foreach that I want to expand on. It's simple:
<ul>
<?
$sql_find = "SELECT DISTINCT(column_chosen) as Sec FROM column_a WHERE column_chosen NOT LIKE '' ";
$get_var = mysqli_query($db, $sql_find);
while ($r=mysqli_fetch_assoc($find_var)){
foreach($r as $newest_variable) {
echo '
<li>'.$newest_variable. '</li>';} }?>
</ul>
Let's say its html output is this:
<li>one</li>
<li>two</li>
<li>three</li>
I want to be able to get a specific variable ($newest_variable) and put it in $_SESSION or do other things, maybe alert it with javascript, etc, etc.
Question:
Is this possible with this structure? How could I get a specific variable $newest_variable?
For example, in the 2nd <li>, just get two and put into $_SESSION['result']
Any insight or direction is grealty appreciated.
<ul id="itemList">
<?
$sql_find = "SELECT DISTINCT(column_chosen) as Sec FROM column_a WHERE column_chosen NOT LIKE '' ";
$get_var = mysqli_query($db, $sql_find);
while ($r=mysqli_fetch_assoc($find_var)){
foreach($r as $newest_variable) {
echo '
<li>'.$newest_variable. '</li>';} }?>
</ul>
<script>
$('#itemList li').click(function() {
var index = $(this).index();
var text = $(this).text();
alert('Index is: ' + index + ' and text is ' + text);
});
</script>
Heres small code with JQuery, you can pass those variables to php with ajax and set as session, as well execute other functions you want :)
If you want to make an array of all the elements from the foreach, it's pretty simple:
<ul>
<?
$sql_find = "SELECT DISTINCT(column_chosen) as Sec FROM column_a WHERE column_chosen NOT LIKE '' ";
$get_var = mysqli_query($db, $sql_find);
while ($r=mysqli_fetch_assoc($find_var)){
foreach($r as $newest_variable) {
$newArray[] = $newest_variable; //Makes an array of all elements of the foreach
echo '
<li>'.$newest_variable. '</li>';
}
}
?>
</ul>
Now, the array $newArray will have all values of the foreach so that, for example, if you wanted the second element, you could use $newArray[1].

Categories