I come from a C# MVC background but I am currently working on a PHP project.
In C# you can setup decorators to specify the request URL using something along these lines:
[HttpGet]
[Route("/ControllerName/ActionName")]
public string MyAction() {
// ...
}
I am wanting to set something similar up in PHP, so I set my file structure like this:
+ assets
+ css
+ javascript
+ images
+ server
+ api
+ controllers
- index.php
+ ui
+ area1
- view1.html
- view2.html
+ area2
- etc.html
- .htaccess
- index.html
Where index.html is my login page, the other html pages live in their respective /ui/area directory, and my restful API pages live in /server/api/controllers. The /server/api/index.php follows a very similar pattern to this Stack Overflow answer: https://stackoverflow.com/a/1737903/1920035
In my .htaccess file, I have the following redirect rule setup:
# Redirect traffic starting with /api to the /server/api/index.php file
Redirect 301 ^(api/.*)$ /server/api/index.php [L,QSA]
The idea is that if I hit /api/account/get that it will redirect to the /server/api/index.php file and run its magic to run the respective controller/action.
The issue is that when I spin up my server and hit the pretty URL that it always returns a 500 response without any useful response text.
To complicate things, I'm running Docker for Windows using php:8.2.2-apache.
What am I doing wrong here? I do not have much experience setting up .htaccess files and with a vague 500 response, I don't have much to go off of.
You need to check Apache's error log for the details of the 500 error. However...
This is syntactically invalid (which might account for the 500 error) and the wrong directive to use here.
Redirectis a mod_alias directive that triggers an external redirect.[L,QSA]are "flags" used with the mod_rewriteRewriteRuledirective. TheRedirectdirective does not take a regex as an argument (it uses simple prefix-matching).But you shouldn't be triggering an HTTP external (301) redirect here, you need to internally rewrite the request instead (the user should not be aware of the underlying
/serversubdirectory).For this (URL rewriting) you need to use mod_rewrite (so this needs to be installed if not already). For example:
A request for
/api/<anything>would be internally rewritten to/server/api/index.php.No need for the capturing group and
.*suffix on the original regex. So,^api/is essentially the same as^(api/.*)$, but more efficient. The slash prefix on the substitution string (2nd argument) is not required with internal rewrites (and best omitted - so it is treated as a filesystem path and not a URL-path).mod_rewrite (
RewriteRule/RewriteConddirectives) is capable of issuing (complex) external redirects as well as internal rewrites. mod_alias (Redirect/RedirectMatchdirectives) is for simple external redirects only. (Having said that, mod_alias also has some directives used for internal filesystem mapping.)Reference: