HTACCESS URL Variable Rewrite - php

Looking to rewrite a URL and can't seem to get it working.
Example URL:
http://www.example.com/find/agency.php?agency=33524&name=happy-example
Ideal, rewritten URL:
http://www.example.com/find/agency/happy-example
One of the many attempted rewrites:
RewriteRule ^/([.]+)/([.]+)$ agency.php?agency=$1&name=$2
RewriteRule ^/([.]+)/([.]+)/$ agency.php?agency=$1&name=$2
Even if the removal of the "agency=" variable isn't possible, I still can't seem to make this URL write out the variables - am I approaching the rewrite backwards?

Try using a rewrite condition to catch the query string before doing the rewrite.
For example something like:
RewriteCond %{QUERY_STRING} ^agency=33524&name=([^&]+)
RewriteRule ^find/agency.php$ find/agency/%1? [R=301]

There are several things wrong with your rule. However to get a URL like this.
http://www.example.com/find/33524/happy-example
You would need to use a rewrite like below.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^find/([^/]+)/([^/]+)/?$ /agency.php?agency=$1&name=$2 [L]

Use a lazy modifier for the symbol matching (currently ([.]+) will match everything )
RewriteRule ^/([.]+?)/([.]+?)$ agency.php?agency=$1&name=$2
RewriteRule ^/([.]+?)/([.]+?)/$ agency.php?agency=$1&name=$2
You can also combine these into one rule
RewriteRule ^/([.]+?)/([.]+?)[/]{0,1}$ agency.php?agency=$1&name=$2
This does not include whatever flags you would need depending on your particular case

Related

Rewrite Pretty or SEO friendly URL via htaccess

I have a problem with transforming urls from dynamic to static.
I have a site where different pages are generated with a dynamic url, like:
www.example.com/?pr=project-abc123
I would like to rewrite the url of each one with htaccess making it static, like this:
www.example.com/project-abc123
// or
www.example.com/pr/project-abc123
Now, i found this htaccess code that seems to work:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \?
RewriteCond %{QUERY_STRING} ^p=(.*)$
RewriteRule (.*) http://example.com/%1? [L,R=301]
RewriteRule ^(.*)$ /index/?pr=$1[L]
URLs are rewritten as indicated (first type, whitout /pr/ ), but gives me a multiple choice error. What am I doing wrong?
Let's understand RewriteRule directive which is the real rewriting workhorse.
A RewriteRule consists of three arguments separated by spaces. The arguments are
Pattern: which incoming URLs should be affected by the rule;
Substitution: where should the matching requests be sent;
[flags]: options affecting the rewritten request.
Let's start with the following snippet:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
First line of code, describes RewriteEngine is turned on. Here I use RewriteCond directive which defines a rewrite rule condition. Using RewriteCond directive we defined two conditions here. This directive took a server variable called REQUEST_FILENAME. The two conditions above tell if the request is not a file or a directory, then meet the rule set by RewriteRule. See more details on this issue.
Now it's time to write some rewrite rules. Let's convert
www.example.com/?pr=project-abc123
// to
www.example.com/project-abc123
and rewrite rule will be:
RewriteRule ^(.*)$ index.php/?pr=$1 [L]
And to get the www.example.com/pr/project-abc123 we need the rule as the below:
RewriteRule ^/?([a-z]+)/(.*)$ index.php/?$1=$2 [L]
// or
RewriteRule ^/?pr/(.*)$ index.php/?pr=$1 [L]
The [L] flag tells mod_rewrite to stop processing the rule set. This means that if the rule matches, no further rules will be processed.

Cleanning urls with htaccess

