0

I'm trying to rewrite a URL so that it's user/search engine friendly, then 301 redirect the original URL to the new one.

At the moment the posts generate like this: example.com/blog/post.php?s=nice-post

But I'd like them to look like this: example.com/blog/nice-post

Here's what I've got so far:

RewriteEngine On

RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]

RewriteCond %{QUERY_STRING} ^s=(.+)$
RewriteRule post.php /%1? [R=301,L]

RewriteCond %{REQUEST_URI} !post.php
RewriteRule ^([a-zA-Z0-9_-]+)$ post.php?s=$1

Unfortunately, this clashes with the 404 redirect, sending all pages not found to the blank post.php file, and I can't work out why. Is there a better way of approaching the URL rewrite/redirect?

Thanks for having a look :)

Martin
  • 351
  • 2
  • 8
  • 17
  • Can you change `post.php` itself to issue a 404 (`header()` is your friend) if the post hasn't been found? That would be the easiest way I can think of, because your rewrite rules cannot possibly know which posts exist and which don't. – tdammers Aug 26 '12 at 10:15
  • Hi @tdammers, that would be good. My php skills are pretty rudimentary– do you have a link to a resource where I might be able to swot up on this? – Martin Aug 26 '12 at 15:27
  • Try the PHP documentation on `header()`: http://php.net/manual/en/function.header.php – tdammers Aug 26 '12 at 18:05
  • Thanks @tdammers but I think you've lost me there– that's a pretty general page… – Martin Aug 26 '12 at 19:09

2 Answers2

1

Elaborating on tdammers' suggestion about header()

in your post.php, before outputting anything, decide if it's a valid post or not (for example by looking its id up in the database).

if( !$valid ) {
    header( 'HTTP/1.0 404 Not Found' );
    echo "404";
    exit;
}

i.e. if the page was found invalid, PHP sends out a 404 header to the browser to notify it that this is a missing page. Unfortunately, there's no straightforward way to redirect to Apache's default 404 page, so you'll have to output something yourself -- but since you already have a custom 404 page, you may just include() that.

SáT
  • 3,633
  • 2
  • 33
  • 51
  • Hi @SáT, looks like what I'm after. I've tried to get that to work but I'm getting errors… Tried include('http://tempertemper.net/error'); and readfile('http://tempertemper.net/error'); in place of the echo but it's not having it. Not my area of expertise, I'm afraid so a bit more hand-holding might be in order… Sorry if I'm being thick! :) – Martin Aug 27 '12 at 13:45
  • It's okay. But what kind of errors, exactly? Maybe [http://stackoverflow.com/questions/8028957/header-already-sent-error-in-php]("headers already sent")? – SáT Aug 27 '12 at 14:23
  • I've got this running at the very start of the document and that's followed by the usual , etc. Should I be including the if(!$valid… after the initial include? or somewhere else? – Martin Aug 27 '12 at 14:44
  • With The page just hangs. – Martin Aug 27 '12 at 14:45
  • With I get: Warning: include() [function.include]: URL file-access is disabled in the server configuration in /home/users/uks71468/html/tempertemper.net/blog/post.php on line 5 Warning: include(http://tempertemper.net/error) [function.include]: failed to open stream: no suitable wrapper could be found in /home/users/uks71468/html/tempertemper.net/blog/post.php on line 5 – Martin Aug 27 '12 at 14:46
  • And finally: Warning: include() [function.include]: Failed opening 'http://tempertemper.net/error' for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in /home/users/uks71468/html/tempertemper.net/blog/post.php on line 5 – Martin Aug 27 '12 at 14:47
0

Going to assume you've got these rules in an htaccess file in your /blog/ directory. Try adding a RewriteBase and removing the leading slash from your query string backreference:

RewriteEngine On

RewriteBase /blog/

RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]

RewriteCond %{QUERY_STRING} ^s=(.+)$
RewriteRule post.php %1? [R=301,L]

RewriteCond %{REQUEST_URI} !post.php
RewriteRule ^([a-zA-Z0-9_-]+)$ post.php?s=$1
Jon Lin
  • 142,182
  • 29
  • 220
  • 220
  • Hi @jon, you're right– sorry! I should have mentioned that the .htaccess file that's doing the work is in the /blog/ directory! I've tried the amendment and it seems to do the same thing as before: http://tempertemper.net/blog/this-post-does-not-exist – Martin Aug 26 '12 at 18:53