Little mod_rewrite problem - php

I have a classifieds website. Each classified is linked like this originally:
mydomain.com/ad.php?ad_id=Bmw_M3_M_tech_113620829
What RewriteRule should I use to make this link look like:
mydomain.com/Bmw_M3_M_tech_113620829
Also, what do I need to add to my .htaccess file?
This is what I have so far:
Options +FollowSymLinks
Options +Indexes
RewriteEngine On
RewriteBase /
And I have just enabled mod_rewrite which was disabled at first on my Ubuntu server by using:
a2enmod rewrite
Anything else I need to know or do?
Thanks

It looks like you need something like this:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/ad\.php
RewriteRule ^(.*)$ ad.php?ad_id=$1 [L]
This should rewrite a request to mydomain.com/Bmw_M3 into mydomain.com/ad.php?ad_id=Bmw_M3.
The RewriteCond excludes direct requests to ad.php from being rewritten. The RewriteRule would simply substitutes anything after mydomain.com/ in place of the $1. The [L] (last) flag stops the rewriting process so that it won't apply any more rewrites for a request that is rewritten by this rule.

You need to add the rule itself. Requires regex =)
RewriteRule ([a-zA-Z0-9_]+) ad.php?ad_id=$1
Of course, this regex should be fine tuned based on the ad ID you're passing on - by telling what characters can be in that ad ID and similar. For example, if all ad IDs are ending with and underscore and 9 digits, something like this:
RewriteRule ([a-zA-Z0-9_]_[0-9]{9}) ad.php?ad_id=$1
Oh, also, after enabling mod_rewrite restart apache. Make sure that AllowOverride is not set to None, cause in that case, apache will ignore .htaccess files in directories.

Related

RewriteRule in htaccess fails, but it could be my host

