I currently have an api.php file built using the Slim Framework. I'd like to use something like api.mydomain.com (or mydomain.com/api) to reference the API file and make calls using http://api.mydomain.com as the base url. The Slim documentation calls for the following to be added to your .htacess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
But if I'm correct, that returns the index.php file if the file requested doesn't exist. How best to setup a rewrite from api.mydomain.com or mydomain.com/api to the index.php? Everything we've found points to configuring this using .htaccess.
We used the following rewrite rule, but this resulted in having slashes ('/') appended to all of our URLs, which also required us to reconfigure our routes in Slim as well. (Example: "/messages" became "/messages/" and "/threads?id=123" became "/threads/?id=123")
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} ^api\.mydomain\.com [NC]
RewriteRule ^ api.php [QSA,L]
While it is possible to fix this with some complex apache rules (see the links included), this was actually addresses in Slim version 2.2+ so you are far better off just updating your version of slim (phar version set to "2." or "2.2.").
http://www.slimframework.com/install
If you decide to go the apache route (not recommended) then check these links:
https://webmasters.stackexchange.com/questions/23382/how-to-remove-trailing-slashes-from-url-with-htaccess
htaccess remove .php, .html and trailing slash
Related
I have this web api project which is developed by other company. The file structure is:
/project
---/app
---/ApiEndpoint.php
---/public
---/index.php
The DocumentRoot is pointing to /project/public. The index.php is working (http://myapi.com/), however when I try to browse into the api endpoint http://myapi.com/api/endpoint I got 404 error.
How do I configure the .htaccess to rewrite this condition?
/project/public/.htaccess config
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^?]*)$ /index.php?path=$1 [NC,L,QSA]
</IfModule>
The current configuration is there to make sure every request go to index.php (that is probably dispatching requests in some way) except for the files that actually are in the public directory (probably needed for static files like images, and such).
If you wrote a php yourself to be directly called by http://myapi.com/api/endpoint, you should put it in /project/app/public/api/endpoint/index.php.
BUT I suspect you should study that application more and understand the current dispatching method, before doing that.
I am using Slim Framework v3. I've set up API and its working smoothly if I access http://localhost:8080/slimapp/public
I have default directory structure. My Sample API endpoint is http://localhost:8080/slimapp/public/cards which returns JSON response of my cards
How Could I change the public folder to the domain, So I would be able to access my cards endpoint with http://localhost:8080/slimapp/cards?
You can simply rewrite the requests with
RewriteCond %{REQUEST_URI} !^/slimapp/public
RewriteRule ^slimapp/(.*)$ /slimapp/public/$1 [L]
This will serve the appropriate public folder, without redirecting the client. The RewriteCond is needed to avoid a redirect loop.
You can also edit Slim's default .htaccess file as:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ public/index.php [QSA,L]
Note: .htaccess file must be located in server root
Here is the baffling sequence of events that just transpired.
1) I have a working Laravel installation, with an empty .htaccess file, all URLs work.
2) I add some rules to .htaccess just to play around a bit, then remove the rules.
3) Now I have an empty .htaccess again (so nothing has changed compared to step 1 above) but now no URLs work anymore except the homepage.
For example, you will see that http://jovansprojects.com/march_madness/ works (that's the root of the Laravel folder), using this route:
Route::get('/', 'HomeController#showWelcome');
But http://jovansprojects.com/march_madness/login does not work anymore, despite having worked normally before.
This is the relevant route:
Route::get('login', 'SessionsController#create');
Note that it doesn't throw a Laravel error, like a 'not found exception' - it simply doesn't seem to know Laravel is installed there at all.
I've tried clearing Artisan's cache according to some online suggestions but didn't help.
So, to sum up: .htaccess is exactly the same as it was before (empty) but it seems the server doesn't even know to ask Laravel to handle the URLs anymore, not beyond the homepage anyway.
These are the rules I added to, and then removed from, .htaccess (I wanted to redirect trailing slashes):
Options -MultiViews
RewriteEngine On
RewriteBase /march_madness/
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ $1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
I suspect that RewriteBase may have something to do with it, but after I deleted the rules why didn't it revert to the way it was?
It would seem that Laravel does need the "Front Controller" in .htaccess in order to be able to route "pretty" URLs (ie. without having to use index.php in the URL and rely on PATH_INFO).
So, at the minimum, something like the following would be required in the .htaccess file (probably in the root of your Laravel install):
RewriteEngine On
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
It would seem that there were two .htaccess. Note that .htaccess files are inherited along the filesystem path. However, mod_rewrite (to which the directives above belong) is not inherited by default. So, if you enable the rewrite engine in a subdirectory then the mod_rewrite directives in the parent directory will be ignored.
I need to rewrite links of api/mobile/3/* to api/mobile/v3/* due to a restriction of our router, we're modernizing an existing codebase (paths can't start with numbers because they map to php namespaces)
The following works if I add an R flag to the api rewrite - as in it redirects me to the proper place.
I can't have a redirect though as the existing apps that use this API will not follow a redirect.
# make sure mod_rewrite is ON
RewriteEngine On
# rewrite api 3 to v3
RewriteRule ^api/mobile/3/(.*) api/mobile/v3/$1 [QSA]
# send other requests to the application
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /index.php [QSA,L]
When I remove the front controller call, Apache gives me a 404 to the correct v3 path I want, so the problem I suspect is somewhere in the combination of the first RewriteRule and the second.
I'm realizing while writing this that this is probably because rewrite just changes what file gets executed and not the SERVER variables.
Is there any way to get apache to rewrite what gets handed off to the front controller to make this work?
I am using Phil Sturgeon's REST server for CodeIgniter and want to modify the functionality so I can support URLs like these:
http://api.example.com/users
http://api.example.com/users/1
To get a list of users and a single user respectively, instead of the ones it supports like these:
http://api.example.com/users
http://api.example.com/users?id=1
I read on his blog that this should be possible using mod_rewrite, but have been unable to get this working as expected.
The default CodeIgniter .htaccess looks like this:
RewriteEngine on
RewriteCond $1 !^(index\.php|css|images|js|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
And I have tried to add my own rules to attempt to achieve this functionality. This is one that I expected to work correctly. It is placed after the activation of the RewriteEngine and before the CodeIgniter rules.
RewriteRule ^users/([0-9+]) /users?id=$1 [NC]
I figured this would then cascade down to the next rule which would route through CodeIgniter and then hit the correct users.php controller, then the index_get method (as remapped by the REST Server).
Instead, I get an 'unknown method' error - it appears as though CodeIgniter is trying to use the user integer as a function, for example in users/12 it is trying to find the 12() method in users.php.
Does anyone know what is going wrong here, or can recommend a solution to this problem?
CodeIgniter uses a front controller pattern and supports clean URLs. This means that it should be able to transparently pick up and route requests they way you want. You should be able to set your web server to route all requests to CodeIgniter's index.php and modify it's configuration file to suit.
Edit your system/application/config/config.php file and set the index_page variable: $config['index_page'] = '';. Then, edit your .htaccess file or your virtual host configuration file in Apache to use something like:
# Turn on the rewriting engine.
RewriteEngine On
# Default rewrite base to /
RewriteBase /
# Rewrite if the request URI begins with "system":
RewriteCond %{REQUEST_FILENAME} ^system
RewriteRule ^(.*)$ index.php/$1 [NC,L]
# Or if it points at a file or directory that does not exist:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Also rewrite it to the front controller.
RewriteRule ^(.*)$ index.php/$1 [NC,L]
Edit: Check out this answer from the author himself, who says that CodeIgniter should pick up either query string or URI segment styles by default.
Edit 2: Ah, I see what you mean. You don't want to have the query variable name as a URI segment. You can probably fix this by modifying your routes file, such that it sends all queries to a single method on that controller.