2

I am looking for correct htaccess rules for my search.php page. Because I tried several, but nothing worked. It may be possible my existing htaccess rules conflicting it. So I am also pasting my current htaccess file here. Currently I have following search page url with query string:

http://my-domain.com/search.php?q=keyword

I want the following clean url:

http://my-domain.com/search/keyword

My HTML form is:

<form method="get" action="search.php">
    <input type="text" name="q" class="txtfield" value="<?php echo $q; ?>" placeholder="Search post here..." />
</form>

htaccess:

Options +FollowSymlinks -MultiViews

RewriteBase /

#Enable mod rewrite
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ page.php?category=$1 [QSA,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/([^/]+)$ page.php?category=$1&post=$2 [QSA,L]

Note that I don't have search related htaccess rule in above file because as I said nothing worked. I always saw 404 page. That's why I removed it.

Also If I put submit button in the form in some future like below:

<form method="get" action="search.php">
    <input type="text" name="q" class="txtfield" value="<?php echo $q; ?>" placeholder="Search post here..." />
    <input type="submit" name="btnsearch" class="btn" value="Search" />
</form>

My search url will change to:

http://my-domain.com/search.php?q=keyword&btnsearch=Search

Then I am wondering what correction/modification I will have to do in the correct htaccess rule which you will give to me as per my first query? Should we have two rules if the search url contains two or more than two query strings? Please help me on this guys. Thanks.

Sachin
  • 1,646
  • 3
  • 22
  • 59

2 Answers2

4

When a form is submitted it will indeed make your URL as:

http://my-domain.com/search.php?q=keyword&btnsearch=Search

To keep submitted URL pretty you need to prevent form submission using Javascript code and make URL pretty like this.

<html><head>
<script>
function prettySubmit(form, evt) {
   evt.preventDefault();
   window.location = form.action + '/' + form.q.value.replace(/ /g, '+');
   return false;
}    
</script>
</head><body>
<form method="get" action="search" onsubmit='return prettySubmit(this, event);'>
   <input type="text" name="q" value="<?php if (isset($_GET['q'])) echo $_GET['q']; ?>"
       class="txtfield" placeholder="Search post here..." />
   <input type="submit" name="btnsearch" class="btn" value="Search" />
</form>
</body></html>

This will submit your form to a pretty URL:

http://my-domain.com/search/keyword

Now you will need this rule in your root .htaccess to handle this pretty URL;

Options -MultiViews
RewriteEngine On

RewriteRule ^search/(.+)$ search.php?q=$1 [L,QSA,NC]

Update:

Here is a way to do it completely using mod_rewrite rules without using any JS. Use following rules in root .htaccess:

Options -MultiViews
RewriteEngine On
RewriteBase /my-project/

# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} /search(?:\.php)?\?q=([^\s&]+) [NC]
RewriteRule ^ search/%1? [R=302,L,NE]

# internal forward from pretty URL to actual one         
RewriteRule ^search/(.+)$ search.php?q=$1 [L,QSA,NC]
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Ok but I am not understanding why everyone is suggesting to use JavaScript? Why it can not be done in only PHP/htaccess? What happen if somebody has turned off JS in his browser? Can you please tell me how to do it without JS? – Sachin May 16 '16 at 06:49
  • I want a solution that can work in both cases - a form without submit button and with submit button. I need htaccess rules for both situation. – Sachin May 16 '16 at 06:50
  • hmm.. then what is [http://matthewjamestaylor.com/blog/how-to-post-forms-to-clean-rewritten-urls](http://matthewjamestaylor.com/blog/how-to-post-forms-to-clean-rewritten-urls) for? – Sachin May 16 '16 at 06:53
  • Did you use JS in your first solution because my form had submit button too? If so, if we don't have the submit button, then do we not require any JS? – Sachin May 16 '16 at 06:56
  • Your first JS solution is making my URL as when I searched for more than one keyword - "search keyword". The plus sign is gone now! – Sachin May 16 '16 at 07:40
  • 1
    ok thanks. yea i checked it. actually i tried your first method with js. – Sachin May 16 '16 at 08:01
  • Your second way of doing pretty url without JS didn't work. It shows "Not Found". URL becomes `http://domain.com/search/?q=keyword&btnsearch=Search` – Sachin May 16 '16 at 11:24
  • I used it but it now directly takes me to out of my project folder. It's again 404 and URL changes to `http://localhost/search/keyword`. What needs to be done in htaccess to set it at `http://localhost/my-project/search/keyword` – Sachin May 16 '16 at 11:58
  • Well did you mention anywhere about presence of `my-project`? Your question says clean URL is `http://my-domain.com/search/keyword`. Try my updated answer now. – anubhava May 16 '16 at 13:40
  • Though I didn't mention about it but when I tried it on my local then it didn't work even with your updated solution. Still going out of the project folder. – Sachin May 16 '16 at 16:41
  • Both solutions are working fine on my Apache so it is something to do with your local setup. Did you clear your browser cache or test with command line tool like `curl`? – anubhava May 16 '16 at 16:44
  • Yes I cleared all cache data. Even i tried in other browsers too. Your editing `RewriteBase /my-project/` has no impact. – Sachin May 16 '16 at 16:49
  • What will be the correct action attribute of form when it is done without JS? – Sachin May 16 '16 at 16:53
  • Your solution `RewriteBase /my-project/` if it does work then it will break my other htaccess rules because I have some rules for page, post and category pages as well. – Sachin May 16 '16 at 16:54
  • Not just `RewrtieBase`, I have `RewriteRule ^ search/%1? [R=302,L,NE]` instead of `RewriteRule ^ /search/%1? [R=302,L,NE]` (note removal of leading slash) – anubhava May 16 '16 at 17:00
  • Oh ok. I got it. It's working now. But I guess RewriteBase would damage my other rules; though i didn't test it yet. – Sachin May 16 '16 at 17:11
  • 1
    @anubhava you, sir, are a true .htaccess genius. I've been killing myself over this for hours. – yaakov Sep 09 '18 at 05:30
1

1.Remove the .php extension (optional)

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]

2.Support http://my-domain.com/find/keyword

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^find/([^/\.]+)$ /search.php?keyword=$1

3.Test

<?php
if ($_POST['query'] != '') {
   header( 'Location: /find/' . $_POST['query']);
}
echo $_GET['keyword'];
?>
<form method="post" action="">
   <fieldset>
      <input type="text" name="query" />
      <input type="submit" value="Search" />
   </fieldset>
</form>

Hope this helps.

keziah
  • 564
  • 1
  • 6
  • 24
  • 1
    How does `find.php` come into the picture? OP has shown that the file is `search.php`... – Mike Rockétt May 16 '16 at 05:52
  • because the name `search` in `search/keyword` should not be the same as the file name search.php so I gave it another name. – keziah May 16 '16 at 05:55
  • It certainly shouldn't... Check your logs. And turn off `Multiviews`. – Mike Rockétt May 16 '16 at 05:59
  • I changed search form action to `search/` and put your point no. 2 htaccess rule in my htaccess file, but it now shows `/search/?q=keyword` in address bar. How to remove `?q=`? – Sachin May 16 '16 at 06:03
  • I don't think your first rule is mandatory. We can simply change action attribute of our form. Isn't it? – Sachin May 16 '16 at 06:04
  • @user5307298 - When you submit the form, it will automatically do that. See http://stackoverflow.com/a/5464577/1626250. – Mike Rockétt May 16 '16 at 06:05
  • Please don't suggest me javascript method. I want to do it in htaccess only. – Sachin May 16 '16 at 06:08
  • updated my answer and this works for me. i've translated it into POST method because GET returns ugly URL – keziah May 16 '16 at 06:22
  • hey man, what are you doing? why are you making this simple question to so complicated. why did you change form action to POST. Everybody knows, search form always use GET. You said ugly, then why this question was asked for? We are finding a solution to make it fancy but by keeping GET. – Sachin May 16 '16 at 06:34