I read that Self Sabotage is Not asking for help so here I am.
So, I have a site...it's working great using WAMP. It's working great on my current host. But I need to switch to a new host and now it's failing. I figured it's a .htaccess issue but now I'm not sure. On my current host I have no .htaccess file and it works great. On my localhost server using WAMP I had the same thing as on my new host but I just disabled the .htaccess file, renaming it to BAD.htaccess, and the site still works great. This is why I think it's a server-side problem and I need some help. On my WAMP server in vhosts I disabled +FollowSymLinks for that "domain". On my current host I had no easy way to do that so it's just whatever they gave me, but it works.
I am currently with Ionos and have switched to GreenGeeks, who use cPanel. So far I haven't found a vhosts file to edit to remove +FollowSymLinks, if that is even the problem.
Maybe it can be accomplished with .htaccess and if so here is what I need to do. First my current .htaccess:
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^poems$ poems.php [R]
#RewriteRule ^poems/$ poems.php
RewriteRule ^collections$ collections/ [R]
RewriteRule ^collections/$ collections.php
RewriteRule ^poem$ poem/ [R]
RewriteRule ^poem/$ poem.php
RewriteRule ^poem/([0-9]+)/([a-zA-Z])$ poem.php?num=$1&poem=$2 [NC,L]
RewriteRule ^collection$ collection/ [R]
RewriteRule ^collection/$ collection.php
# RewriteRule ^poem/([0=9]+)$ indpoem.php?num=$1 [NC,L]
With the first two setups I can go to example.com/poems and it will redirect or rewrite to example.com/poems.php but still look like example.com/poems. Same with collections. On the new host those rewrite rules do rewrite it but the URL or URI shows example.com/poems.php, which I don't want per current SEO standards. Still, I could live with that.
However, when I get to the next level... example.com/poem/#/poem-name it fails on my new host. I do have a file called poem.php which it should rewrite to. In that file I use the following to get the # and name...
$URL = explode("/",$_SERVER['REQUEST_URI']);
So I don't have to do a _GET.
As you can see I tried to do a RewriteRule to change it from the first to example.com/poem?111&name, but that just seems silly because on WAMP I don't have to do anything. I could try rewriting it to the same URL again, but I have a feeling that won't work. And if it does it will probably be poem.php/#/name/
Any thoughts on a server config I'm missing when using cPanel. I even tried doing
Options -FollowSymLinks
in my .htaccess file with no success.
Any help would be appreciated. My WAMP and the new host have all the most recent versions of Apache and PHP.
There are a few issues here...
For the site to work without the .htaccess file at all (on your WAMP dev server and current host) then MultiViews (part of mod_negotiation) must have been enabled. It is MultiViews that "rewrites" /foo to /foo.php.
If MultiViews is enabled then your current .htaccess file is essentially overridden since the MultiViews content-negotiation occurs before your mod_rewrite directives are processed so your RewriteRule patterns fail to match.
MultiViews is disabled by default on Apache, it needs to be "explicitly" enabled. Unfortunately, some shared hosts do enable this in the server config (which causes more problems than it fixes - if you are not expecting it.)
On the new host those rewrite rules do rewrite it but the URL or URI shows example.com/poems.php.
RewriteRule ^poems$ poems.php [R]
Because MultiViews is disabled and your directives externally "redirect" /poems to /poems.php. There is no "rewrite" here. The R (redirect) flag triggers an external redirect.
RewriteRule ^poem$ poem/ [R]
RewriteRule ^poem/$ poem.php
However, for /poem you are redirecting to /poem/ (appending the trailing slash) but you have omitted the L flag so processing continues and the request is further rewritten to /poem.php. But because you have already triggered a Redirect, the request is "redirected" (not rewritten) to /poem.php, again exposing the .php.
Redirects should nearly always include the L flag. In fact, all your rules should include the L flag for optimisation and to prevent accidental conflicts.
Why are you redirecting to append the trailing slash (as if this is the preferred canonical URL)? You make no mention of this in your question text and only one of your examples includes a trailing slash on the URL as far as I can see? So, what is the preferred/canonical URL? What URL are you linking to? Incidentally, MultiViews will not append a trailing slash - so either this redirect is not required, or your site is not actually "working great" on WAMP / current host without the .htaccess file. (?) (Personally, I would not use a trailing slash.)
RewriteRule ^poem/([0-9]+)/([a-zA-Z])$ poem.php?num=$1&poem=$2 [NC,L]
:
$URL = explode("/",$_SERVER['REQUEST_URI']);
Your PHP script parses the requested URL-path (ie. $_SERVER['REQUEST_URI']), it is not referencing the query string. However, the above RewriteRule directive is rewriting to a query string - which would seem to be entirely superfluous ("silly" - as you suggest). Because you are not using the query string in your PHP script, the request still "works" when using MultiViews.
According to your PHP script, you simply need to rewrite the request to poem.php, without a query string. (Which is what MultiViews does. Although, strictly speaking, MultiViews rewrites /poem/123/name to /poem.php/123/name - passing the additional URL-path as path-info to poem.php.)
This regex only matches a single letter in the 3rd (name) path segment so it will fail to match a requested URL of the form /poem/123/name, so the request is not rewritten to poem.php and the request fails (with a 404 I suspect).
This regex also does not match a trailing slash. (So, is the trailing slash really canonical?)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
These conditions are entirely superfluous where you have put them. RewriteCond directives only apply to the first RewriteRule directive that follows.
Options -FollowSymLinks
You need FollowSymLinks for mod_rewrite to work. Don't try to disable this. FollowSymLinks is actually the default Apache setting, so you only need to explicitly enable it (ie. +FollowSymLinks) in .htaccess if it has been disabled in the server config.
Solution
Personally, I would not use a trailing slash on the canonical URLs. (This is in line with most of your examples and the regex used in your rule.)
So, bringing the above points together:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# Canonical redirect to remove trailing slash (from non-directories)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)/$ /$1 [R,L]
# Internal rewrites to ".php"
RewriteRule ^poems$ poems.php [L]
RewriteRule ^collections$ collections.php [L]
RewriteRule ^poem(/\d+/[\w-]+)?$ poem.php [L]
RewriteRule ^collection$ collection.php [L]
On the other hand, if the canonical URL should include a trailing slash then change it accordingly:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# Canonical redirect to append trailing slash to "all" URLs
RewriteRule !/$ ${REQUEST_URI}/ [R,L]
# Internal rewrites to ".php"
RewriteRule ^poems/$ poems.php [L]
RewriteRule ^collections/$ collections.php [L]
RewriteRule ^poem/(\d+/[\w-]+/)?$ poem.php [L]
RewriteRule ^collection/$ collection.php [L]
If you have many such URLs/pages then you can make this entirely "generic" without having to explicitly name each URL/file. ie. "poems", "collections", etc.
Alternatively, you simply enable MultiViews and let mod_negotiation rewrite the URLs. However, you will not be able to canonicalise the trailing slash or validate the request before rewriting and MultiViews applies to everything, not just your .php files, so potentially creates duplicate content. If you need to do any specific rewriting, such are rewriting the query string then MultiViews is likely to conflict.
Options +MultiViews

mod_rewrite into subdirectory file from folder

