.htaccess mod_rewrite does not work with two parameters on localhost - php

I would like to have clean URLs in my projects. So I've written these codes in a .htaccess file.
RewriteEngine On
Options +FollowSymLinks
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ index.php?page=$1&id=$2 [NC,QSA,L]
RewriteRule ^([^/\.]+)/?$ index.php?page=$1 [NC,QSA,L]
But it does not work completely when I'm trying to work with it locally.
Imagine that I have a directory myproject in htdocs (www) in my local web server path and other files are stored in this folder. Now I can see the project if I go to localhost/project.
Now I want to work with URLs.
It works well if I have only one parameter in URI like localhost/myproject/tours. But if I have 2 parameters like localhost/myprojects/tours/inside, it seems that all css, js and images files go away. I've also added RewriteBase /myproject to .htaccess file, but nothing solved.
What is my mistake? I need a solution that works on both remote and local server.

First of all, see my response on your other question about your code: Why .htaccess mod_rewrite does not show a real directory
Now, RewriteBase won't solve your problem about css/js/images etc. It's only for htaccess and it defines the base path when a rule is rewritten.
One common way to avoid this problem is to add in all your files a base url right after <head> html tag.
For you, it would be: <base href="http://localhost/myproject/" />
Otherwise, if you reach localhost/myprojects/tours/inside then your css/js/images links will be resolved as localhost/myprojects/tours/inside/__here__ because the default base path here is the current directory (/myproject/tours/inside/) and this is not what you want
Edit: if that's the case, don't forget to remove leading slashes from your css/images/javascript html links

The browser will build absolute URL paths out of your relative URL paths by looking at your made up context of /myprojects/tours. You may need to strip one or two levels of that prefix off to find the real path.
The access log will show you plain as day what relative URL's come in when you use the old and new URLs.

Related

htaccess friendly URL rewrite rule

I have recently change my hosting and i need a htaccess rewrite rule for my files. I tried many examples but no one really works for my case. I have never been really good in htaccess and on my older hosting i didn't really need anything it just worked but here is not. Basically i want that my PHP files are without extensions and treated like a directory. So for example i have a URLs like these:
www.domain.com/file1/{id}/{nick}
So for example:
www.domain.com/myfile1/104/username
www.domain.com/myotherfile/455/nick
File1 in this case is a PHP file and {id} and {nick} are changable. I have this structure on my entire site for many other PHP files etc. So if possible i want one universal rule for all files. I tried with htaccess to remove php extenstion etc but all I got is 404 error. Also URL in browser should stay friendly without PHP extension. So in my case if i rewrite my URL manually in:
www.domain.com/file1.php/{id}/{nick} it worked but i don't want to change all the links etc on my website. So all i want is to hide PHP extension and treat PHP files as directory.
Thanks
You can use this single and generic front controller rule in site root .htaccess:
AcceptPathInfo On
DirectoryIndex index.php
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([\w-]+)/(.*)$ $1.php/$2 [L]

Subfolders in a REST API

Let’s say I have a structure like this https://domain.com/api/rest/v1.0/, but in the folder v1.0 I have subfolders like data-model and constants.
Now let’s say I’m using mod rewrite, so all URLs that have the base URL https://domain.com/api/rest/v1.0/ get forwarded to https://domain.com/api/rest/v1.0/index.php.
Would this affect my PHP files contained in https://domain.com/api/rest/v1.0/data-model/ and https://domain.com/api/rest/v1.0/constants/?
For example, if in https://domain.com/api/rest/v1.0/index.php I try to add a file from https://domain.com/api/rest/v1.0/constants/ using require_once, would that cause some kind of redirect loop?
I’m not getting any output after the lines of code where I do the above, but am before. Similarly I’m not getting any errors/reloading of the page in the browser so am at a bit of a loss.
If this is the issue, does anyone have any pointers to a better REST file structure than just lumping all the files in the root folder?
Thanks
UPDATE
Here is my rewrite rule:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule api/rest/v1.0/(.*)$ api/rest/v1.0/index.php?request=$1 [QSA,NC,L]
</IfModule>
No, neither your php files nor your directories are affected. mod_rewrite only rewrites URLs. That means that urls are only rewritten if accessed via http request (e.g. with a browser).
Probably your rewrite rules are wrong. Also check php log files for errors.
What are your rules like?
It turns out the solution was that my subdirectories weren’t properly added in require_once as my paths were relative. So instead of require_once 'folder/file.php' I changed my files so they now read require_once dirname(__FILE__) . '/folder/file.php'

Mod_rewrite website like facebook

