Question

I am currently using column header's as links that when clicked will sort the results by the column name by adding a get variable to the url. Here is an example:

<a href="
  <?php
  // Sorts by order id. If already sorted by order id, then it will change the link to sort descending
  if(!isset($_GET['sortby']) || $_GET['sortby'] != 'order_id'){
    echo $_SERVER['SCRIPT_NAME'] . '?sortby=order_id';  //example: tracker.php?sortby=order_id
  } elseif(isset($_GET['sortby']) || $_GET['sortby'] == 'order_id'){
    echo $_SERVER['SCRIPT_NAME'] . '?sortby=order_id_desc'; //example: tracker.php?sortby=order_id_desc
  }?>
">Order ID</a>

I also have a form where users can enter pick a category from a selectbox and then enter a searchterm. I am using if statements and switch statements to check if the $_GET['sortby'] variable and the $_POST['search_submit'] variable is set and if so, to run a certain sql statement based on the value of the GET variable.

There are 4 different scenarios.

1. Default: If neither sort nor search is set. This one works fine:

if(!isset($_GET['sortby']) && !isset($_POST['search_submit'])){ //Default, If no sort or search is set
  $sql = 'SELECT * 
          FROM orders 
          ORDER BY order_id DESC'; 
}

2. If the search is set but the sort is not. This one works fine:

if(isset($_POST['search_submit'])) {
  $search_string = ' WHERE ' . $_POST['searchby'] . '= "' . $_POST['search_input'] . '" ';
}

if(!isset($_GET['sortby']) && isset($_POST['search_submit']) ){ //If the search is set but no sort
  $sql = "SELECT * 
          FROM orders"
          . $search_string . 
          "ORDER BY order_id DESC";
}

3. If the sort is set, but the search is not. This one works fine:

if(isset($_GET['sortby']) && !isset($_POST['search_submit'])) { //If the sort is set but no search
  switch ($_GET['sortby']) { 
    case "order_id":
      $sql = "SELECT * 
              FROM orders 
              ORDER BY order_id ASC";
    break;

    case "order_id_desc":
      $sql = "SELECT * 
              FROM orders  
              ORDER BY order_id DESC";
    break;
  }
}

4. If the search AND sort is set. All 3 of the above if statements work, but the last one is giving me problems.

if(isset($_GET['sortby']) && isset($_POST['search_submit'])) { //If the sort AND search is set
  switch ($_GET['sortby']) { 
    case "order_id":
      $sql = "SELECT * 
              FROM orders"
              . $search_string . 
              "ORDER BY order_id ASC";
    break;

    case "order_id_desc":
      $sql = "SELECT * 
              FROM orders"
              . $search_string . 
              "ORDER BY order_id DESC";
    break; 
  }
} 

What happens is that you can search, but as soon as you click on one of the column headers and it reloads the page with the new GET variable, it will get rid of the current POST variable, thereby showing all results again. I tried to load the current POST variable into a session after the $_POST['search_submit'] isset and then make the last if statement check to see if the session variable is set, but what happens then is that the session is always set and if i try to go back to the homepage, it will keep those search results.

Perhaps I need to destroy the session somewhere? Perhaps there is an overall better approach I could be taking to combining sort and search features?

Was it helpful?

Solution

I would recommend changing the search form from a method="POST" to method="GET" and use just GET for all your requests. If you cannot change your POST requests, you are going to need to POST each request (including sorting), which will require javascript attached to your sort links.

The benefit to using GET is that your users can bookmark specific searches since all the data would be contained in the Query string.

EDIT: Retaining the search strings in subsequent requests:

I would abstract out your sorting code to something like this:

<?php
function write_sortable_header_link( $column_id, $column_name ){
   if( ( isset($_GET['sortby']) && $_GET['sortby'] != $column_id ) || !isset($_GET['sortby']) )
     $query = "?sortby=$column_id";
   else
     $query = '?sortby='.$column_id.'_desc';

   if( isset($_GET['searchsubmit']) ){
     $query .= '&amp;searchsubmit=1';
     $query .= '&amp;searchby=' . urlencode( isset($_GET['searchby']) ? $_GET['searchby'] : '' );
     $query .= '&amp;search_input=' . urlencode( isset($_GET['search_input']) ? $_GET['search_input'] : '' );
   }

   $href = $_SERVER['SCRIPT_NAME'] . $query;
   echo "<a href='$href'>$column_name</a>";
}
?>

You would then call it like this:

<?php write_sortable_header_link( 'order_id', 'Order Id' ); ?>

It would make sure your sorting URL's contain the correct query string arguments for persistence.

OTHER TIPS

Try to use $_GET only, involving $_POST seems unnecessary.

Not an answer to your question, but just my 0.2

In your situation I usually do the sorting client side in the web browser using javascript. It prevents essentially the same query being run over and over again with only different ORDER BY parameters.

With jquery there are even some very nice plugins that make it pretty easy.

example: http://tablesorter.com/docs/

This is the code I ended up using to make the link rewrite with the sort and search get variables as suggested by dcneiner. I took out the urlencode, the switched & to the '&' sign and made the inline if statement read as just the get variable, since the only way those get variables can be set is if the search_submit is set since they're part of the same form. I also added the '{' and '}' back into the if and else statements. I'm guessing you're using a slightly different way of doing PHP? Do you see anything wrong or unsecure about the changes I made? I wasn't too sure why you did it your way. But thanks again.

function write_sortable_header_link( $column_id, $column_name ){ //Function that creates a link with the search query if needed
  if( ($_GET['sortby'] != $column_id) || !isset($_GET['sortby']) ) { //If the GET variable is not the column id of this button or if the GET sortby variable has not been set
    $query = "?sortby=$column_id"; //then add this to the end of the url
  } else {
      $query = '?sortby='.$column_id.'_desc'; //otherwise if the GET variable is the column id of this button, then add the descending code to the end of the variable
  }

  if(isset($_GET['search_submit']) ){ //If the GET variable search_submit is in the url
    $query .= '&search_submit=1'; //then add this to the end of the url string
    $query .= '&searchby=' . $_GET['searchby']; //add whatever is currently in the GET searchby to the end of the url string
    $query .= '&search_input=' . $_GET['search_input']; //add whatever is currently in the GET search_input to the end of the url string
  }

  $href = $_SERVER['SCRIPT_NAME'] . $query; //this is the href part of the link
  echo "<a href='$href'>$column_name</a>"; //this creates the actual link
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top