This could be probably duplicate due to unable to find that original even after checked the similar questions list of stackoverflow. Actually if user type myipaddress/gt then it should redirect to myipaddress/gt/gt.htm
I tried various mod_rewrites but still gets the 'gt' folder contents listed in browser. I gave the last try with below mod_rewrite.
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteRule ^gt$ gt/gt.htm [NC,L]
But still the browser shows the contents of the 'gt' folder. What am I doing wrong?
You can use this rule in /gt/.htaccess:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /gt/
RewriteRule ^/?$ gt.php [L]
Due to the fact that Apache sees gt as a directory, it treats it as such. However, that doesn't stop all rewriting for that particular path.
This is the basic process:
You navigate to /gt.
Apache sees that as an existing directory, and thus redirects to /gt/.
Your rule is ignored, because it doesn't contain the trailing slash.
This is why you still see the directory listing.
As such, you should change your rule to this:
RewriteRule ^gt/$ gt/gt.php [NC,L]
Alternatively, you can make use of DirectorySlash off and make the trailing slash optional, like so:
Options +FollowSymlinks
DirectorySlash off
RewriteEngine On
RewriteBase /
RewriteRule ^gt/?$ gt/gt.php [NC,L]
Doing either of the above allows you to have multiple rules of a similar nature in a single .htaccess file.

mod_rewrite not working to change URL

I want to change dynamic URL's to URL's more acceptable by search engines.
For example change this :
http://myurl.com.au/page.php?id=100&name=myname
to
http://myurl.com.au/100/myname.php
or .html at the end it does not matter.
I am using Apache 2.2. I am not using .htaccess rather I put my code in /etc/httpd/conf/vhosts/myfile
but it does not work, the URL does not change at all.
Options Indexes Includes +FollowSymLinks
RewriteEngine On
RewriteRule ^([^/]*)/([^/]*)\.php$ /page.php?id=$1&name=$2 [L]
What am I doing wrong?
Either your have the wrong description in your question or your rule is backwards. Maybe this could work:
Options Indexes Includes +FollowSymLinks
RewriteEngine On
RewriteCond %{QUERY_STRING} id=(.*)&name=(.*)$
RewriteRule ^/page\.php /%1/%2.php [L]
After doing some further testing it turns out that I do have the right code. I just don't have my head screwed on and was not thinking. Expecting that the mod_rewrite would magically change the URL to symbolic links when it is actually doing the reverse of that. It is all working for me now.

Rewrite Url (URL Routing) in .htaccess

My directories are like:
http://www.mydomain.com/macbook-computer
http://www.mydomain.com/sony-computer
http://www.mydomain.com/lenovo-computer
I want to make that, if a user type computers/macbook-computer like:
http://www.mydomain.com/computers/macbook-computer
I want to display page which is : http://www.mydomain.com/macbook-computer.
My restrictions are:
1. User must type /computers (segment 1)
2. String coming from computers/ must end with "computer". (segment 2)
How can I make this achieve in my .htaccess file?
You may try this:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/computers/([^-]+)-computer/? [NC]
RewriteRule .* %1-computer? [R=301,L]
Redirects permanently
http://www.mydomain.com/computers/anyname-computer with or without trailing slash.
To:
http://www.mydomain.com/anyname-computer
Strings computers and computer are assumed to be fixed, while anything is assumed to be variable.
The incoming URL structure has to be kept for the rule-set to work: First folder /computers followed by /anyname-computer.
For silent mapping, remove R=301 from [R=301,L]
You need a rewrite rule in your .htaccess file, and a little regular expression magic. Something like this should do the trick
RewriteRule ^computers/macbook-computer$ http://www.mydomain.com/macbook-computer
Here's a nice online tool for checking rewrite rules
http://htaccess.madewithlove.be/

mod_rewrite to direct site.com/something to index.php?values=something

(I might be an idiot, it appears that .htaccess isn't enabled by default in Apache on OSX.)
I know there are a lot of mod_rewrite questions out there, but I just can't get mine right and nothing else seems to quite cover it.
All I want to do is redirect
www.url.com/something
or
www.url.com/something/anything/more
to
www.url.com/index.php?values=something
or
www.url.com/index.php?values=something/anything/more
Nothing fancier than that (I'll put in something about ignoring gif/jpg/png, adding www. etc later later) - all processing of something/anything/more will be done in PHP.
I just can't get it right though. Any hints/resources or anyone who's just managed to do this? It's more frustrating knowing that I once got it absolutely perfect but lost that code years ago.
This is pretty straightforward, at least in what you are asking But basically you need to make index.php passthrough (so you don't rewrite index.php to index.php), then the main rewrite.
RewriteEngine On
RewriteRule index.php - [L]
# your conditions here
RewriteRule ^/?(.*)$ /index.php?values=$1 [L]
Add whatever conditions you want to exclude rewrite at the # your conditions here spot
RewriteEngineOn
RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !-d
RewriteRule ^(.*)$ /index.php?values=$1 [L]
Please note that you need to have AllowOverride On set in the Apache host config file for the directory in question if you are trying to do this in an .htaccess file and of course need to have mod_rewrite module enabled.
This rule will ignore the redirect for any actual files or directories (i.e. images) that actually exist (including index.php).

Categories