URL rewrite in htaccess results is missing CSS and images - php

I need to remove a specific thing from my URL. Here I give a page name user.php and get it using $_GET['url'] then make it array using PHP explode() method.
https://www.example.com/index.php?url=user
I need to remove the index.php?url= like this,
https://www.example.com/user
Now I already use this code in .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule index.php?url=$1 [QSA, L]
Almost everything was fine the user.php page was loaded perfectly. But when I was given a slash to my URL it stops showing CSS or other IMG directories. But when I delete the .htaccess file it works fine in this URL:
https://www.example.com/index.php?url=user/anonymous
But not works in this URL when I assign the .htaccess rules.
https://www.example.com/user/anonymous
Why my all stylesheet and other directory is not working perfectly?

RewriteRule index.php?url=$1 [QSA, L]
I think you have a couple of glaring typos(?) in your question that make this directive completely invalid... you are missing a RewriteRule pattern, so this won't actually match anything and the erroneous space in the flags argument is syntactically invalid, resulting in a 500 Internal Server Error response?!
The RewriteRule directive should be written like:
RewriteRule ^([\w/-]+)$ index.php?url=$1 [QSA,L]
^([\w/-]+)$ matches a URL-path containing any of the characters: a-z, A-Z, 0-9, _ (underscore), / (slash) and - (hyphen). I've excluded the dot, which is naturally part of real filenames.
You should also ensure that MultiViews is disabled, so that mod_negotiation doesn't rewrite the request before mod_rwrite - since your "extensionless" requests appear to map directly to filenames. eg. /user maps to /user.php. Place the following at the top of your .htaccess file:
Options -MultiViews
But when I was given a slash to my URL it stops showing CSS or other IMG directories.
This isn't a problem with .htaccess, but is caused by using relative client-side URLs to your static resources. When you request the URL /user/anonymous then the browser will resolve any relative URLs relative to /user/anonymous (not the document root - which is probably what you are expecting). If you have a relative URL to css/styles.css then the browser is naturally going to resolve this to /user/css/styles.css - which probably doesn't exist (and is likely getting rewritten to index.php - but that isn't the issue - the fact that it doesn't exist is the issue).
If you look at the network traffic (HTTP requests) in the browser, it should give you a clue as to what's going on.
You need to change your client-side URLs to use either root-relative (starting with a slash) or absolute (scheme + hostname) URLs to fix this issue.
See my answer to the following question on the Webmasters stack that explains this further:
https://webmasters.stackexchange.com/questions/86450/htaccess-rewrite-url-leads-to-missing-css

Use following code in your .htaccess file
RewriteEngine On
#main user page
RewriteRule ^user$ index.php?url=user [L]
#user detail page
RewriteRule ^user/([^/]*)$ index.php?url=$1 [L]

Related

Is there a way to change a php URL with htaccess?

