Htaccess rewriting URL - multiple levels - php

This is probably a duplicate, I'm sorry in advance.
I'm having a bit of a thick moment and need some help with a rewrite rule:
RewriteRule ^([a-zA-Z0-9_-]+)/?$ /index.php?name=$1 [L]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)?$ /index.php?name=$2 [L]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)?$ /index.php?name=$3 [L]
This is currently how we rewrite one of our sites - until we had a bug with 4 levels E.g. /about/company/people/dean.
I could just add another rule to rewrite the 4th level to the index page - but is there a nice way of doing this?
Basically, the overall result - when a url of type '/a/b/c/d/e/f/g' is requested, it will rewrite to '/index.php?name=g' - or whatever is the last element in the url.

Stick to the end of string anchor. It should catch the last chunk after /:
RewriteRule .*/([a-zA-Z0-9_-]+)/?$ /index.php?name=$1 [L]

Related

.HTACCESS adding to slugs

So, I'm currently building a REST API in PHP.
I managed to get slugs working for the most part.
If I request /api/admin/v1/users/1, it will return the user I need.
However, I also need to be able to add to it, e.g. /api/admin/v1/users/1/keys.
The HTACCESS file managing the slug is in the folder itself (/users/).
RewriteEngine On
RewriteRule ^(.*)$ user.php?slug=$1 [L]
I tried adding another line, but I think I messed up (I'm not that advanced with HTACCESS)
RewriteRule ^(.*)/keys$ keys.php?slug=$1 [L]
This didn't do anything, it still returns the user object.
RewriteRule ^(.*)$ user.php?slug=$1 [L]
RewriteRule ^(.*)/keys$ keys.php?slug=$1 [L]
The first rule matches everything, so the second rule is never processed. But since the first rule matches everything it will also rewrite itself (to user.php?slug=user.php) on the second pass by the rewrite engine.
You can resolve these issues by making the regex more restrictive. From your example URL it looks like the slug is numeric - in which case you can restrict the regex to match digits (0-9) only.
For example:
RewriteRule ^(\d*)$ user.php?slug=$1 [L]
RewriteRule ^(\d+)/keys$ keys.php?slug=$1 [L]
Note that the first rule also matches an empty URL-path, ie. no slug at all (as does your original rule). The second rule does not permit an empty slug (it would never match anyway).
The second rule don't work because the L flag stay for: last - stop processing rules
So you need to edit to:
RewriteEngine On
RewriteRule ^(.*)$ user.php?slug=$1 [QSA, L]
RewriteRule ^(.*)/keys$ keys.php?slug=$1 [QSA, L]

htaccess 3 different urls in one php file

I have 3 step in one php file:
This is my htacess now:
RewriteRule ^igra/(.*)$ "/index.php?page=igra&id=$1"
RewriteRule ^igra/(.*)/sezona/(.*)$ "/index.php?page=igra&id=$1&season=$2"
RewriteRule ^igra/(.*)/sezona/(.*)/liga/(.*)$ "/index.php?page=igra&id=$1&season=$2&league=$3"
When i go in browser something like index.php?page=igra&id=$1 or index.php?page=igra&id=$1&season=$2 or index.php?page=igra&id=$1&season=$2&league=$3 sure with real values it works fine, but when i try to access with this pretty links it always show me the first rewrite rule..
I hope u understand me what i need here, best regards..
Your first rule is capturing everything, so the subsequent rules never get executed. Just switch them around:
RewriteRule ^igra/(.*)/sezona/(.*)/liga/(.*)$ /index.php?page=igra&id=$1&season=$2&league=$3 [L]
RewriteRule ^igra/(.*)/sezona/(.*)$ /index.php?page=igra&id=$1&season=$2 [L]
RewriteRule ^igra/(.*)$ /index.php?page=igra&id=$1 [L]
Notice also the addition of the L flag.

Conflicting mod_rewrite rules

This is the full set of rewrite code in my htaccess file, but I'm only having problems with a conflict in the last 3 rules. The final rule writes the URL I want, but returns travel.php instead of travel2.php
RewriteEngine On
Options +FollowSymLinks
RewriteCond %{http_host} ^www.example.com [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
RewriteRule ^(.+[^/])/$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^journal/([^/]*)$ /journal2.php?url=$1 [L]
RewriteRule ^travel/([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)$ travel.php?country=$1&url_string=$2
RewriteRule ^travel/([a-zA-Z0-9-]*)$ /travel2.php?cat=$1
RewriteRule ^travel/([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)$ travel2.php?cat=$1&subcat=$2
This is what I'm after from those last 3:
/travel/country/title-url-string (currently works & displays correct content)
/travel/category (currently works & displays correct content)
/travel/category/subcat (currently displays URL as I want it, but returns travel.php content instead of travel2.php)
I originally had an ID number in the travel.php rule, and removing that has resulted in the conflict. I'm aware two of the rules have the same pattern, so how can I best go about getting the results I want? Thanks for any help. :)
From last 3 rewrite rules:
1 & 3 check the same pattern where first one always take effect.
Further, as your category and country values cannot be distinguished each other here, I would suggest to append a unique identifier to the url as below:
RewriteRule ^travel/country-([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)$ travel.php?country=$1&url_string=$2
RewriteRule ^travel/category-([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)$ travel2.php?cat=$1&subcat=$2
So your matching urls would be:
/travel/country-countryname/title-url-string
/travel/category-categoryname/subcat

URL rewrite php query strings

I have two urls doing some queries which I'm struggling to rewrite in the manner I want.
First
/shop/index.php?category=catslug
which I want to be
/shop/category
Second
/shop/index.php?product=slug
to
/shop/category/product
I have this currently:
RewriteRule ^shop/([A-Za-z0-9-]+)/?$ shop/index.php?category=$1 [L]
RewriteRule ^shop/[A-Za-z-]+/([A-Za-z0-9-]+)/?$ shop/index.php?product=$1 [NC,L]
The problem is that one of the rules is ruining anything that starts with shop so that things like shop/cart doesn't work. I'm so confused. Is this possible?
Note that for shop/cart, the cart part matches the [A-Za-z0-9-]+ part of the first RewriteRule. So it is rewritten to shop/index.php?category=cart.
The way to avoid this, hoping that you have a relatively small number of fixed URLs, is to have a RewriteRule before your 2 rules like
RewriteRule ^shop/(cart|this|that|other|thing) - [L]
RewriteRule ^shop/([A-Za-z0-9-]+)/?$ shop/index.php?category=$1 [L]
RewriteRule ^shop/[A-Za-z-]+/([A-Za-z0-9-]+)/?$ shop/index.php?product=$1 [NC,L]
For requests matching one of the pipe-delimited strings (such as cart), - means don't change the request, and [L] means last (don't continue to the next rules).

How to implement URL rewriting two rules with the same extension?

My htaccess code:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)-([0-9]+)\.html$ post-details.php?post_id=$2 [L]
RewriteRule ^post-year-([0-9]{4})-([0-9]+)\.html$ post-details-year.php?post_year=$1&post_month=$2 [L]
The first rule is working and giving me the correct output but the second one is not; it jumped to the first rule with "post_details.php" desired "Post-details-year.php".
Additionally when I change the file extension:
Example:
RewriteRule ^post-year-([0-9]{4})-([0-9]+)\.html$ post-details-year.php?post_year=$1&post_month=$2 [L]
to
RewriteRule ^post-year-([0-9]{4})-([0-9]+)\.cgi$ post-details-year.php?post_year=$1&post_month=$2 [L]
the rewriting engine starts going over the your rules one by one until it find one that fits.
The problem was that your first rule was very powerful, and it catched URLs you didn't want it to.
When you try and access post-year-123.html, the first rule matches post-year to ([a-zA-Z0-9_-]+) part of the regex, and 123 to ([0-9]+), which then just redirects you according to the first rule.
If you switch them, and put the second rule first, it will first try to match it and will success, thus sending you to the place you want.

Categories