views:

50

answers:

5

Hi !

How can i display an image on my webpage which i located above webscope? The image is located at /home/image.jpg and the website is located at /home/www/example.com/index.php which refers to http://example.com/.

I have tried this code to retrieve the image, but it does not work :(

    header('Content-type: image/jpeg');
    readfile( realpath( "/home/image.jpg" ));

And I have tried this version too:

    header('Content-type: image/jpeg');

    $image = imagecreatefromjpeg( realpath('../../image.jpg'));

    // OUTPUT IMAGE AND FREE MEMORY
    imagejpeg($image);  
    imagedestroy($image);  

When I try to read the file with this code:

    fopen( realpath( "../.." ) . '/image.jpg', 'r+' );

It returns this error

    Warning: fopen(/home/image.jpg) [function.fopen]: failed to open stream: No such file or directory in /home/www/example.com/image.php on line 4

Can anyone please help me? I am getting desperate!!!!!

Thanks in advance.

A: 

Make sure PHP is allowed to read the file, fopen($filename, 'r+'); will return FALSE if you can't.

Kevin Sedgley
Thanks for your answer! I tried this code **fopen( realpath( "../.." ) . '/image.jpg', 'r+' );** and it returns this error **Warning: fopen(/home/image.jpg) [function.fopen]: failed to open stream: No such file or directory in /home/www/example.com/image.php on line 4**. Is there anything i can do?
Mathias Bak
"No such file" is quite unambiguous.
VolkerK
I have spoken to the company which host my site. They say i can put files in the folder and then retrieve them with a php script. Its a key feature in my application, and i am willing to pay anyone to fix the problem. So if you think you can, just say so
Mathias Bak
A: 

I'll bet it's a permissions problem: The user your script is running under is likely not to be allowed to access files in /home.

Remove the content-type header, and turn on error_reporting(E_ALL);: PHP will tell you why it can't access the file.

If that is the problem, you'd do better to store the images elsewhere, though, and give that directory the necessary rights.

As a side note, there is no need to create and destroy an image as you do in your example (unless you want this explicitly, e.g. to remove ID3 and other metadata). A simple fpasshtru() will do.

$name = '/path/to/image';
$fp = fopen($name, 'rb');

// send the right headers
header("Content-Type: image/jpeg");
header("Content-Length: " . filesize($name));

// dump the picture and stop the script
fpassthru($fp);
exit;
Pekka
Do not bet. Nor guess. Predict and fortune tell as well. Read an error message and be sure.
Col. Shrapnel
It says the image does not exist, but i dont understand that... I can see it through my ftp program lol
Mathias Bak
@Mathias you are aware that the FTP program's root is not necessarily the system's absolute path?
Pekka
Yes, but that shouldn't matter when i use relative paths in my script right?
Mathias Bak
@Mathias not really, but it makes it harder to determine whether the file actually exists. Can you try a different directory?
Pekka
Unfortunately no. The only folders i have access to is **"/"** **"/www"** **"/www/example.com"**. The image is located in "/". I can't put anything in "/www" and "/www/example.com" is the root of my website. I can create a new folder in "/" and put the image in there, but that does not change anything (I have tried). I don't have a lot of options.
Mathias Bak
@Mathias maybe you should ask the provider for absolute paths. This is almost certainly a path problem.
Pekka
Should i just ask them to give me the path to the "real root" of the webserver and put that right into the code?
Mathias Bak
Or maby you know of another way of protecting your images in a proper way?
Mathias Bak
@Mathias how is this protecting the images? You are simply passing them through, aren't you?
Pekka
No. The idea is that it's only my script which can display the images. You cannot link to them, because they are not in the webscope. The only way you can get access to them i through a php-script which is located on my domain.
Mathias Bak
@Mathias but if the script does what you quote above, how is that different from having a direct image link? Are you going to add some additional security?
Pekka
Files above webscope can only be accessed through a PHP script located on the server itself. They can't see the image just by typing "http://example.com/directory/image.jpg" because the image is not located in the webscope and must be retrieved through a phpscript located on localhost. And in the php script i have implemented some security check to check if the user is logged in and has permission to see the image :)
Mathias Bak
@Mathias I get the part with the script, I just wanted to point out that that in itself is no protection :) Any results from VolkerK's suggestion?
Pekka
It don't list any files. In other words, it says that there are no files in the home folder. I really don't get it. I will try to find a company who can fix it for me. But thank you for your help!! It was very nice :-)
Mathias Bak
@Mathias no problem. If you want, you can E-Mail me your FTP data so I can take a look. I'm working but I can spare a few minutes.
Pekka
Is it possible your FTP account is chrooted and what it sees as `/home` is some entirely other directory of what the webserver sees as its own `/home`? You may very well be FTPing into `/home/users/<youraccount>/home` and your script is looking in the real `/home` instead.
Marc B
@Pekka It would be great if you could take a look at it. Where can i find your email adress? I can see your site is under development :)@Mark B Thanks for the tip!!
Mathias Bak
@Mathias look closely at my profile page :)
Pekka
@Pekka Haha i totally oversaw that xD An email has been sent.
Mathias Bak
A: 

Your first example is how it should be.
No need to look for anything else.

I have tried this code to retrieve the image, but it does not work :(

When the code doesn't work, a programmer ought to debug it, to find why. And repair.

So, you have to get an error message somehow. Did you look into error_log?

Col. Shrapnel
It says the image does not exist. Thats unfortunately my only clue :(
Mathias Bak
A: 

Let's add more error handling to your script

<?php
$path = '/home/image.jpg';

$fp = fopen($path, 'rb');
if ( !$fp ) {
  foo($path);
}

if ( !headers_sent() ) {
  header('Content-type: image/jpeg');
  fpassthru($fp);
}

die;
function foo($path) {
  echo 'failed'; flush();

  $out = date("Y-m-d H:i:s\n");
  $out .= " cwd=".getcwd()."\n";
  $out .= " fopen($path) failed\n";
  $dir = dirname($path);
  if ( !is_dir($dir) ) {
    $out .= " $dir is NOT a directory\n";
  }
  else {
    $out .= " $dir contains the following files:\n";
    foreach(glob($dir.'/*') as $fn) {
      $out .= '   '.$fn."\n";
    }
  }
  $out .= "\n\n";

  error_log($out, 3, 'soError.log');
}

Keep an eye on the file soError.log.

VolkerK
Thank you very much for the code!! I have tried it with different directories and got some interesting results. I just dont have the knowledge to read the errormessages properly :(
Mathias Bak
A: 

Perhaps your webhost has open_basedir configured, and the /home directory is outside its limits, making the image unreachable by your script.

You can check if it's set by doing ini_get('open_basedir'); and seeing what's returned.

Marc B
open_basedir() is set to "no value". What does that mean?
Mathias Bak
Means it's not restricted, so an open_basedir restriction isn't causing this problem.
Marc B
Ok :-) Nice to have that option eliminated. One down, lots to go xD Thank you!
Mathias Bak