1

This is my .htaccess code:

RewriteCond %{REQUEST_URI} !^/pages/ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)(/([^/]+))? pages.php?PAGE=$1&LINK=$3 [L]

*where $1 = profile and $3 = john-smith

This is works fine rewriting like https://example.com/profile/john-smith but I need a second rewrite rule like https://example.com/john-smith only if the second parameter that contains john-smith exist.

Thank you!

UPDATE: (Complete rules of my .htaccess file)

# protect files beginning with .
RewriteRule /\.(.*) - [NC,F]

# redirect HTTPS
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

# No root access without index.* and other security
RewriteEngine On
Options All -Indexes
RewriteBase /
DirectoryIndex index.php index.html index.htm
ErrorDocument 404 https://example.com/pages.php?PAGE=404

# Prevent upload malicious PHP files
<FilesMatch “\.(php|php\.)$”> 
Order Allow,Deny 
Deny from all 
</FilesMatch>

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [QSA,L]

RewriteCond %{REQUEST_URI} !^/pages/ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)(/([^/]+))? pages.php?PAGE=$1&LINK=$3 [QSA, L]
Adrian
  • 11
  • 2
  • Can you please explain in natural language exactly what you are trying to do. ie. The URLs being requested and the expected target URLs? There are no "URL parameters" in the two example URLs you've stated (the "URL parameters" are only present in the URL being rewritten to). "I need a second rewrite rule like `https://example.com/john-smith` only if the second parameter that contains john-smith exist" - There is no "2nd parameter" in that URL, there is just one _path segment_ `john-smith`? – MrWhite Aug 08 '21 at 12:16
  • 1
    The orriginal url structure before my htaccess code looks like this: https://example.com/pages.php?PAGE=profile&LINK=john-smith. Only I need to do right now it's to remove firs parameter (PAGE=profile) whend second exist, because I have situations when only the first parameter exist. – Adrian Aug 08 '21 at 13:01
  • So, when a request comes in for `example.com/john-smith` (ie. just one path segment and no trailing slash) it should rewrite the request to `/pages.php?LINK=john-smith`? – MrWhite Aug 08 '21 at 14:37
  • 1
    Yes, exactly... – Adrian Aug 08 '21 at 15:03

1 Answers1

0
RewriteRule ^([^/]+)(/([^/]+))? pages.php?PAGE=$1&LINK=$3 [L]

The "problem" with this is that it will also match a request for /john-smith (the 2nd group is optional), but rewrites the request to pages.php?PAGE=john-smith&LINK=, instead of pages.php?LINK=john-smith as required. For this you will need a separate rule. It also matches /profile/john-smith/anything, discarding /anything but still rewrites the request (a many to one relationship) which potentially opens your site up to spammers.

Assuming you are not allowing dots (.) in the URL path segments (as per your examples) then there's no need to check that the request does not map to a file. eg. a request for /profile/john-smith could never map to file if your files all have file extensions, so the filesystem check is redundant.

Try the following instead:

# Rewrite exactly one path segment
# eg. /john-smith to pages.php?LINK=john-smith
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/.]+)$ pages.php?LINK=$1 [L]

# Rewrite exactly two path segments
# eg. /profile/john-smith to pages.php?PAGE=profile&LINK=john-smith
RewriteCond %{REQUEST_URI} !^/pages/ [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/.]+)/([^/.]+)$ pages.php?PAGE=$1&LINK=$2 [L]

The NC flag on the preceding RewriteCond directive is probably redundant.

([^/.]+) - I've changed the capturing subpattern to also exclude dots. And the second rule matches exactly two path segments, not one or two path segments, as in your example.

MrWhite
  • 12,647
  • 4
  • 29
  • 41
  • Thank you so much for your reply! Unfortunelly, your solution doesn't work for my situation... The "two part segment" code works only if I change $ with ? and without dot. The "one part segment" doesn't work at all. – Adrian Aug 08 '21 at 18:05
  • @Adrian What do you mean by "doesn't work"? What happens exactly? Do you get an error? What response do you see? If the "two part segment" only works if you change it then it's matching something different to the example URLs as stated. What other directives do you have in this `.htaccess` file? Please edit your question to include your complete `.htaccess` file with these directives in place - you may have a conflict. And where is this `.htaccess` file located? Do you have any other `.htaccess` files? – MrWhite Aug 08 '21 at 19:24
  • I've just update my question with the complete rules of my .htaccess file. So, the htaccess file is located on the same folder with the pages.php and it's the only one I have. It's not a particular error for the "one part segment" rules. Actually, the result look like a lost page with some snippets of my header and footer, not showing the right content as it loads when I acces without rewrited url. – Adrian Aug 08 '21 at 19:43