How can i split URL with htaccess - .htaccess

For example:
google.com/en/game/game1.html
should be
google.com/index.php?p1=en&p2=game&p3=game1.html
how can i split URL and send index.php the part of "/" ?

You can only achieve this if the query parameters are of a fixed length. Otherwise there is an other way but requires parsing of the path in the application.
Fixed length implementation
The following rule matches all three URL parts then rewrites them as named query arguments to index.php.
RewriteRule ^([^/]+)/([^/]+)/(.+)$ index.php?p1=$1&p2=$2&p3=$3
This rewrites:
/en/game/game1.html
To:
/index.php?p1=en&p2=game&p3=game1.html
Unknown length implementation
# Don't rewrite if file exist. This is to prevent rewriting resources like images, scripts etc
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php?path=$0
This rewrites:
/en/game/game1.html
To:
/index.php?path=en/game/game1.html
Then you can parse the path in the application.
Edit:) To make it so the rewrite rule only matches if the first level of the URL consists of two characters do:
RewriteRule ^([a-zA-Z]{2})/([^/]+)/(.+)$ index.php?p1=$1&p2=$2&p3=$3
You can also do it for the unknown length implementation so:
RewriteRule ^[a-zA-Z]{2}/ index.php?path=$0

Related

HTACCESS How to "cut" URL at one point

I am new to .htaccess and I don't understand it well. Recently I have built the following code:
RewriteEngine On
RewriteCond %{HTTP_HOST} (.*)
RewriteCond %{REQUEST_URI} /api/v2/
RewriteRule ^api/v2(.*) /api/v2/api.php?input=$1
This was in the root public folder (example.com/.htaccess). But now I have to create second Rewrite and I want to make .htaccess file in example.com/api/v2/ folder. I tried to remove /api/v2/ part in each Rewrite Rule, but only thing I got was error 500.
What I want to achieve:
If someone uses this link: https://example.com/api/v2/test/test/123, I'd like to make it into https://example.com/api/v2/api?input=test/test/123 with .htaccess located in example.com/api/v2 folder.
Addressing your existing rule first:
RewriteCond %{HTTP_HOST} (.*)
RewriteCond %{REQUEST_URI} /api/v2/
RewriteRule ^api/v2(.*) /api/v2/api.php?input=$1
The first RewriteCond (condition) is entirely superfluous and can simply be removed. The second condition simply asserts that there is a slash after the v2 and this can be merged with the RewritRule pattern. So, the above is equivalent to a single RewriteRule directive as follows:
RewriteRule ^api/v2(/.*) /api/v2/api.php?input=$1 [L]
This would internally rewrite the request from /api/v2/test/test/123 to /api/v2/api.php?input=/test/test/123 - note the slash prefix on the input URL parameter value.
However, unless you have another .htaccess file in a subdirectory that also contains mod_rewrite directives then this will create a rewrite loop (500 error).
Also note that you should probably include the L flag here to prevent the request being further rewritten (if you have other directives).
If someone uses this link: https://example.com/api/v2/test/test/123, I'd like to make it into https://example.com/api/v2/api?input=test/test/123 with .htaccess located in example.com/api/v2 folder.
I assume /api? is a typo and this should be /api.php?. Note also that the slash is omitted from the start of the URL parameter value (different to the rule above).
I tried to remove /api/v2/ part in each Rewrite Rule, but only thing I got was error 500.
This is the right idea, however, you need to be careful of rewrite loops (ie. 500 error response) since the rewritten URL is likely matching the regex you are trying to rewrite.
Try the following instead in the /api/v2/.htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_URI} !api\.php$
RewriteRule (.*) api.php?input=$1 [L]
The preceding RewriteCond directive checks that the request is not already for api.php, thus avoiding a rewrite loop, since the pattern .* will naturally match anything, including api.php itself.
You could avoid the additional condition by making the regex more specific. For example, if the requested URL-path cannot contain a dot then the above RewriteCond and RewriteRule directives can be written as a single directive:
RewriteRule ^([^.]*)$ api.php?input=$1 [L]
The regex [^.]* matches anything except a dot, so avoids matching api.php.
Alternatively, only match the characters that are permitted. For example, lowercase a-z, digits and slashes (which naturally excludes the dot), which covers your test string test/test/123:
RewriteRule ^([a-z0-9/]*)$ api.php?input=$1 [L]
Or, if there should always be 3 path segments, /<letters>/<letters>/<digits>, then be specific:
RewriteRule ^([a-z]+/[a-z]+/\d+)$ api.php?input=$1 [L]

How to mod rewrite this URL correctly?

