mod_rewrite changes the current dir - php

I have a php file that loads an article from a db based on the given variables. There is also an .htacces file in the root of the site. I used this in the htaccess to redirect
RewriteRule
^articles/([a-zA-Z0-9-_\s]+).html$
template/index.php?action=viewarticle&alias=$1
after redirecting, the page shows fine but the html in the page goes wrong, for example:
media/2011/02/21/logos.jpg turns in to articles/media/2011/02/21/logos.jpg
This happens because the htacces is redirecting. Is there anyway to do this redirect while keeping the root dir unchanged?

This happens coz the htacces is redirecting.
No, this happens because the browser thinks that
example.com/articles/my_article.html
is a resource in the /articles sub-directory, and treats all relative URLs as relative to /articles.
There is no way to change that behaviour.
You will need to start using absolute image references, or relative image references that consider the additional directory:
<img src="/media/2011/02/21/logos.jpg"> <------ recommended
<img src="../media/2011/02/21/logos.jpg">
you could also use <base> as suggested by #Boris but absolute paths (or full URLs) are a vastly cleaner solution to the problem in my opinion.

First, what do you mean by "html in the pages goes wrong":
Is it the link showed in the status bar?
Is it the actual href? If it is, you probably use some view helper which construct your "base url"
Maybe you "link" your resource without specifing an absolute path (using /), then your resource are "relatively" linked to current page (/articles/)
.htaccess don't change anything in your code.
There is an html element which allow you to define base url used everywhere in your page.
<base href="/root" />
if you have for example Article 12 then when clicking on the link, you will redirect to /root/articles/12

Also, mixing Pekka's answer with Boris', you should define somewhere in your application which is the root path of your application and output all paths as absolute, prepending the base dir you defined earlier.
for example: in config.inc.php
define("ROOT_URI", "http://myserver.com/myapp");
everywhere:
<img src="<?php echo ROOT_URI;?>/media/2011/02/21/logos.jpg
This is like using the base element as Boris suggested, without using it (I also dislike base), and makes your application able to work in whatever folder under the webserver it is stored.

Related

How to use "relative" URLs?

i have a doubt, in an HTML file I have the following structure:
MAIN -> index.php
-> IMAGES -> image.jpg
In an 'img' tag should I use this:
<img src="IMAGES/image.jpg">
Or this?
<img src="/IMAGES/image.jpg">
Note that in the second example I added the slash before IMAGES. This is my question.
Both work in that case, but I suggest to use your first option (relative path), so if in the future you move your entire project under a new root dir, all your site will continue working.
In this case, they're exactly the same, but consider this updated example:
MAIN -> index.php
-> ABOUT -> index.php
-> IMAGES -> image.jpg
Now, inside ABOUT/index.php there is a difference, because
<img src="IMAGES/image.jpg"> # => /ABOUT/IMAGES/image.jpg
<img src="/IMAGES/image.jpg"> # => /IMAGES/image.jpg
Both would work but if you don't expect to ever move your IMAGES directory, go with /IMAGES/image.jpg. This would be preferable because you'll be able to use that same uri anywhere in your markup (say, if you add MAIN/SCRIPTS/newscript.php, then /IMAGES.. will work, IMAGES/image.jpg would not). If, however, you always intend to store IMAGES as a directory at the same level as index.php, but you might end up moving index.php somewhere else, then you might consider using IMAGES/image.jpg.
The "safety" of using relative URLs depends on if you will be using subdirectories in your URLs.
Assuming your file structure,
If you are at http://example.com/index.php, then the url IMAGES/image01.jpg will work.
If you are at http://example.com/somedir/index.php, then "IMAGES/image01.jpg will not load (It will be looking for http://example.com/somedir/IMAGES/image01.jpg instead of your intended http://example.com/IMAGES/image01.jpg)
This means that using relative URLs is "dangerous" if you:
1) Move or copy your index.php file into a subdirectory
2) Use url rewriting to remove index.php from your URLs (and so hae URLs like example.com/some/location rewrite to example.com/index.php?l=some/location)
Your safest bet is to use a variable to get your base URL:
define('BASE_URL', 'http://example.com');
Then later in your HTML:
<img src="<?php echo BASE_URL; ?>/IMAGES/image01.jpg" alt="" />
If you move your site in the future, you can change the BASE_URL constant.
Both should work, but I'd suggest using the slash. When you add the slash before hand, it means to look in the top most directory. With out it it means relative to the current file.
If you use the method with the slash before hand it allows you to move the file, or copy html to other files and it won't matter where they are.
On a side note, without the slash is called a relative path, and with the slash is called and absolute path.