I am trying to change:
example.com/profile.php?id=abcdefgh
To simply:
example.com/abcdefgh
I searched here on StackOverflow and I understood that I need to do something with my .htaccess, I tried this code:
RewriteEngine On
RewriteRule ^([^/]*)$ /profile.php?id=$1 [L]
But it seems nothing changes, when type this URL (example.com/profile.php?id=abcdefgh) it doesn't get rewritten.
P.S. I don't know if the above code is right, i tried it because where I got it from had a similar problem to mine.
This should work.
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ profile.php?id=$1 [QSA,L]
You should be requesting the "pretty" URL, ie. /abcdefgh. Your mod_rewrite directive in .htaccess then internally rewrites this to the "real" URL that actually handles the request (ie. /profile.php?id=$1). That directive is expecting a URL of the form /abcdefgh. However, in its current state I should expect a rewrite loop:
Request /abcdefgh
Request is rewritten to /profile.php?id=abcdefgh.
Processing starts over...
Request is rewritten to /profile.php?id=profile.php (because the regex ^([^/]*)$ matches the profile.php part of the rewritten URL.
GOTO #3
In this example you can avoid the rewrite loop by simply making the RewriteRule pattern (regex) more restrictive. eg. Include a dot (.) in the negated character class (assuming your new "pretty" URLs do not contain a dot).
For example:
RewriteRule ^([^/.]+)$ /profile.php?id=$1 [L]
You then need to actually change the URLs on your website to the new "pretty" URLs.
However, if you are currently getting a 404 then maybe this directive isn't being processed at all? Are .htaccess files enabled? Do you have other directives in your .htaccess file?
UPDATE: in the id the only characters allowed are A-Z
In that case you should be more specific with the regex and match just the characters required. This helps to avoid conflicts and avoids the need for filesystem checks (to some extent) - which are relatively "expensive". Note, however, that you've stated "A-Z" but your example includes lowercase letters. For the sake of argument I'll assume the id can include a-z and A-Z.
So, this now becomes:
RewriteRule ^([a-z]+)$ /profile.php?id=$1 [NC,L]
No other filesystem checks (preceding RewriteCond directives) are necessary. The NC (nocase) makes the regex match case-insensitive.
There is no need to check that the request does not map to a file (with a preceding condition), since the regex ^([a-z]+)$ could never match a file (that includes a file extension).
There is also no need to check that the request does not map to a directory, unless you are requesting directories in the document root directly - which is probably "unlikely". However, therein lies an inherent conflict with this URL structure. If you needed to be able to access a directory then those directory names become invalid IDs - so you would need other checks elsewhere in your system to ensure no IDs were generated that map to physical directories in the document root.

Network Solutions hosting URL looks weird for Apache server

I was trying to prettify URLs for dynamically generated pages on my website, so that when a user visited the virtual URL topicview/interesting-user-friendly-text he would really be seeing, under the hood, topicview.php?topicid=123
I added the necessary code to my .htaccess file to replace the topicview/interesting-text part of the URL with topicview.php?topicname=interesting-test, but the Regex kept misfiring.
So, I changed the Regex to return the entire URL so I could see why it wasn't working with this code:
#Allow for topicview/topic-name URLs
RewriteRule (.+)$ topicview.php?topicname=$1 [L]
I then visited topicview/user-friendly-text. I'm not sure if this is unique to Network Solutions hosting, however, when I examined the topicname GET paramter, I got this string in return:
data/1/2/323/232/823238/user/999999/htdocs/topicview.php
This URL was not displayed in the topicname GET parameter, just a regular file, like index.php or topicview.php, if I just visit the URL index.php or topicview.php
Why is the URL internally represented like this to the Apache server, and how can I rewrite my mod_rewrite code to get a more user friendly virtual URL for the topicview.php?topicid=1 pages?
thanks
For the friendly URL try this in your .htaccess file
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?topicview/([^/.*]+)/?$ topicview.php?topicname=$1 [L,QSA]
The pattern matched in a RewriteRule is normally the similar to the REQUEST_URI but the behaviour you describe suggests it is matching against the REQUEST_FILENAME or something similar which is the file path including the full document root.
This would suggest your RewriteRule is not in your .htaccess file but instead in your or rules in the Apache config files, correct?
Instead you should try getting the value you want using a RewriteCond so you can guarantee you are matching against the REQUEST_URI, for example:
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteRule . topicview.php?topicname=%1 [L]
Note the %1 rather than $1 which allows you to use values captured in the RewriteCond.

Apache mod_rewrite module issue

I have the following code in my .htaccess.
RewriteEngine On
RewriteRule ^/(\w+)/?$ /?user=$1
I'm trying to rewrite
http://domain.com/?user=username into http://domain.com/username. Unfortunately this code doesn't rewrite anything. Please help
Note:
I checked phpinfo() and mod_rewrite is loaded.
Update
I need to get username from url like http://facebook.com/username. But this code rewrites every folder in root folder, so my /css folder become http://domain.com/css/?u=common. How to allow this code works only for http://domain.com/index.php
The mistake you are doing is the use of / in the beginning of the line ^/(\w+)/?$
rewrite rules strips off the / from the beginning of the pattern to be matched in .htaccess and directory context.
Try doing this:
RewriteEngine On
RewriteRule ^(\w+)/?$ /?user=$1
From RewriteRule Directive docs :
What is matched?
In VirtualHost context, The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string (e.g. "/app1/index.html").
In Directory and htaccess context, the Pattern will initially be matched against the filesystem path, after removing the prefix that lead the server to the current RewriteRule (e.g. "app1/index.html" or "index.html" depending on where the directives are defined).
If you wish to match against the hostname, port, or query string, use a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or %{QUERY_STRING} variables respectively.
Edit: Answer updated as per OP's request:
Add this :
RewriteEngine On
#do nothig if URL is trying to access the folder CSS.
RewriteRule *css/* - [L]
#checks where the URL is a valid file/folder.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(\w+)/?$ /?user=$1
I think that you are doing it the right way round, but explained it the wrong way round!
Is the problem that you don't need the initial / as the URL passed to test doesn't include it!?
I suspect it should be RewriteRule ^(\w+)/?$ /?u=$1
Also, be careful you don't end up with a loop!

add trailing slash to my urls

I have a serious problem since two days trying to rewrite the urls of my php website with htaccess.
Options +FollowSymlinks
RewriteEngine On
RewriteRule devis demande-devis.php
RewriteRule mentions-legales mentions-legales.php
RewriteRule condition-utilisation condition-utilisation.php
RewriteRule condition-generales-ventes condition-generales-ventes.php
RewriteRule fournisseur fournisseur.php
RewriteRule qui-sommes-nous qui-sommes-nous.php
RewriteRule faq faq.php
RewriteRule services services.php
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !example.php
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [L,R=301]
But what I expect for example, is to have http://www.example.com/services/ .
With the code, when I type that URL into the browsers address bar, I have a web page without CSS.
Most likely the problem is relative versus absolute notation of the css file urls.
Consult the http servers error log to see what is actually referenced or check the delivered html source of the page that lacks the style definitions.
The page you specify in your comment to the question shows both, relative and absolute references of css files. However you have no rewriting rules for those...
That works as usual. Just ensure you set the right link to your CSS files so that the browser is able to request them without 404's from your server.
As you have probably edited the URLs within the .htaccess files after you've written the php script, you need to reflect these changes in your PHP script, too, by updting the links in there, too.
Monitor your server error log to find out which URIs are wrongly send.
Review those.
Then improve the output of your application by fixing that erroneous output.
Please see as well:
do-it-yourself universal header/footer.php
and similar questions that are about the root of your problem.

URL Rewrite rule in .htaccess for Root directory

I am using this rule to rewrite the link
RewriteEngine On
RewriteRule ^(.*)/(.*) show_cv.php?email=$1
It is working fine like if I write this url with last slash
www.mysite.com/letschat_2008#yahoo.com/ ----> index.php?email=letschat_2008#yahoo.com
But when I remove the last slash from the link www.mysite.com/letschat_2008#yahoo.com/ it shows error 404.
I wish the URL Rewrite rule would work for both with slash and without slash (/)
www.mysite.com/letschat_2008#yahoo.com/ ----> index.php?email=letschat_2008#yahoo.com
www.mysite.com/letschat_2008#yahoo.com ----> index.php?email=letschat_2008#yahoo.com
Your rules are looping, you need to make sure you are rewriting an email address, and add some conditions so that the rule doesn't get applied if it's accessing an existing resource:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9_\-\#\.]+)/?$ /show_cv.php?email=$1 [L]
You should then be using the following rule:
RewriteRule ^(.*)/? show_cv.php?email=$1
I assume you note these rules in a .htaccess file, not in the server configuration when looking at your description ?
Rethink if you don-t want to put this into the server configuration. Apart from the usage of .htaccess files being harder to debug using rewrite rules in those files is more complex than in the server configuration. This is documented in mod_rewrites docs.
The reason for the behaviour is the different content of REQUEST_URI in both cases. Have a try checking this directly and you will see the problem. The whole part "letschat_2008#yahoo.com" is simply missing in that variable in case 2 (no "/"). To get this working you must use an additional rewriteCondition (also documented...). Something like these untested lines:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/(.+)&
RewriteRule - show_cv.php?email=%1
(note the '%' instead of a '$' in the last line)

Categories