Blog Mod Rewrite Not Returning ID

For some reason my blog mod rewrite isn’t working.

RewriteRule ^blog/([0-9]+)/(.*)$ /blog.php?post_id=$1&title=$2 [L]

When I visit my blog page and write:

echo $_GET[‘post_id’]; die();

Nothing is returned. In order for a user to go to an individual blog page I need that id returned. Any idea as to what I am missing?

unemp,

Test URI? mod_rewrite enabled (and tested)?

Tip: Use [R=301,L] to see the redirection in action - that is my first point of testing mod_rewrite scripts which are acting up.

Regards,

DK

The URI seems to be correct, but maybe I’m missing something there. mod_rewrite is enabled and works for my other pages.

I added in the [R=301,L] but that didn’t seem to do anything.

You can view the issue at http://pitchbig.com/blog .

Try clicking on a blog title and you’ll see that it’s not redirecting to the article. Any other thoughts?

Jason,

I can see it’s not working (check http://wilderness-wally.com/ to see how it’s done correctly - and without the blog numbers (post_id)).

If you’ve looked at the tutorial article in my signature and run the few tests, you’ll be able to verify that mod_rewriting is enabled and functioning correctly.

Your page does load with the redirection made by hand.

That implies that mod_rewrite is not working OR you have something else in your ROOT directory (blog.php there) OR other code is conflicting with your code. You need to show your entire .htaccess for me to see about conflicts.

Regards,

DK

Hi David,

It appears as if my mod rewrite is working because going to http://pitchbig.com/index.php will redirect you to http://pitchbig.com. Also, blog.php is in my root directory.

Below is my entire .htaccess file:

# Apache configuration file
# httpd.apache.org/docs/2.2/mod/quickreference.html

# ----------------------------------------------------------------------
# Webfont access
# ----------------------------------------------------------------------

# Allow access from all domains for webfonts.
# Alternatively you could only whitelist your
# subdomains like "sub.domain.com".

<FilesMatch "\\.(ttf|otf|eot|woff|font.css)$">
  <IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
  </IfModule>
</FilesMatch>


# ----------------------------------------------------------------------
# Proper MIME type for all files
# ----------------------------------------------------------------------

# Audio
AddType audio/ogg                      oga ogg
AddType audio/mp4                      m4a

# Video
AddType video/ogg                      ogv
AddType video/mp4                      mp4 m4v
AddType video/webm                     webm

# Proper svg serving. Required for svg webfonts on iPad
#   twitter.com/FontSquirrel/status/14855840545
AddType     image/svg+xml              svg svgz 
AddEncoding gzip                       svgz
                                       
# Webfonts                             
AddType application/vnd.ms-fontobject  eot
AddType font/truetype                  ttf
AddType font/opentype                  otf
AddType application/x-font-woff        woff

# Assorted types                                      
AddType image/x-icon                   ico
AddType image/webp                     webp
AddType text/cache-manifest            appcache manifest
AddType text/x-component               htc
AddType application/x-chrome-extension crx
AddType application/x-xpinstall        xpi
AddType application/octet-stream       safariextz
AddType text/x-vcard                   vcf

# ----------------------------------------------------------------------
# ETag removal
# ----------------------------------------------------------------------

# FileETag None is not enough for every server.
<IfModule mod_headers.c>
  Header unset ETag
</IfModule>

# Since we're sending far-future expires, we don't need ETags for
# static content.
#   developer.yahoo.com/performance/rules.html#etags
FileETag None

Options +FollowSymLinks  
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=301,L]

RewriteCond %{SCRIPT_FILENAME} !-d  
RewriteCond %{SCRIPT_FILENAME} !-f

RewriteRule ^u/(.*)$ /profile.php?u=$1 [QSA,L]
RewriteRule ^c/(.*)$ /company.php?c=$1 [QSA,L]

RewriteRule ^blog/([0-9]+)/(.*)$ /blog.php?post_id=$1&title=$2 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\\.]+)$ $1.php [NC,L]

RewriteCond %{HTTP_HOST} ^www\\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\\ /index\\.php\\ HTTP/
RewriteRule ^index\\.php$ http://pitchbig.com/ [R=301,L]

RewriteRule (.*)\\.xml(.*) $1.php$2 [nocase]  

ErrorDocument 404 /404.php

unemp,

