.htaccess detect numbers separated by '-' - apache

I couldn't find any helpful resource on the web, so I'm just asking it here
I have my .htaccess file with the following lines of code:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^KOP/shop/(\d+)*$ KOP/shop/details.php?id=$1 [L]
RewriteRule ^KOP/order/(\d+)*$ KOP/order.php?id=$1 [L]
When I enter
localhost/KOP/order/1612-8077-68
I get a page not found error
But when I enter
localhost/KOP/order/1612807768
The rewrite works, and writes out the number from $_GET
I would like to know what should I change in my code to let it rewrite with the dashes between the numbers. Is there a line in my .htaccess file telling apache to redirect only numbers?

Based on your shown samples, could you please try following. Please make sure you clear your browser cache before testing your URLs.
RewriteEngine ON
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^KOP/shop/(\d{4})-(\d{4})-(\d{2})$ KOP/shop/details.php?id=$1$2$3 [L]
RewriteRule ^KOP/order/(\d{4})-(\d{4})-(\d{2})$ KOP/order.php?id=$1-$2-$3 [L]
// Remove the dashes to get only the numbers ↑
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^KOP/shop/(\d+)*$ KOP/shop/details.php?id=$1 [L]
RewriteRule ^KOP/order/(\d+)*$ KOP/order.php?id=$1 [L]

Related

Rewrite URLs in .htaccess for replacing Query parameters with forward slash (id?=value)

I have made sure that rewrite engine is enabled and removing .php extensions is working so I know that isn't the issue.
what I'm trying to do is simply remove the ?id=value aspect of the URL, so basically making the URL look like such:
folder/medias/value
Instead of
folder/medias?id=value
My current .htaccess looks like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
RewriteRule ^404/?$ /404.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ 404.php [L,R]
With your shown samples/attempts, please try following htaccess Rules. Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
##Rules for external rewrite.
RewriteCond %{THE_REQUEST} \s/([^.]*)\.php\?id=(\S+)\s [NC]
RewriteRule ^ /%1/%2? [R=301,L]
##Rule for internal rewrite.
RewriteRule ^([^/]*)/([^/]*)/?$ $1?id=$3 [L]
You may try this code inside the /folder/.htaccess (create this file if it doesn't exist):
RewriteEngine On
# External redirect from /folder/media?id=val to /folder/media/val
RewriteCond %{THE_REQUEST} /(\S+?)\.php\?id=([^&\s]+)\s [NC]
RewriteRule ^ /folder/%1/%2? [R=301,L,NE]
# Internal rewrite from /folder/media/val to /folder/media?id=val
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w-]+)/([\w-]+)/?$ $1.php?id=$2 [L,QSA]
Trailing ? in first rule is to remove query string from original URL.
%{REQUEST_FILENAME} !-f and %{REQUEST_FILENAME} !-d is to skip existing files and directories from rewrite in 2nd rule.

friendly url only opens the post.php not cat.php

Friends, what is the right way to get both the php files to open friendly URL contents?
My current code works OK if I only use:
Options +FollowSymLinks
RewriteEngine On
# SEO URL Settings
RewriteBase /site/
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteRule ^(.*)$ post.php?id=$1 [QSA,L]
but then I also need friendly URL for my categories so I tried to add:
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteRule ^(.*)$ cat.php?cat=$1 [QSA,L]
but doing so only the post URL opens but category links redirect back to index.php but if you remove the rewrite for post than the cat.php contents shows.
If someone could help me out here would really appreciate your kindness.
This is because of your use of the [L] flag.
The [L] flag causes mod_rewrite to stop processing the rule set. In
most contexts, this means that if the rule matches, no further rules
will be processed. This corresponds to the last command in Perl, or
the break command in C. Use this flag to indicate that the current
rule should be applied immediately without considering further rules.
Documentation
Instead, try and have your rules laid out like this:
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteRule ^(.*)$ post.php?id=$1 [QSA]
RewriteRule ^(.*)$ cat.php?cat=$1 [QSA,L]

Removing page query string .htaccess