I'm using mod_rewrite for the first time in order o create a website similar to facebook.
Whener I type mywebsite.com/user.name, the mod_rewrite redirects me to mywebsite.com/hotsite/index/php and there, I use a little php to get the user name from the url and get the userId from it.
Then I have the other areas like mywebsite.com/user.name/diary, mywebsite.com/user.name/contact, and so on...
This is all working well with this code in my .htaccess:
Options +FollowSymlinks
RewriteEngine on
RewriteBase /mywebsite
# ————————————————————————-
# > URL REWRITING
# ————————————————————————-
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(.*)/diario$ hotsite/diary.php
RewriteRule ^(.*)/recados$ hotsite/messages.php
RewriteRule ^(.*)/fotos$ hotsite/photos.php
RewriteRule ^(.*)/videos$ hotsite/videos.php
RewriteRule ^(.*)/contato$ hotsite/contact.php
RewriteRule ^([a-z0-9._\-]+)$ hotsite/index.php [L]
The problem I have is with the path to the external files (css, images, backgrounds...).
Since my browser thinks I am in "website.com" I had to add "hotsite/" to all the paths. This works well for when I am at the user main page, like "mywebsite.com/user.name". However, if I go to "mywebsite.com/user.name/diary" the browser thinks I'm in another folder and then I have to add "../hotsite" in order for the paths to work.
I could make an IF in all the paths to check if I am at the index or not, but this would be very clumsy.
I could also put absolute paths in evertyhing, but since I'm developing offline with apache, this wouldn't be good either.
Any other solutions?
Thank you vey much.
You should probably use the base tag available in HTML (put it between the <head></head> tags):
<base href="yoursiteroot" />
In other words, something like this:
<base href="/mywebsite" />
However, this requires that your relative links are adjusted based on the path you specify. :-)

PHP mod_rewire entire site, and rewriting image URLs?

I have pretty much developed an entire site and was foolish to not implement mod_rewrite. I wish to do so now, and did a test page. The mod_Rewrite works perfectly, but I then have the issue of all of the imaegs being linked to the new pages URL, for example:
www.mysite.com/county/Kent.html
from
www.mysite.com/sector.php?county=kent
It works great, but then when I am on the new link the URL for images changes to this.
mysite.com/county/images/widMot.png
As if the 'images' folder is in the 'county' folder which actually doesn;t exist. Is there a rewrite rule, which will ignore this image link change? Or something I am missing?
EDIT: As requested:
...
RewriteEngine On
RewriteRule ^county/([^/]*)\.html$ /sector.php?county=$1 [L]
...
EDIT: The solution the answer posted was excellent, and resolved the image issue, but I was then stuck with an issue of my css files being put after /images/ directory. Ofc a simple fix would be place them in there, but is there no other way?
Please take a look at the <base> HTML tag.
http://www.w3schools.com/tags/tag_base.asp
It allows you to define the base URL of your site, after that, any link built like /images/someimage.png will direct you to the root directory's images/.
EDIT:
To be more specific, all relative URLs starting with a forward slash / will begin immediately after domain name.
Try something like:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule YOUR REWRITE RULE
</IfModule>
Should pass everything to your rewrite rule, unless the requested URL is an actual file on the server.

mod_rewrite trouble

So I'm using a simple rewrite rule like:
RewriteEngine On
RewriteRule ^foo/?$ foo.php [NC,L]
It redirects perfectly to foo.php, but it seems like all links and images in foo.php are being taken from folder foo on the server which doesn't exist. For instance, 1.png will now be foo/1.png or index.html will now be foo/index.html. So my question is: is there any way to make thing right without changing paths to the files in foo.php?
Your visitors' browsers see the current page as being at /foo/, thus all relative URLs will be resolved under /foo/. You will need to set the base URL, or update all your relative URLs to point to your site root (e.g. do not use relative/path/url.jpg but /relative/path/url.jpg).
In your code you should provide a rewrite rule for your resources (images, css, etc...) or add conditions for real files / folders like...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
The two RewriteCond lines test to see if the requested URL points to an actual real directory (the !-d part), and the second one tests if it's a real file (!-f)
In the future, you can easily debug your mod_rewrite stuff by adding this two lines to your .htaccess file:
RewriteLogLevel 3
RewriteLog "/path/to/a/file.log"
2 simple ways
absolutize the references as suggest by Ianzz
remove the foo path for referenced object still using htaccess
RewriteRule ^foo(/.*.(jpg|html|gif|css))$ $1 [L]
I prefer the 2nd solution because the htaccess do the mess and htaccess fix the situation, and no changes to your code are needed.

Categories