mod_rewrite browser trying to get content from non-existant dir - php

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.

Related

php script includes html in different directory

I have a form handler which is written in PHP and resides in a different directory than the html files. When the handler runs, it needs to include one of the html files. The html files have relative hrefs in them, which break because the page was served from the PHP directory, not the html directory.
For example, index.html contains
<link rel="stylesheet" type="text/css" href="css/site_global.css?4013920463"/>
These links are produced by Adobe Muse and expect that "css" is a subdirectory under the location of the html files and that the page was served from the html directory. Again, since I'm serving the page from the PHP directory, the relative links break.
Short of putting in absolute paths for the hrefs, is there any other technique I should consider? I really don't want to put in absolute paths because they will break for other reasons.
Ideally, I'd like to use some sort of method that allows me to set the "working path" in the browser - so that I can tell it to fetch hrefs from the right place.
Relative paths in a browser are computed based on the current page path (see here). If you are looking at http://foo.bar/one/page.html , the site_global.css path will be http://foo.bar/one/css/site_global.css .
If I understood your question, you can use the element to set a base URL for all the relative links in the page.
See here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
try $_SERVER['DOCUMENT_ROOT'], gives the path to your base directory with current working dir
or
try echo realpath(dirname(FILE));

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.

mod_rewrite changes the current dir

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.

Change the default path where the web server looks for images

I'm trying to change the default path or add a path that the webserver looks for images. I really would really like a solution to do this in PHP and not in htaccess.
The most basic example would be trying to "break" the current implementation so say I have a directory with the following:
main/
image.png
index.php
In index.php:
<?php
// Change the directory WAY out of current directory
chdir('../../../');
echo getcwd(); // DEFINITELY NOT where image.png is located
?>
<img src="image.png" width="402" height="265" alt="1">
<!-- WHY ARE YOU STILL RENDERING?!?! -->
Let me know if you understand my point or if you have any questions.
Thanks all!
Matt Mueller
I think you're confusing the current working directory on the server filesystem and the web server document root.
When you create an image element in HTML, it (the browser) looks for the source based on a few parameters.
If the src path is relative (no leading slash), the image will load relative to the <base> element URL if set, otherwise the current URI
If the src path is absolute, the image will load from the absolute path from the document root, eg <img src="/foo/bar/baz.jpg"> will load from http://example.com/foo/bar/baz.jpg
If the src is an absolute URI, then it will simply load from that
The img tag is sent to the client.
changing the directory of the preprocessor will not change the client's directory, as that is fixed to the current page they are on, such as http://example.com/.
You would need to change each img tag's src to change the directory to look in.
To avoid future confusion, you could have a function that prefixes the correct directory.
e.g.
<img src = "<?php echo produceImageURL('image.png'); ?>" width = "402" height = "265" alt = "1" />
What is the relative path for PHP and the relative path for the page are two separate things.
You changed the directory for the current PHP script. However, the requested page and it's resources are still relative to main/index.php
jnpcl had it right:
<base href="../../../">
put that between your <head> </head> typically after <meta />, before you load any files

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"]).'/">';
?>

Categories