Rewrite URL parameters with htaccess just doesnt work?

Hello guys. been searching the whole internet and tried every single thing I have found but i cant make it work. i would really really appreciate if somone could help me with this

i have hidden .php extensions in the url. schedule is a .php file

i simply has a webpage looking like this:
example .com/folder/schedule?c=test
but i want it to look like this
example. com/folder/schedule/test

Then i have another similar page but with 2 parameters.
example .com/schedule?c=test&day=today
i want it to look like
example.com/schedule/test/today
and if only one of the parameters
example.com/schedule/today

That’s the hard part. If there is only one of the parameters, how would you know whether it the c parameter or the day parameter?

Can you make it so that c is always required? That would make it a lot easier.

1 Like

Yes, that would work

Perhaps add another file:

http://example.com/schedule-date/today
http://example.com/schedule-date/2020-04-22

1 Like

Hm I think it would be easier for me to have one file and make both parameters required, for now at least. Even tho your example would be more clean

1 Like

Right, I’d start off with this:

RewriteEngine On

RewriteRule ^schedule/([^/]+)/([^/]+)$ /schedule.php?c=$1&day=$2 [L]
RewriteRule ^schedule/([^/]+)$ /schedule.php?c=$1 [L]

That means:

  1. “schedule” followed by a slash, then something, then a slash and then something else must be rewritten to /schedule.php?c=something&day=something else
  2. “schedule” followed by a slash, then something must be rewritten to /schedule.php?c=something

Now it depends on how you’ve setup Apache to hide the .php extension - if you’ve used MultiViews for that then the above won’t work because MultiViews takes precedent over rewrites.

In that case I would advise to disable multiviews using Options -MultiViews (on a separate line) and then add a rule for /schedule like so:

RewriteRule ^schedule$ /schedule.php [L]
1 Like

Standard practise with most PHP Frameworks and Content Management Systems is to redirect all browser requests to a default index.php if and only if the request is not a specific file or directory:

file: .htacces

# REWRITE STUFF     
  RewriteEngine On

# ONLY CALL ONCE 
# <IfModule mod_rewrite.c>
  # FORCE NON-WWW
    # RewriteCond %{HTTP_HOST} ^www.example.com [NC]
    # RewriteRule ^(.*)$ https://example.com/$1 [L,R=302]
 # Force www:
   # RewriteCond %{HTTP_HOST} ^example.com [NC]
   # RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301,NC]

  # FORCE PRETTY-URLs  
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$  index.php/?$1 [L]
# </IfModule>  
ErrorDocument 404 error-document.html

file: index.php

<?php 
declare(strict_types=1);

// following two lines should be set in php.ini
   error_reporting(-1);
   ini_set('display_errors', '1');

  $page = $_SERVER['QUERY_STRING'] ?? 'home';
  $page = empty($page) ? 'home' : $page;
  $page = explode('/', $page)[0];
  switch($page):
    case 'home' :
      // do stuff here
    break;

    case 'search' :
      // do stuff here
    break;

    case 'search-date' :
      // do stuff here
    break;

    default:
      // do stuff here
    break;
  endswitch;  

This method is more expandable and also good for SEO link juice :slight_smile:

1 Like

Ideally you should not need to use <IfModule...>. You should know whether the module is loaded or not and either include the appropriate directives - or not.

2 Likes

I have tried that exact line so many times but every time i get the error - 500 Internal Server Error

This is what my htacces looks like

# Start rewrite rules
RewriteEngine on
RewriteBase /  

# Remove php extension
rewritecond %{SCRIPT_FILENAME}.php -f
rewriterule [^/]$ %{REQUEST_URI}.php [QSA,L]
rewriterule ^(.*)/$ $1 [R=301,L]

RewriteRule ^schedule/([^/]+)$ /schedule.php?c=$1 [L]


ServerSignature Off

DirectoryIndex schedule.php  

oh thank you! i might have to implement that then

Do you have access to the Apache logs? Does it say what’s wrong?

1 Like

Request exceeded the limit of 10 internal redirects due to probable configuration error. Use ‘LimitInternalRecursion’ to increase the limit if necessary. Use ‘LogLevel debug’ to get a backtrace.

i do not use wordpress btw and I am on localhost

That would indicate the .htaccess causes Apache to redirect in a loop, so it rewrites a URL to something else, then again, and again, and again, etc, until Apache stops it

Is what you posted your full .htacess file?

1 Like

Try the .htaccess file I supplied and replace index.php with schedule.php

1 Like

Thank you guys. I think i am closer now. I still get the same error in apache log but now the HTML get shown(before i got the 500 Internal Server Error over the whole page) on schedule.php, but all the style and js files seems to fail to be linked?

# Start rewrite rules
RewriteEngine on
RewriteBase /  

# remove .php extensions  
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]

DirectoryIndex schedule 
RewriteRule ^/?$ schedule [L,R]

# FORCE PRETTY-URLs  
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$  %{REQUEST_FILENAME}.php/$1 [L]

Options -Indexes
ServerSignature Off

oh well the “loop” problem is still there.

I’d recommend moving away from the magic and switch to being very explicit about what URLs should map where.

So say you have /schedule that should load /schedule.php and /course that should load /course.php, write rules like so:

RewriteRule ^schedule$ /schule.php [L]
RewriteRule ^course$ /course.php [L]

That makes your .htaccess file really easy to read and it will never accidentally match something you didn’t mean to. Just make take into account that Apache tries URL from top to bottom, so start with the more specific URLs at the top and work your way down to the more generic.

For example:

RewriteRule ^schedule/([^/]+)$ /schedule.php?c=$1 [L]
RewriteRule ^schedule$ /schedule.php

The top has more parts and is more specific. Ordering them this way you can be sure a more generic one will never win over a more specific one.

1 Like

Today the htaccess file worked flawlessly as i want it to. Weird but I dont mind.
Thank you so very much for the help guys

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.