I have a .htaccess file that creates a SEO URL. For example, let's say the ugly URL is: example.com/stories?url=hello-world&page=5 the URL becomes example.com/stories/hello-world/5
This works perfectly, but for the first page I want the URL to not display the page number. For example, I want a URL like this example.com/stories/hello-world/1 to be example.com/stories/hello-world How do I do this?
Current .htaccess
RewriteEngine On
RewriteBase /stories/
RewriteCond %{THE_REQUEST} /\?url=([^&\s]+)&page=([0-9]+) [NC]
RewriteRule ^ %1/%2? [L,R=302]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?url=$1&page=$2 [L,QSA]
Try this it like this,
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# for hello world first page we are giving static value 1 to page.
RewriteRule ^([\w-]+)/?$ index.php?url=$1&page=1 [QSA,L]
# for others we are getting dynamic value.
RewriteRule ^([\w-]+)/([\d]+)$ index.php?url=$1&page=$2 [QSA,L]

Clean URL with mod_rewrite including sub directory inside domain

I am trying to use mod-rewrite in .htaccess for implementing clean/pretty URLs.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ details.php?id=$1 [L,QSA]
RewriteEngine On turns the engine on.
RewriteCond %{REQUEST_FILENAME} !-f does not rewrite anything if the
request filename exists, and is a file.
RewriteCond %{REQUEST_FILENAME} !-d does not rewrite anything if the
request filename exists, and is a directory.
RewriteRule ^([^/]+)/?$ details.php?id=$1 [L,QSA] This is the actual
rewrite rule. It takes anything after the domain name (anything
other than forward slashes), and rewrites it to details.php, passing
it as the id parameter.
RewriteRule ^([^/]+)/?$ details.php?id=$1 [L,QSA] is working when request for http://www.domain.com/texas
This is well and good. What I need is that my request URL looks like this:
http://www.domain.com/location/texas
and details.php has the below code
<?php
$id = $_GET["id"];
echo "new id is ".$id;
?>
Problem: I couldn't write a valid .htaccess RewriteRule to identify this request http://www.domain.com/location/texas.
Please help.
What all I tried?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^location/?$ details.php?id=$1 [L,QSA] - not working
RewriteRule ^location/[a-z][-a-z0-9]*?$ details.php?id=$1 [L,QSA] - working, but id is displayed blank.
You can just tweak your existing rule by making starting location/ optional:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(?:location/)?([^/]+)/?$ details.php?id=$1 [NC,L,QSA]

Order of rules in .htaccess file

I have an .htaccess file like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foo.*$ /cgi/foo.cgi [L]
RewriteRule ^.*$ /cgi/fallback.cgi [L]
but when I go to a URL starting with foo in that folder, the browser still gets redirected to the fallback.cgi script. If I remove the second rule, the 'foo' line works OK.
According to my understanding, the first rule should take precedence, and the [L] should prevent any other rules from happening.
You are right, the 1st rule should be applied first and I think it is. The problem might be the 2nd rule is also being applied, so the code should be like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foo.*$ /cgi/foo.cgi [L,NC]
RewriteCond %{REQUEST_URI} !/cgi/(foo|fallback)\.cgi [NC]
RewriteCond %{REQUEST_URI} !/foo [NC]
RewriteRule ^.*$ /cgi/fallback.cgi [L]
The ^ means beginning of string.
RewriteRule ^foo.*$ /cgi/foo.cgi [L]
So that rules ONLY matches /foo followed by zero or more characters.
To match a file beginning with "foo" use this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (^|/)foo.*$ /cgi/foo.cgi [L]
It matches:
/foo
/foo.php
/food.php
/foolish/dog
It does not match:
/kung-foo.cat
/FOO.php
Update
Remember that some browsers do redirect caching. I was testing this on my own server and had performed a redirect that was cached. Made me confused for a bit when my new rules weren't working.
It is applying 2nd rule because;
In 2nd rule your are matching .* (means everything)
RewriteCond lines are only being applied to 1st rule only
Correct code would be:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# don't do anything for a file, dir or symlnk
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ - [L]
RewriteRule (^|/)foo /cgi/foo.cgi [L,NC]
RewriteRule ^ /cgi/fallback.cgi [L]