I am adding a REST API to my application. The REST API is located at /api of my app. I want to route all requests correctly including requests that have parameters. I have the following htaccess rules which are working for the most part:
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L]
</IfModule>
Using these rules, I can now go to:
mysite.com/api/projects/get and it will correctly give me back JSON data as if I would have accessed it the regular way mysite.com?url=api/projects/get
My problem begins when I try to add parameters to the request.
My application will already handle parameters. So if I were to go to: mysite.com/api/projects&type=1, it will give me back the projects of type 1. However, I think it is expected that the URL would look more like: mysite.com/api/projects?type=1 (note the ? instead of the &)
How would I modify my htaccess rules to handle this?
I was trying the following but with no luck:
RewriteRule ^(.*)/?(.*)$ index.php?url=$1&$2 [L]
You'll need to use the Query String Append flag, as shown below:
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
Per the documentation:
When the replacement URI contains a query string, the default behavior
of RewriteRule is to discard the existing query string, and replace it
with the newly generated one. Using the [QSA] flag causes the query
strings to be combined.
Consider the following rule:
RewriteRule "/pages/(.+)" "/page.php?page=$1" [QSA]
With the [QSA] flag, a request for /pages/123?one=two will be mapped to
/page.php?page=123&one=two. Without the [QSA] flag, that same request
will be mapped to /page.php?page=123 - that is, the existing query
string will be discarded.

.htaccess rewriterule /directory/ to php

I have a problem with showing images and css files on my site when using RewriteRule on .htaccess file:
RewriteEngine On
RewriteRule ^home/?$ page.php?id=home [L,QSA]
RewriteRule ^stats/?$ statspage.php?id=abcd [L,QSA]
...but the images and css files not loaded.
Add a RewriteCond before each RewriteRule:
RewriteEngine On
RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|png|css)$ [NC]
RewriteRule ^home/?$ page.php?id=home [L,QSA]
RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|png|css)$ [NC]
RewriteRule ^stats/?$ statspage.php?id=abcd [L,QSA]
RewriteCond provides more detailed qualifications for a particular RewriteRule.
%{REQUEST_URI} is a server variable. It provides the requested URL path, i.e, the portion after the domain name, but not including the query string.
The condition I added to your rules allows all URLs that end in the listed extensions to skip that particular rewrite. Which means Apache can send the resource as it is requested.
The exclamation mark ! means NOT.
Periods have a special meaning in regular expressions so if you want to match an actual period they need to be escaped with a backslash: \..
The combination of parenthesis: () and pipes: | create alternating lists: (gif|jpe?g|png|css). So here any extension will match: gif OR jpeg OR jpg OR png OR css. The question mark after the e in jpe?g makes the e optional, hence jpeg OR jpg.
The dollar sign $ means "end of string", so the matched pattern must be the last thing in the URL path.
In English: Apache mod_rewrite is instructed to match URL paths that do NOT end in a period followed by either "gif", "jpeg", "jpg", "png", or "css". Therefore URLs that do match (images and css) skip the rule.

How to pass specific query strings in a URI using .htaccess file? (e.g. from domain.com/ce/hello-world/ce/ to domain.com/hello-world/ce/ )

I'm developing a website and have a htaccess rule as follows:
RewriteRule ^(ac|bc|cd)/(.*) $2?folder=$1 [L,QSA]
But, I want to pass all requests having /ab/ or /bc/ or /cd/ or any URI with two letters between slashes /../ right after the domain.com (i.e. domain.com/ab/, domain.com/ac/, domain.com/ad/, ...) from http://domain.com/ab/hello-world/ to http://domain.com/hello-world/, or from http://domain.com/ab/cf/hello-world/ to http://domain.com/cf/hello-world, or from http://domain.com/ce/hello-world/ce/ to http://domain.com/hello-world/ce/. Note that I only wanna pass the above query strings which appear right after .com (e.g. .com/ax/ or .com/re/, etc) not in the middle or end of the URI.
You can try this rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(ac|bc|cd)/(.+) $2?folder=$1 [L,QSA]

How to make a clean .htaccess?

i have problem with htaccess and not quite good at it. I want to know how to make a url clean.
Here is the original
http://site.com/page.php?p=index1/index2
and i want this type of url
http://site.com/page/index/index2
and how do i get the p value which is index1/index2 if i what to $_get it from the database?
The pattern ([^/]+) matches everything up to but not including / into $1 and the remainder is captured in (.*) into $2.
RewriteEngine On
# Don't rewrite real existing files & directories (like css,js,img)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Add .php to the first group (like page.php) and stick the rest into p
RewriteRule ^([^/]+)/(.*)$ $1.php?p=$2
Inside of PHP, retrieve the value of p via:
$_GET['p']

Resources