wordpress image path changing dependent on file

I'm having problems with the paths to my first wordpress theme. Post images and stuff not related to css is located in wordpress_folder/blog-images/ and in index.php when I link to images I use this path: blog-images/img.jpg
The problem is now that when I want to link to the same image from another file (not index.php) in this case single.php wich displays one blog post, the correct path is now ../../../blog-images/img.jpg
This is causing problems in the includes like sidebar etc. sidebar.php works fine when called from index.php but the images path is changed if sidebar.php is called from single.php.
Does anyone know what's going on?
If you are creating these links from within php scripts, I would suggest using the site_url() function to get the URL for your wordpress install and then appending your images path to the end of that. If you are editing static theme files like css, then you should use /wordpress_folder/blog_images/img.jpg.
Something like <img src="<?php echo site_url() ?>/blog_images/img.jpg" /> should be sufficient from theme files.
The reason that paths are chaning is because if you are in wordpress_folder then the path blog_images/img.jpg resolves to wordpress_folder/blog_images/img.jpg but if you are on a post that has the url yoursite.com/wordpress_folder/2011/09/category/my_great_post then the path would resolve to wordpress_folder/2011/09/category/blog_images/img.jpg which is obviously incorrect.
For this reason you should try to use the absolute path or full URL so that no matter what file/folder/url you are linking from, the path will always be correct.
The main downside you may run into is that if you were to change the name of your wordpress folder, or remove it altogether, then you may need to make a lot of edits to reflect that. But in any case, you should put the / in front of your path so that it can be referenced the same from everywhere.
Also check out the site_url() reference page, it lists some other helpful functions at the bottom that may be useful to you.
I thought this was a little unclear from drew's answer, so I am adding a little bit more in a separate answer. His advice is sound and I agree with him.
If you prepend a url with a / then it will navigate based on your site url. Without the slash it uses relative navigation.
So here are some examples for www.mydomain.com
//always shows the image located at http://www.mydomain.com/myfolder/pic.png
//no matter what the url is
<img src="/myfolder/pic.png" />
//shows the image located relative to the current path
//if current url is http://www.mydomain.com/posts/ then the image will come from
//http://www.mydomain.com/posts/myfolder/pic.png
<img src="myfolder/pic.png" />
If you are creating links dynamically from php side then you will want to use site_url().
If you are creating links to your theme directory folder then you will want to use bloginfo('template_directory')

.htaccess redirect subdirectory as query string in php

This is hard to explain, so hopefully I'm understood in my question.
(1) I want to create "SEO friendly" links that remove the query string from a web site. There is only one variable, let's call it "page". Here is the following code for my .htaccess file.
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(.*)$ index.php?page=$1
This works in providing the proper redirect. So /applications/ will send to index.php?page=applications.
(2) My index.php will include a view page based on the value of $_GET['page']. Here is some sample code below:
switch ($_REQUEST['page']) {
default:
include ("home.php");
break;
case "apps":
include ("apps.php");
break;
}
There seems to be no problems so far.
(3) Let's make apps.php an exact copy of home.php. home.php loads just fine, but apps.php will not load linked CSS and JScript pages. When apps.php is loaded, it thinks it is in the /apps/ directory. To load the linked pages, I would need to insert a "../" in front of the file name. Then it displays correctly.
So my question is -- How can I properly write the .htaccess file so the home.php and apps.php page can be identical files and produce identical results, instead of the apps.php file being treated as if it were in the /apps/ directory?
First, I should apologize as I don't have a solution which involves making changes in the htaccess. My solutions are of a different nature.
I think the problem can be solved if you have a config variable,preferably in a config file, which will hold the root folder for images, js etc. Most of the time its public_html, the document root, where the url of your website points to. so your config variable could look like:
$base_url = 'http://www.mywebsite.com/';
The config file should be included in index.php unconditionally.
So, when you include any js or images, you do it like this:
<script type="text/javascript" src="<?php echo $base_url;?>js/global.js" />
<img src="<?php echo $base_url;?>images/gradient_green.jpg" />
If you include the config file in index.php, all the files you include based on switch-case conditions, will be able to use the $base_url variable.
Another possible solution is to use the base tag. Look it up here:
http://www.w3schools.com/TAGS/tag_base.asp
I hope this helps.
use absolute urls for js, css and images on your pages (starting with a slash).
/js/main.js instead of js/main.js
You can't do that with .htaccess unless you do an external redirect (by adding the [R] flag to your RewriteRule). But then you expose the query string, which is what you wanted to avoid in the first place.
The reason it can't be done: It is not apps.php which "thinks it is in the /apps/ directory" - it's the browser which "thinks" that. In the page source generated by apps.php, you send relative URLs back to the browser, and now the browser will request these resources relative to the location of the page it asked for. For the browser, the page it got is in /apps/, no matter what rewriting you applied internally on the server side.
So the options you have are:
Do an external redirect with your .htaccess (and defeat your original purpose ;-)
Change the URLs dynamically with PHP while processing apps.php etc, as you said (prefixing ../ to the URLs)
Use absolute URLs, just as #nobody has suggested in his answer.
The last one is the only real option IMHO.