Using the / as the first character in the redirection tells Apache to look in the SERVER root directory for a match before looking in your DocumentRoot (root of the domain). Since your .htaccess is in your DocumentRoot, there is no need for the / and, thus, no need to confuse Apache about your intent.

I have major concerns regarding the server abuse contained within your .htaccess (it’s not my problem, just things I need to point out to you as well as other members).


# Apache configuration file
# httpd.apache.org/docs/2.2/mod/quickreference.html

# ----------------------------------------------------------------------
# Webfont access
# ----------------------------------------------------------------------

# Allow access from all domains for webfonts.
# Alternatively you could only whitelist your
# subdomains like "sub.domain.com".

<FilesMatch "\\.(ttf|otf|eot|woff|font.css)$">
  <IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
  </IfModule>
</FilesMatch>

[COLOR="#0000FF"][rant #4][indent]The definition of an idiot is someone who repeatedly does the same thing expecting a different result.  Asking Apache to confirm the existence of ANY module with an <IfModule> ... </IfModule> wrapper is the same thing in the webmaster world.  DON'T BE AN IDIOT!  If you don't know whether a module is enabled, run the test ONCE then REMOVE the wrapper as it is EXTREMELY wasteful of Apache's resources (and should NEVER be allowed on a shared server).[/indent][/rant 4]

Compounding matters, you make several <IfModule> tests throughout your .htaccess and each one must be tested for every pass through your .htaccess (use a log level of 9 to see how many passes you make for each request).

If you have control over your server, move the <IfModule> and other core directives into the server's httpd.conf or httpd-vhosts.conf files where they'll be read ONCE. If you don't have server control, ask your host for help as it will ease the abuse of their server so they should be happy to help.[/COLOR]

# ----------------------------------------------------------------------
# Proper MIME type for all files
# ----------------------------------------------------------------------

# Audio
AddType audio/ogg                      oga ogg
AddType audio/mp4                      m4a

# Video
AddType video/ogg                      ogv
AddType video/mp4                      mp4 m4v
AddType video/webm                     webm

# Proper svg serving. Required for svg webfonts on iPad
#   twitter.com/FontSquirrel/status/14855840545
AddType     image/svg+xml              svg svgz
AddEncoding gzip                       svgz

# Webfonts
AddType application/vnd.ms-fontobject  eot
AddType font/truetype                  ttf
AddType font/opentype                  otf
AddType application/x-font-woff        woff

# Assorted types
AddType image/x-icon                   ico
AddType image/webp                     webp
AddType text/cache-manifest            appcache manifest
AddType text/x-component               htc
AddType application/x-chrome-extension crx
AddType application/x-xpinstall        xpi
AddType application/octet-stream       safariextz
AddType text/x-vcard                   vcf

# ----------------------------------------------------------------------
# ETag removal
# ----------------------------------------------------------------------

# FileETag None is not enough for every server.
<IfModule mod_headers.c>
  Header unset ETag
</IfModule>

# Since we're sending far-future expires, we don't need ETags for
# static content.
#   developer.yahoo.com/performance/rules.html#etags
FileETag None

Options +FollowSymLinks
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=301,L]

[COLOR="#FF0000"]RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f[/COLOR]

[indent]Is this for u/{something}? Why did you use {SCRIPT_FILENAME}?[/indent]

RewriteRule ^u/(.*)$ [COLOR="#FF0000"]/[/COLOR]profile.php?u=$1 [QSA,L]
RewriteRule ^c/(.*)$ [COLOR="#FF0000"]/[/COLOR]company.php?c=$1 [QSA,L]

RewriteRule ^blog/([0-9]+)/(.*)$ [COLOR="#FF0000"]/[/COLOR]blog.php?post_id=$1&title=$2 [[COLOR="#808080"]R=301,[/COLOR]L]

[indent]Good - but only use for your testing then remove![/indent]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\\.]+)$ $1.php [NC,L]

[indent]1. I would have tested whether the .php extension IS a file rather than the current request not a file
2. No need to escape . in a character range definition
3. I would "reverse" the \\ and exclude /
4. The No Case flag is intended for the case INsensitive {HTTP_HOST}, not {REQUEST_URI} which IS case sensitive. Besides, both cases (and the kitchen sink) are matched by your character range definition so this is useless here, anyway[/indent]

RewriteCond %{HTTP_HOST} ^www\\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

