View Full Version : .htaccess rewrite problem
fastsol1
06-30-2013, 04:17 PM
So I really don't know or understand much with htaccess. I am trying to do a simple url rewrite for a blog type thing. I want to take a url like amecms.com/view-article.php?article=whatever-whatever and make it show like amecms.com/article/whatever-whatever. I can get it to rewrite technically I guess but I think because of the added article/ in the url the page is not figuring out the directory correctly and isn't finding my css file and other files to include.
You can check out what I mean amecms.com/articles.php and choose a article. Here is the rewrite rule I have so far.
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^article/(.*)$ ./view-article.php?article=$1
Any help is appreciated.
fastsol1
06-30-2013, 04:37 PM
Oh how I love searching an trying for hours and finally posting for help and then 2 seconds later find a solution. I ended up using a <base> tag that tells files to use the path in the href of the tag for guidance. I set it to my main domain name and it all seems to work how I want.
<base href="http://www.example.com/" />
All other pages seem to work fine too. I don't honestly know if this is the correct or best way to make it work, so I am very interested in what other methods to try.
Using <base> can become problematic very easily. There's a good conversation here (http://stackoverflow.com/questions/1889076/is-it-recommended-to-use-the-base-html-tag).
I'm not saying you "shouldn't use it," or that it is a "bad thing" in general. Just make sure you know what it does, so you don't have any surprises. :)
Here's what I would recommend:
1. use RewriteBase in your htaccess. This does what you were probably trying to do, but only internally, when you're rewriting (no unexpected side effects).
2. get rid of the leading ./ in your RewriteRule. It doesn't make sense there.
3. test changes
RewriteEngine On
RewriteBase /
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^article/(.*)$ view-article.php?article=$1
fastsol1
06-30-2013, 06:06 PM
Ok, tried that and it does the same thing as before I put in the <base>. I tried some variations of it with a url instead of the / but that didn't work either. Any other tricks?
alright; I see now what your issue is. You're using relative URLs to load your scripts.
Yes, using <base> will fix that, though (as I mentioned) it may have other (unintended) side effects. But, if it works for your purpose, go ahead and use it.
A better (IMHO) solution would be to use root-relative URLs where appropriate. For example, when you do <script src="scripts/general.js"></script>, you're always expecting to get the same script, right? The one in the scripts/ directory, off your document root, ...right?
Problem is, that's not the URL you're asking for. You're asking for the scripts/ directory off of whatever directory you happen to be in at the moment. If your current URL is example.com/articles/some-article, you're asking for articles/scripts/general.js. If you're at example.com/how/did/i/get/here/im/so/confused/index.html, you're asking for /how/did/i/get/here/im/so/confused/scripts/general.js.
If you want the scripts/ directory off your document root, ask for it specifically: <script src="/scripts/general.js"></script>.
fastsol1
06-30-2013, 07:42 PM
Yeah after looking around I have found the / to be a better solution also. That too answers other questions I have had in my head. So I will have to take some time and change all the paths in the site. Thanks.
fastsol1
06-30-2013, 08:27 PM
So after playing a little, the / method is great for live sites but makes it not work on local host. I have apache setup to read in my D: and then I have each site in a different folder. Browsing to the folder works just like browsing to a hosted site online. in the url bar it says localhost/whatever/file.php as an example. So now using the / the paths are looking at localhost as the root rather than the folder I have the site in.
mm... different situations, different needs.
ever thought about creating local domains on virtual hosts (http://httpd.apache.org/docs/current/vhosts/index.html)? There's a "learning curve," but it would allow each of your local sites to have its own document root. It's also very nice having a local environment that more closely resembles the "real" internet.
fastsol1
07-01-2013, 12:32 AM
I have been looking at that for the last few hours and have tried many times to make it work but with no luck.
fastsol1
07-01-2013, 11:37 AM
Windows 7 and wamp
Beverleyh
07-01-2013, 01:50 PM
If you want to side-step .htaccess altogether, you *could* set a global path variable in a common file.
I do something similar to you (each website in a sub-folder) but in my main header.php file for each website ,I include a $myRoot variable - something like;
<?php $myRoot = 'http://localhost/mywebsite/'; ?>
And then prefix the paths in my HTML markup with the variable, like this (all of my website pages are .php so this works for me);
<script src="<?php echo $myRoot;?>scripts/general.js"></script>
The output will be: <script src="http://localhost/mywebsite/scripts/general.js"></script>
Then when you move your website to the live server, you only change your $myRoot variable in the common file and the change filters down to all the paths in your markup;
<?php $myRoot = 'http://www.mywebsite.com/'; ?>OR just;
<?php $myRoot = '/'; ?>so the output would be; <script src="http://www.mywebsite.com/scripts/general.js"></script> or <script src="/scripts/general.js"></script>
You wouldn't be able to do this in all cases but it *might* work for you.
fastsol1
07-01-2013, 04:22 PM
I have thought of your concept to Bev. Am I correct when saying that the / does not work as expected for php with include() and require(), I seem to get a fatal error when using it on a live site. Does php look from the root already or what?
Beverleyh
07-01-2013, 04:56 PM
Yes, if you use "/" in a php include() its trying to look from a place even deeper than the root of your wamp-dwelling website - ie. the root of your C drive instead.
But, you can create a variable for your php includes using the same idea though;
$myRootURL = 'http://localhost/mywebsite/';
$myRootPATH = 'C:\wamp\www\mywebsite\';
There are other ways to define a root but this is the one I use (old habits and all)
EDIT: some other ways to define a root path for php includes: http://stackoverflow.com/questions/344419/how-do-i-set-an-absolute-include-path-in-php
That's a great solution and totally workable/sufficient in many cases. I'd only suggest using constants instead of variables, so you can't accidentally modify/overwrite them (and they will always be available globally, regardless of scope):
<?php
define( 'ROOT_URL','/localhost/sites/example' );
define( 'ROOT_PATH','C:\wamp\www\sites\example' );
You could even do some switching logic so you wouldn't need to change them all manually when you uploaded to your server:
<?php
if( $_SERVER['SERVER_NAME'] === 'localhost' ){
require file/that/defines/local/constants.php;
}
else{
require file/that/defines/production/constants.php;
}
Beverleyh
07-01-2013, 07:06 PM
Nice - I'll have to remember that switcharoo logic traq :D
fastsol1
07-03-2013, 12:45 AM
Thanks for all the input. I have taken the time and converted my cms to use / on most links and image paths. It wasn't that terrible to do really. I made a few define() to help, although a couple of these I already had but mostly for localhost use. I have a few different versions so that I have options of when and where I need to use them depending on localhost or online and php includes or html links.
// Strips the SERVER HOST to main domain name
function stripHost()
{
if(substr($_SERVER['HTTP_HOST'], 0, 4) == "www.")
{$server = substr($_SERVER['HTTP_HOST'], 4);}
else {$server = $_SERVER['HTTP_HOST'];}
return $server;
}
define("SITE_SERVER", $site_server = stripHost());
define("CURRENT_DIR", (dirname($_SERVER['PHP_SELF']) == '/') ? '/' : dirname($_SERVER['PHP_SELF']).'/');
define("BASE_URL", (SITE_SERVER == 'localhost') ? 'http://'.SITE_SERVER.CURRENT_DIR : '/');
define("ROOT", dirname(dirname(__FILE__)).'/');
fastsol1
07-03-2013, 05:49 PM
I also just figured out how to setup virtual host on my localhost, so that's really cool!
Powered by vBulletin® Version 4.2.2 Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.