fix paths with pretty urls? - php

I am trying to use pretty links with my website, but i have a problem with paths of css and js files.
Thats what i wrote in .htaccess file
RewriteEngine on
RewriteRule ^register register.php [NC,L]
RewriteRule ^login login.php [NC,L]
RewriteRule ^settings settings.php [NC,L]
RewriteRule ^logout logout.php [NC,L]
RewriteRule ^profile/([0-9a-zA-Z]+)$ profile.php?u=$1 [NC,L]
The problem here appears when i try to access profile.php with the variable
example: http://example.com/xxxx/profile/ashraf
This here will consider profile as the main folder when importing style files which is not a folder, it's just profile.php
Thank you

I think you can add this before your rules
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Basically what this ( common on many CMS systems ) says, is if Not a real file !-f, or a real directory !-d then continue on. Therefore if the file actually exists, such as a css file, it will not pass the condition and will not be re-written.
So I would say put it right here
RewriteEngine on
## insert here ##
RewriteRule ^register register.php [NC,L]
You may have to place it before each rule, that I am not that sure of, as I haven't done a whole lot with .htaccess in like 5 years. Basically when I learned how to use the URI instead of a URL and route everything through a index.php and a router script.
This is the extent of my .htaccess files these days ( just FYI for my explanation of my lack of remembering ) and it literally never changes. That's one of the biggest benefits of building a router and using the URI
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
This answer I did has a pretty good ( if I say so ) explanation of how what I call the URI method works.
How to change the name of the directory in url in php using htaccess?
Here is another answer I did on this topic that outlines how to build a basic router
Oop php front controller issue
Anyway hope that helps.

The browser cannot know if the paths in the URL are real directories or just parts used in rewrite rules. When it sends a request to the web server to get the CSS, the browser must convert it any relative urls to absolute and assumes the current page is in a path of directories.
In other words, in your HTML page, always use absolute urls: <link href="/xxxx/style/mycss.css" ...>

Put this after the profile.php rule. This will take out the extra 'profile'.
RewriteRule ^profile/(.*)$ $1 [L]
Or use a long path to the css file:
<link href="/xxxx/style/style.css" rel="stylesheet">
Either one should work.

Related

.htaccess is reloading some files twice