Best practices with multiple directories in HTML

I haven't found a clear answer to this question (but have determined the HTML tag is more trouble than it's worth.)
When you're working with multiple directories on a website, how do you make sure relative links to the rest of your site work as you change your current directory? I don't want my link to "/index.php" to actually link to "/support/index.php" when I go to the support directory.
We're using PHP, so I could use output buffering to change links, but I want to see if others have any good ideas. Could also implement it through Smarty in one way or another. I haven't built a website from scratch that has used multiple directories simply because I don't know of an easy way to deal with this, but the problem shouldn't be too difficult.
(Running on IIS, but obviously it would be better to let it work on any server.)
you could declare a base_url variable, or declare a constant containing your base url
e.g.
DEFINE('BASE_URL', 'http://example.com/');
when using links
e.g.
Home
You already have everything you need
how do you make sure relative links to the rest of your site work as you change your current directory?
we're using absolute links for that
I don't want my link to "/index.php" to actually link to "/support/index.php" when I go to the support directory.
Lucky you, it will never happen
/index.php is absolute path and will never point anywhere beside /index.php.
/ is not just for decoration. It the meaning of slash at the beginning of the path is "root directory". So, /index.php means index.php placed in the root directory.
/support/index.php means index.php placed in the support directory which is placed in the root
easy-peasy. just always use absolute path (not URL which is senseless)
I store a “base” URI in two locations: (i) on the PHP/Zend Framework server, my configuration.xml file holds conventional values such as URIs; (ii) on the client side a more shallow, hidden <form/> holds other (less security compromising) values such as a base URI.
The form, by the way, looks something like this:
<form id="AppSettings" action="#">
<input type="hidden" id="MyBaseUri" value="http://superuser.com"/>
</form>
Add <base href="http://www.domain.com/"> to your <head> tag. This will make all relative links start from the directory given as href. Then use relative links like support/index.php not beginning with/ (i.e. not /support/index.php)
Note: Make the <base> tag the first tag in your <head> section, as all links after that will be interpreted from that base dir. (e.g. <link href="relative/path"> will already use the base dir if it is defined above.
Advantage: you can move your whole page to a subdirectory like http://www.domain.com/page and only have to change the <base> tag. If you use links like /support/index.php they will always start from the root directory (i.e. http://www.domain.com/)
Dynamic base dir for url rewrites:
<?php
if (preg_match("/https/i",$_SERVER["SERVER_PROTOCOL"]))
$protocol = "https";
else
$protocol = "http";
echo '<base href="'.$protocol.'://'.$_SERVER["HTTP_HOST"].dirname($_SERVER["SCRIPT_NAME"]).'/">';
?>

mod_rewrite browser trying to get content from non-existant dir

I have my mod_rewrite set up so that it redirects all requests that aren't targeting existing files or directories to index.php?req=* where * is the request.
Works all fine but when I send the browser to something like this:
http://myurl/A/B/C
The browser tries to find all images, stylesheets in the non-existing folder C. How can I make the browser to look in / instead of the 'virtual' directory?
Do I have to put an absolute path everywhere?
You need to use absolute URLs (or at least absolute URL paths) when referencing the resources. So http://example.com/foo/bar or /foo/bar instead of foo/bar or ./foo/bar.
Because otherwise the URL path of the current document is used as base path the relative paths are then resolved from.
Another way would be to change the base URL with the base element like:
<base href="/">
This will change the base URL path to /. But note that this will affect all relative URLs and not just those with a relative URL path.
Yes. Either like this:
<img src="/image.jpg" />
or using HTML's <base>.
I'd prefer altering the src, though. It's less of a hassle.

Categories