[indent]I wouldn't have bothered Apache to copy the {REQUEST_URI} string again for the redirection and merely use RewriteRule .? http://%1%{REQUEST_URI} [R=301,L].[/indent]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\\ /index\\.php\\ HTTP/
RewriteRule ^index\\.php$ http://pitchbig.com/ [R=301,L]

[indent]You were smart enough not to use the end anchor so why did you use the start anchor? The format of {THE_REQUEST} is "GET /index.html HTTP/1.1" and it looks like all you needed to match was the index.php ... which is exactly what the associated RewriteRule does.[/indent]

RewriteRule (.*)\\.xml(.*) $1.php$2 [nocase]

[indent]Possibly nothing before or after .xml? That doesn't make any sense (to me - just like the nocase).[/indent]

ErrorDocument 404 /404.php

Okay, with all my comments about your coding, I didn’t see anything before your blog rule which would prevent it from matching nor anything after which would redirect from blog.php.

Suggestions:

  1. Clean-up and move core directives to the server/vhost configuration files
  2. Reorder to move all remaining core directives above mod_rewrite
  3. Reorder the mod_rewrite to handle site-wide changes (e.g., remove www and remove / from non-directory requests) first, then specifics (like the blog) then general redirections
  4. If the blog keeps failing, move it around in the list of mod_rewrite redirections

Regards,

DK

Hey David,

I have an endless amount of questions about your last post. 1. I’m really bad at .htaccess as my experience is mainly as a front-end developer ~ portfolio : http://jasonbiondo.com

  1. I do actually have my own server so I have full control and I am running a LAMP stack, but that’s configured pretty bad too :slight_smile:

I think it’s interesting that I can move some of those ifs into my apache config files. However, even by removing the “/” in the blog rewrite, the ID is still not being returned in the PHP.

Any other ideas as to why?

Also, why were these in red?

RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f

I’m aware it is. It just doesn’t grab my attention as much as front-end development.

Jason,

If you have specific questions, go ahead! The best way to learn is to get semi-educated through reading then ask question about things which weren’t clear (that also helps me to discover where the tutorial needs some editing).

LAMP server, eh? Great! I won’t host on a WAMP server but that’s what I’m stuck with as a test server. Nearly identical except that WinDoze doesn’t provide all the services a 'nix server does.

IMHO, it’s not interesting, it’s MANDATORY! Okay, if it’s your server, mandatory is wrong but doing “silly things” (of the type I was whining about) on a shared server should get you barred.

Okay, the leading / wasn’t required anyway but the fact that there is no change means that you are getting the blog.php in the DocumentRoot (not the server’s root).

{SCRIPT_FILENAME}: Typically, %{REQUEST_FILENAME} is used (as you have done) and this was only attached to the one RewriteRule (which followed). That was highly unusual.

Then, the Apache Foundation says:

What was that in reference to?

Regards,

DK

@dklynn; , you really should have smelled the stink of MultiViews here!


RewriteRule ^[COLOR="#FF0000"][B]blog[/B][/COLOR]/([0-9]+)/(.*)$ /[COLOR="#FF0000"][B]blog[/B][/COLOR].php?post_id=$1&title=$2 [L]

@unemployment; if you change Options +FollowSymLinks to Options +FollowSymLinks -MultiViews it should work as intended.

Rémon,

Well, that’s too true! The first blog would have requested blog.php but without creating the query string. If blog.php is smart enough to read the URI, however, it might have resolved the problem even with the (IMHO, HATED) MultiViews was enabled.

Well spotted … and commented.

Regards,

DK

Scallio,

This almost solved my problem. The issue is now the URL changes to http://pitchbig.com/var/www/pitchbig.com/pitchbig.com/blog.php?post_id=3&title=A-Development-Teams-Guide-for-Using-Dropbox

where var/www/pitchbig.com/pitchbig.com is the path to the root directory. How do I eliminate this from:

RewriteRule ^blog/([0-9]+)/(.*)$ blog.php?post_id=$1&title=$2 [R=301,L]

Change blog.php to /blog.php and see if that works

The guess new is that it made the blog article display, but the bad news is that the URL wasn’t rewritten. The url shows up as http://pitchbig.com/blog.php?post_id=3&title=A-Development-Teams-Guide-for-Using-Dropbox when I try to access http://pitchbig.com/blog/3/A-Development-Teams-Guide-for-Using-Dropbox

Remove R=301.
That is, change [R=301, L] to just [L].
Clear your browser cache before testing that.

Fixed. Thank you