i am trying to use RewriteRules to get clean urls using my HTACCESS file.
here is what i have so far
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
The above code takes a url that looks like this company.com/about.php and turns it into company.com/about/ so all my links url are like this "/about/" i didnt add the .php because of the rewrite rule.
what i am trying to do now is add a rule that will clean my url when parameter is passed. for example
company.com/about/?profile=member_name i want it to look like company.com/about/member_name
i have tried the two rewrite code below but it doesn't work.
RewriteRule ^([a-zA-Z0-9]+)$ /our_work.php/ [L]
RewriteRule ^/our_work.php([^/\.]+)/?$ ?project=$1 [L]
please keep in mind that my file extension is already being striped from the url.
Please help
Thank you in advance
Apache provides documentation on the use of RewriteRule that you should read before proceeding.
In this particular case, you can rewrite /about/{member_name} to /about.php?profile={member_name} by implementing this rule:
RewriteRule ^about/([a-zA-Z0-9]+)(/)?$ about.php?profile=$1 [L]
The rule states: The requested URL must begin with about/ and be followed by letters and numbers (match #1) and may be proceeded by an additional ending forward slash (match #2); and it will be substitued with a URL about.php with profile query string's value as match #1. The L flag indicates that any rules that follow this rule should be ignored.
Attempting to "cascade" rules will not work with your current set of rules because the /about/{...} is not matched by the first rule.

htaccess rewriterule for directory structure

I have the following .htaccess rewrite problem. We have requests entering with multiple subdirectories and an .html file
for example dir1/file.html
or dir1/dir2/file.html
or dir1/dir2/dir3/file.html
or dir1/dir2/dir3/dir4/file.html
what we eventually need is a rewrite rule to
index.html?dir1=$1&dir2=$2&dir3=$3&dir4=$4&file=$5
(where dir2 to dir5 would be empty if path is too short)
Is there any way to do that directly in the .htaccess file, or is it necessary to handle it in php?
I will see if I can test this out, but this should work for the problem as your question states it:
RewriteRule ^/([a-z0-9]+)/?([^/]*)$ /index.php?dir1=$1&$2 [QSA]
RewriteRule ^/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)/?$ /index.php?dir1=$1&dir2=$2&dir3=$3&dir4=$4 [L]
RewriteRule ^/([a-z0-9]+)/([a-z0-9]+)/([a-z0-9]+)/?$ /index.php?dir1=$1&dir2=$2&dir3=$3 [L]
RewriteRule ^/([a-z0-9]+)/([a-z0-9]+)/?$ /index.php?dir1=$1&dir2=$2 [L]
RewriteRule ^/([a-z0-9]+)/?$ /index.php?dir1=$1 [L]
I emphasize should because only you can really say what your site structure is & how this cascading ruleset would affect your application.
The regex used is fairly simple:
([a-z0-9]+)
That captures any directory name with letters & characters. If you want to capture—let’s say—underscores and dashes on top of that, it would change to something like:
([a-z0-9_-]+)
The first rewrite rule I have set—^/([a-z0-9]+)/?([^/]*)$—is to capture anything that comes after dir1 just in case there’s data to capture that is not a strict directory structure. You can comment that out if you wish. Just added it since that’s how I like to handle situations that need URL parsing like this.
Also, have you considered adding this to the rewrite rule? Perhaps at the top before the rules cascade in?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
I would suggest you this
http://domain/dir1-dir2-dir3-dir4-dir5-file.html
rules
RewriteEngine On
RewriteBase /
RewriteRule (.+)-(.+) $1/$2 [N]
you can even make it dynamic by adding these
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1
this is much cleaner.
UPDATE:
well I didn't mean you use the second part but anyways I explain what I meant, it's not wrong that people use QUERY STRING for passing path in URL but it's important how you do that like in this URL
http://domain/index.php?route=dir1/dir2/dir3/dir4/dir5/file.html
as you can see you will grab the path easily with just one GET variable and even handling of this in RewriteRule is much easier like
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?route=$1&%{QUERY_STRING} [L]
which will let you to have a URL like this
http://domain/dir1/dir2/dir3/.../file.html
and with any reason you may change those slash to hyphen or other acceptable chars which become like this
http://domain/dir1-dir2-dir3-dir4-dir5-dir6-dir7-file.html
and as I said it's more easier to pass the current QUERY_STRING which will look like this
http://domain/dir1-dir2-file.html?q=extra_query_value
and result in PHP if you dump $_GET will be:
q => 'extra_query_value'
route => 'dir1/dir2/file.html'
and finally in PHP you may easily explode them to have all folders' name by individual variable.

Rewriting example.com/section.php?username=xyz to example.com/xyz/section

Using the following htaccess, I have been able to rewrite example.com/profile.php?username=xyz to example.com/xyz,
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)$ profile.php?user=$1
RewriteRule ^([a-zA-Z0-9_-]+)/$ profile.php?user=$1
Adding the following to the above,
RewriteRule ^([a-zA-Z0-9_-]+)/section$ section.php?user=$1
RewriteRule ^([a-zA-Z0-9_-]+)/section/$ section.php?user=$1
did not resolve example.com/section.php?username=xyz to example.com/xyz/section.
Am I doing something wrong here?
First of all: The manner of speaking would rather be the opposite: The rules you showed are to rewrite requests like /xyz internally to /profile.php?username=xyz and not vice versa.
Now if you want to rewrite requests like /xyz/section internally to /section.php?username=xyz where section and xyz are variable, try these rules:
RewriteRule ^([a-zA-Z0-9_-]+)/?$ profile.php?user=$1
RewriteRule ^([a-zA-Z0-9_-]+)/([^/]+)/?$ $2.php?user=$1
To look for static files (images, css) in the right directory without having to write the file address, do:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Before writing the code suggested by RageD
(Sorry, should have posted it as a comment but I needed newlines)
I tested it and it works. Try this:
RewriteRule ^([a-zA-Z0-9_-]+)\/section$ section.php?user=$1
RewriteRule ^([a-zA-Z0-9_-]+)\/section\/$ section.php?user=$1
All I did was escaping the / in the URL since / is a regex delimiter.

Why won't this simple RewriteRule work?

This should be simple but I cannot figure it out. I have this very simple mod_rewrite rule and it just doesn't want to work. This is the entire contents of the .htaccess file.
RewriteEngine On
RewriteRule ^([A-Za-z0-9-_/\.]+)/?$ index.php?page=$1 [L]
If I call the URL domain.com/foo it should rewrite it to index.php?page=foo. But instead, it rewrites it to index.php?page=index.php. I have tried multiple URLs:
index.php?page=foo
index.php
/foo
/
In all cases, PHP acts as if 'page' is set to "index.php". It isn't a fault with index.php because I replaced the entire contents of index.php with a script that simple echoed the value of 'page' and it still comes out as index.php.
Really lost where I'm going wrong here, any help would be awesome!
Thanks
Adrian
Any reason you can't use something simpler, such as:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?page=$1 [L]
If you're trying to keep existing pages from being re-written, then the !-f will take care of that (if file does not exist and if directory does not exist, then re-write)
I think this is what your looking for. Unfortunately it doesn't really work well if the URL has other GET arguments (IE, /some/url/path?page=1).
RewriteEngine On
RewriteRule ^(.*)$ index.php?page=$1 [L]
Better idea.
RewriteEngine On
RewriteRule ^(.*)$ index.php [L,QSA]
The QSA flag will forward the GET params and then in index.php use $_SERVER['REQUEST_URI'] and parse_url to route the request.
From http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html:
'qsappend|QSA' (query string append)
This flag forces the rewriting engine to append a query string part
in the substitution string to the existing one instead of replacing it.
Use this when you want to add more data to the query string via a rewrite rule.

Categories