Search results when none found – stay on page they were on

Not sure it is a smart thing* to do but it is possible.

The easy solution is to check if you have any posts and if not redirect based on the referer

At the top of your code (before the call to get_header) add

if ( !have_posts() ) { 
  if (isset($_SERVER['HTTP_REFERER'])) {
    wp_redirect(301,$_SERVER['HTTP_REFERER']);
  }
}

This is based on the assumption that a referer is being sent with the request, an assumption which might be false based on browser configuration, and is always false when the site uses SSL.

There is a possible alternative solution in which you change your search form to include the current page URL as a hidden field.

The search form will look like

<form action="<?php echo get_option('siteurl')?>" method="get">
  <input name="s" type="text">
  <input type="hidden" name="ref_url" value="<?php esc_url($_SERVER['REQUEST_URI'])?>">
</form>

And then the code at the top of the search page will be

if ( !have_posts() ) { 
  if (isset($_GET['ref_url'])) {
    wp_redirect($_GET['ref_url'],302); 
  }
} else if (isset($_GET['ref_url'])) { // fix the URL
    wp_redirect(remove_query_arg('ref_url',$_SERVER['REQUEST_URI']),301);    
}

The second part of the code is to remove the extra parameter from a URL otherwise you will have different URLs for the same search based on the page from which the search was conducted.

** It is not a smart thing because people are used to searches which don’t find what they look for, but are not used to be redirected to any other place if there are no results. For many it will look as if the search form is not working and you will have to add some notice that there were no results.