My website is a custom made PHP website. I recently made it SEO friendly by copying the .htaccess file from wordpress and modify it a little. The problem is that some pages are realoaded twice especialy pages that have more than 1 backslash like download/something/ . I have noticed this when tracking pageviews one pageviews is counted as twice and i've done a lot of research regarding this and the pageviews are working good it's a very simple function that inserts a new row each time you view a page.
Things to keep in mind:
My website is inside some folders 'https://localhost/simbyone/sim/index.php'.
I don't want to use any GET variables i will have my variables from the URL string
I want .htaccess to look for existing directories located inside 'https://localhost/simbyone/sim/' and if it doesn't find any open index.php with all the strings attached something like 'localhost/simbyone/sim/blabla/' but inside index.php
everything works exactly as i said above the only thing that doesn't do right is that it double loads some pages
this is my .htaccess file:
RewriteEngine On
RewriteBase /simbyone/sim/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /simbyone/sim/index.php [L]
Thanks in advance to anyone that will help me.
Place the .htaccess inside your base folder (in your case, simbyone/sim).
Just put this in the file:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php
This will rewrite and request that is not an existing file or folder to the index.php file.
There you can use $_SERVER['REQUEST_URI'] to evalute the request (keep in mind that the prefix "/simbyone/sim/" will be present there.

htaccess Redirect Causes Errors

I'm working on a website that has been built sloppily.
The website is filled with regular links that are translated into the corresponding .php pages by the .htaccess page.
This is it:
RewriteEngine on
RewriteRule ^koral/(.*)/$ page.php?name=$1
RewriteRule ^koral/(.*)$ page.php?name=$1
RewriteRule ^(.*).html/(.*)/(.*)/(.*)$ cat.php?cat=$1&page=$2&order=$3&dir=$4
RewriteRule ^(.*).html$ cat.php?cat=$1
RewriteRule ^(.*)/(.*).html$ product.php?cat=$1&product=$2
<IfModule mod_security.c>
SecFilterEngine Off
</IfModule>
First of all, I would love some help regarding whether or not this page has everything it should. I've never messed with it before.
Secondly and my main issue, if, for example, I would write the address www.thewebsite.com/foobar.html, it would be translated into www.thewebsite.com/cat.php?cat=foobar by the .htaccess page, and it would give a database error (and reveal information about the database).
I've put a check into cat.php which checks if the category exists, but I can't redirect the user to the 404 error page. There's a page called 404.shtml in the website, but redirecting the user to it causes the .htaccess to just change it again to cat.php?cat=404.
Is the way they used the .htaccess page normal? Should I change this system?
And how are users sent to error pages? From what I understood the server should be doing it on its own?
I would love some clarification... There is some much about this subject I don't understand.
Update:
This is my new .htaccess page
RewriteEngine on
RewriteRule ^error.php?err=(.*)$ Error$1.html
# Only apply this rule if we're not requesting a file...
RewriteCond %{REQUEST_FILENAME} !-f [NC]
# ...and if we're not requesting a directory.
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^koral/(.*)/$ page.php?name=$1
RewriteRule ^koral/(.*)$ page.php?name=$1
RewriteRule ^(.*).html/(.*)/(.*)/(.*)$ cat.php?cat=$1&page=$2&order=$3&dir=$4
RewriteRule ^(.*).html$ cat.php?cat=$1
RewriteRule ^(.*)/(.*).html$ product.php?cat=$1&product=$2
<IfModule mod_security.c>
SecFilterEngine Off
</IfModule>
Because the redirecting is in the code and the user cannot see it, I allowed myself to write the link in a non-clean way. I tried turning it into a clean URL but the following does not do anything:
RewriteRule ^error.php?err=(.*)$ Error$1.html
Can someone please help me understand why? I thought since error.php is a real page, I should put it before the conditional but it didn't work. BTW, I saw in an article about .htaccess that the page should start with Options +FollowSymLinks. It seems to me that everyone sort of has their own way of writing it. Is there a guide or something like that, which I can be sure is authentic and covers all the bases there is about .htaccess?
Thank you so much!!
Using rewrite rules to work around links to .html pages that don't exist is unusual in my experience, but it's really just a different take on "pretty" URLs, e.g. www.thewebsite.com/foobar/ gets routed to cat.php?cat=foobar on the backend.
Your 404 issue is different. You need to be able to display error pages.
One option here is to rewrite requests as long as they don't request an existing file. This is very common for serving up static content like images, CSS files, and the like. To do this, you can use the -d and -f options to RewriteCond, which apply when requesting a directory and file respectively:
RewriteEngine On
# Only apply this rule if we're not requesting a file...
RewriteCond %{REQUEST_FILENAME} !-f [NC]
# ...and if we're not requesting a directory.
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^([^.]+)\.html$ cat.php?cat=$1 [L,QSA]
Now, requests to 404.shtml should go through, because you're requesting an existing file on the filesystem.
Note that the RewriteConds only apply to the single RewriteRule that immediately follows. For additional RewriteRules, also include additional RewriteConds.
Your regex is wrong anywhere. Literal dot needs to be escaped using otherwise it will match any character. Also it is better to use L and QSA flags to end each rule properly.
RewriteEngine on
RewriteBase /
RewriteRule ^koral/([^/]+)/?$ page.php?name=$1 [L,QSA]
RewriteRule ^([^.]+)\.html/([^/]+)/([^/]+)/([^/]*)/?$ cat.php?cat=$1&page=$2&order=$3&dir=$4 [L,QSA]
RewriteRule ^([^.]+)\.html$ cat.php?cat=$1 [L,QSA]
RewriteRule ^([^/]+)/([^.]+)\.html$ product.php?cat=$1&product=$2 [L,QSA]

Bug with mod_rewrite and PHP?

I've run into a bug and I'm not sure of its source. I use mod_rewrite for the following:
RewriteRule ^stuff$ index.php?page=stuff [L]
and it works just fine, but when I use
RewriteRule ^(.+?)$ index.php?page=$1 [L]
CSS is no longer applied to the page and the code doesn't seem to read GET requests.
Can someone elaborate on why this happens for me?
Add a rewrite condition to not rewite if the file is present & use the QSA flag to allow appended parameters:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?page=$1 [L,QSA]
Since your query strings have been converted into a directory-like structure, apache will check the directory if you are not using any path disclosure.
So if you're include the css file like so:
<link href="skins/style.css">
You'll need to disclose the full webpath to the file:
<link href="http://site.com/skins/style.css">`
Also, for all images in your css file you need to do the same, include the full webpath to avoid and issues when rewritting in the future.

.htacces css/js subdirectory issue

I am trying to make some changes to .htaccess file of a site. I have searched all over the web, but I cant find a clear solution for that, or there is possibility that I have got it wrong. So here we are are:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^/$ /e/www/ [R]
RewriteRule ^news$ /news.php
RewriteRule ^news$ /news.php
RewriteRule ^resources$ /resources.php
RewriteRule ^lexicon$ /lexicon.php
RewriteRule ^contacts$ /contacts.php
RewriteRule ^analytics$ /analytics.php
RewriteRule ^([0-9]+)-([0-9]+)-([0-9]+)-(.*)$ /news.php?yy=$1&mm=$2&dd=$3&alias=$4
RewriteRule ^resources$ /contacts.php
RewriteRule ^articles_search$ /articles_search.php
RewriteRule ^articles_data_search$ /articles_data_search.php
RewriteRule ^profile/([0-9]+)&commit=(.*)$ /profile.php?id=$1&commit=$2
RewriteRule ^profile/(.*)&commit=(.*)$ /profile.php?alias=$1&commit=$2
At last 2 rows, i am trying to have a result from this:
www.example.com/profile.php?alias=kokazani&commit=Edit
to this:
www.example.com/profile/kokazani&commit=Edit
The problem now is the wrong path of css and js files. I need a solution, or a better approach of rewriting rules. I think that a solution ,maybe, is to rewrite everything like css/blabla.css to root directory/css/blabla.css, but if there a standard-solution foro this problem, i would like to know :)
Thanks in advance.
There are 2 possible (simple) solutions:
Use absolute paths for your CSS files (/include/css/style.css etc)
Use HTML's <base> element to set the correct base URL for relative URLs to follow (rather then the directory of the document which is altered by Apache).
My approach would be (as suggested by Truth) using absolute paths. If this is not possible, you could use:
RewriteRule ^(.+)/css/(.*)$ /css/$2
But be warned: This means the client (browser) will end up getting and caching multiple copies of the same file because it is fetching it (as far as it can see) from different paths. Therefore you lose the advantage of client-side stylesheet caching.

Url rewriting broke link to css

I'm using the following setting for url rewriting:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
In index.php is parse $_GET['url'] so that in the following examples:
ROOT/user/id/1/name/bobby // user is the page, id = 1, name = bobby
ROOT/blog/post/123/title/welcome // blog is the page, post = 123, title = welcome
So that the first parameter(? i don't know how to call it) is the page name then the following couple of parameters are like "keys/value".
Now when i browse ROOT/ the link to stylesheets that are inserted inside the html of the page and the page are shown correctly.
I fi browse ROOT/index (which is the same as ROOT/) it shows the page (with contents and other stuff) correctly but the links (even if in the html structure are correctly written) to stylesheets are not loaded. And i can see that from the fact that my page has no css at all when i load it.
How can I fix this?
EDIT
The css file's path is as follows:
project/view/css/common.css
The file where is it included is in
project/public/index.php // the one with .htaccess and rewrite rules
This brings me to make a link (inside the index.php) such as
../view/css/common.css
But this works different depending on how the url seems. For examples:
# For URL = public/
project/view/css/common.css // good
# For URL = public/index/
project/public/view/css/common.css // broken
# For URL = public/index/key/value
project/public/index/key/view/css/common.css // broken
Comment doesn't let me format the code, can you please try this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^.*\.(css|jpe?g|gif|png|js|ico)$ [NC]
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
Update
You can try something like this in the <head> section of your pages to support relative path for your image/css/js files referenced on that page:
<head>
<base href="http://www.example.com/static-files/" />
</head>
I think you have two problems (as the given answers didnĀ“t solve your problem yet...):
You are rewriting all file-names so when the browser is requesting css/index.css your rewrite transforms that to index.php?url=css/index.css. #cOle2's answer should solve that.
You are not using absolute paths for your css files. The server is translating the requested page like /user/id/1/name/bobby to /index.php?etc.... but when the browser requests for example the css file that is something like css/index.css in your code, it will actually request /user/id/1/name/bobby/css/index.css and that file does not exist. You can solve that by using only absolute paths to your external files (css, js, images, etc.) like /css/index.css.
Edit: Based on your comments, both your paths are relative and your css is not accessible by the browser, so you need to:
Move the css to the project/public directory (like project/public/css)
Use absolute paths to your css like /css/index.css.
Make sure the urls to your external files are not rewritten by the server.
You can try removing certain file extensions from the rewrite rule, for example the following rule will disregard images, css and js files.
# Do not process images or CSS files further
RewriteRule \.(css|jpe?g|gif|png|js|ico)$ - [L]
Edit: This is how I would apply it:
RewriteEngine On
RewriteRule \.(css|jpe?g|gif|png|js|ico)$ - [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

Categories