13

I'm making an intranet for a post-sale customer service entreprise. Employee need to be able to upload img files to the intranet's server and i need to store them in a directory with is BEFORE www (the website's root directory).

Doing this using php is pretty easy but how to include these imgs on the website once they're uploaded ? I tried this code

<img src="../img/img.png"/>

This is not working because i can't send a file if it is OUTSIDE the server's www directory ...

Is there any proper way to do that ?

Current treeview :

server root directory
           |www
               |(all server files)
           |img
               |(all img files)

(the server's index.php is located in www and the files are in img)

Charles
  • 48,924
  • 13
  • 96
  • 136
Weacked
  • 914
  • 2
  • 7
  • 18
  • Why you want to put these files outside web root? You want to hide them? – Kamil Nov 13 '12 at 09:19
  • Because another team will access these files using FTP and work with them, so these files can't be in the server directory – Weacked Nov 13 '12 at 09:21
  • So you want to copy these files by using php? – Kamil Nov 13 '12 at 09:29
  • copying the requested file in a tmp directory might be a solution, that's why i am currently asking for advices – Weacked Nov 13 '12 at 09:35
  • Then my advicde is: create virtual directory that will be accessible from apache (from php). You can copy files from there (by using php) and serve them from another location. Don't forget to give read permissions on source files. – Kamil Nov 13 '12 at 09:45

5 Answers5

18

You cannot directly access any file outside your web directory. As your question includes the tag PHP as well, I assume you may want to use it.

What you can do is the following:

Inside your www directory, create a "image.php" file, with a similar content to:

<?php
  header('Content-Type: image/png');
  readfile("../img/" . $_GET['img']);
?>

And call your images with

<img src="image.php?img=myimage.png" />

Please be aware that your PHP file shouldn't be that simple :) As you may want to address multiple image formats (and providing the correct header for them), checking for malicious file path/inclusions (you don't want to use $_GET without validating/sanitizing the input), extra caching etc. etc. etc.

But this should give you an idea on how you can target your issue.

Briareos386
  • 1,697
  • 17
  • 31
7

It depends on what you are trying to accomplish and how. With "simple" html commands it is as you found out. You can't go to a directory outside of the www root. (for xampp applications on C for exmple it is most of the time c:\xampp\htdocs).

If you are ok with using serverside commands to accomplish what you want to achieve then you could use php to do a workaround, by reading the appropriate files in via PHP. For example if your file is named "myimg.gif" and lies in "c:\pics"

<img SRC="data:image/gif;base64,<?php echo base64_encode(file_get_contents("c:\pics\myimg.gif"));?>">

With that you are reading the contents of the file and writing it directly into the img tag. Be aware that you need to change image/gif to what you really need there.

Thomas
  • 2,768
  • 3
  • 28
  • 63
  • I was aware of the data hack, but this really isn't cross browser, for instance IE8 limit the file to 32 ko ... – Weacked Nov 13 '12 at 09:30
  • 1
    That is interesting. I wasn't aware of that limit for IE8. If that is the case then the solution made by "GeneSys" would be the way to go there (with additional security parts so that it can't be used to hack your site). – Thomas Nov 13 '12 at 09:32
  • @ThomasE. Wikipedia (http://en.wikipedia.org/wiki/Data_URI_scheme#Disadvantages) lists a few disadvantages when using the data scheme. Nevertheless, if only a few, small images would have been included, I guess your way would probably be the one with the least "footprint". – Briareos386 Nov 13 '12 at 09:37
  • @GeneSys: Tnx. the part about the caching is very interesting there. – Thomas Nov 13 '12 at 09:49
  • PHP has a function for reading mimetype, you dont have to do it manually http://php.net/manual/en/function.mime-content-type.php – Kamil Nov 13 '12 at 10:51
5

You can't directly access file outside/above your root directory (www or public_html).

You can create virtual directory in Apache server configuration. Google "apache virtual directory" for more information.

Virtual directory configuration example:

<IfModule alias_module>
  Alias /uploaded_images/ "/home/someuser/somewhere"
  <Directory "/home/someuser/somewhere">
    Allow from all
  </Directory>
</IfModule>

uploaded_images directory will be available from web like normal directory in www directory. You can copy files from there to another location (kind of buffering).

You can also open/copy that file by ftp from php level without changing anything in apache, but this may be really slow (use it only if you can't control apache config, virtual directory is much better).

php.net: FTP

Kamil
  • 11,919
  • 23
  • 72
  • 160
1

I Agree with @kamil's idea about creating a virtual directory. However if you want to go the php route, I wrote some code that open's images in a directory before WWW and copies them to the www/images folder.

<?php 
$imagepath = "../images/";
define('IMGPATH', realpath($imagepath).DIRECTORY_SEPARATOR);
$cachewwwimg = "images/";
$imagename = 'image.jpg';
copy(IMGPATH.$imagename, $cachewwwimg.$imagename)
?>

<img src="<?php echo $cacheimg.$imagename;?>"/>
Community
  • 1
  • 1
Jefri P.
  • 76
  • 3
  • 1
    What's the benefit of copying the files into a "virtual" (temporary?) directory and have the webserver load the file from there, instead of just "throughputting" the file via PHP? – Briareos386 Nov 13 '12 at 09:53
  • 1
    @GeneSys : Weacked is asking for php way because he doesn't want another team accessed server directory. – Jefri P. Nov 13 '12 at 09:59
  • Well .. you can achieve what I asked with PHP too? In fact, I even gave the answer already. I was just asking: Why would one want to copy files instead of just outputting them? – Briareos386 Nov 13 '12 at 10:03
0

I solved this by simply creating a symbolic link pointing to the global physical folder on my hosting. I didn't have root access, so I created a simple PHP file, calling it symbolic_link.php, that i put in the root of my website and that creates the symbolic link for me. Here it is:

<?php
$target = '/home/<user>/images/';   // hosting physical directory
$link = 'images';                   // symbolic link inside root of web site
unlink($link);
symlink($target, $link); 

After the creation of the symbolic link, I deleted the file.

This is the hosting directory structure:

/home/<user>                        // hosting root   
|
+--/images                          // hosting global dir
|  |
|  +--/logo.png                     // global image
|
+--/www.website.com                 // hosting website dir
   |
   +--/images                       // symbolic link

Now you can use the image as if it were in your website folder:

<img src="https://www.website.com/images/logo.png" alt="..."> 
Sal Celli
  • 1,045
  • 7
  • 5