-1

My root folder is public_html. Outside of public_html I have a folder called images. In order for me to retrieve images from this folder I query the database for correct image name & extension in a file that is stored inside public_html folder -> forms folder -> check_images.php

My database output is:

$output['filetype'] -> jpg
$output['name'] -> 1

The variable $file is the relative path + the filename + filetype, which makes '../../images/1.jpg'.

Now for some reason fetching the image doesn't work, however file_exists() is working fine.

The header is:

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

What am I doing wrong? and why isn't readfile() or file_get_contents() working as it should when they are exactly the same folder as file_exists()

Entire code can be found here: http://pastebin.com/MhkAfY4s

What is currently being displayed is an empty image / or a broken image when being linked to.

UPDATE

  1. First I check the URL: http://pastebin.com/Fz36GmVD
  2. Then I run the image code: http://pastebin.com/fZSRuJ4r
Gjert
  • 1,069
  • 1
  • 18
  • 48

2 Answers2

1

What is happening is most likely that there is other output than the image, thus messing up the image binary data. Have a look at the source of the page, beware of any spaces before your <?php as well as any after the ending ?>one (which you should omit, as it is not needed)

To further help with large file downloads I suggest you use XSendFile to handle the heavy lifting for you.

Update:

To sum it up, the most likely reason to why it didnt work is the ob_start with gzhandler, simply removing it did not do anything, that probably because of the E-Tag and browser still showed cached content.

hank
  • 3,748
  • 1
  • 24
  • 37
  • I have already checked the empty spaces. Nothing there. Whenever I remove the `image header` I get a bunch of random letters output on the page... and with `image header` I get nothing. – Gjert Jul 05 '16 at 09:17
  • Can you pastebin the complete code, including the php-tags and also pastebin the full output, including headers. – hank Jul 05 '16 at 09:18
  • I added the pastebin, see update. Its the full code. The output is simply just the standard broken image from the browser. No code being displayed. – Gjert Jul 05 '16 at 09:25
  • View source and pastebin it still -- In one of the files you just added to the pastebin you use ob_start() and also with a gz_handler, did you just for testing try to remove those? – hank Jul 05 '16 at 09:28
  • I tried removing both, now I just get a bunch of letter output, looks like the image binary. – Gjert Jul 05 '16 at 09:31
  • right, so we are getting somewhere, now pastebin that and the headers (as shown in the developer tools) – hank Jul 05 '16 at 09:32
  • This is the pastebin: http://pastebin.com/BbAk0AKY and the header is: http://pastebin.com/PbzSX6Ce – Gjert Jul 05 '16 at 09:41
  • I have no idea what I just did, however the problem solved itself... I removed the gz_handler completely from the code (commenting it out didnt seem to work) and then it all worked.. – Gjert Jul 05 '16 at 10:25
  • 1
    My guess is that the E-Tag and/or cache policy forced your browser to show old content. The ob_start with gzhandler was probably the reason. – hank Jul 05 '16 at 10:37
0
  • You have done some small errors
  • header('Content-type: image/jpeg') should go before image content
  • check you folder setting shout it be ../ or ../../

So your is php code:

$file_name = (int)$routes[2];
$file = '../images/'.$file_name;

$sql = "SELECT i.image_filetype as filetype, i.image_type as type, i.image_key "
        . "FROM images i "
        . "WHERE i.image_deleted IS NULL "
        . "AND i.image_id = :filename LIMIT 1";

$results = $db_connect->prepare($sql);
$results->bindParam(':filename', $file_name, PDO::PARAM_INT);
$results->execute();
$db_image = $results->fetchAll(PDO::FETCH_ASSOC);
foreach($db_image as $output){
    // PROFILE PICTURE
    if($output['type'] === '1'){
        $path = $file.'.'.$output['filetype'];
        if(file_exists($path)){
            header('Content-type: image/jpeg');
            echo file_get_contents($path);
            exit;
        }else{$error_code = 4;}
    }
}
die('1');

updated code:

not sure what you are doing wrong but below code works for me. So pls provide result details. My image file id godaddy2.jpg in parent images folder.

<?php
// ROUTES[2] IS = IMAGE_ID + UNIQID
// EXAMPLE: 23
//$file_name = (int)$routes[2];

$file_name = 'godaddy2';

//$file = '/home/husliste/images/'.$file_name;

$file = '../images/'.$file_name;
//
//$sql = "SELECT i.image_filetype as filetype, i.image_type as type, i.image_key "
//        . "FROM images i "
//        . "WHERE i.image_deleted IS NULL "
//        . "AND i.image_id = :filename LIMIT 1";
//$results = $db_connect->prepare($sql);
//$results->bindParam(':filename', $file_name, PDO::PARAM_INT);
//$results->execute();
//$db_image = $results->fetchAll(PDO::FETCH_ASSOC);
$db_image[] = [
    'filetype' =>'jpg',
    'type' =>'1',
];

function checkPlanAccess($a){
    return true;
}
foreach($db_image as $output){
    if($output['type']){
        // CREATE HEADER
        switch($output['filetype']){
            case "gif": $ctype="image/gif"; break;
            case "png": $ctype="image/png"; break;
            case "jpeg":
            case "jpg": $ctype="image/jpeg";break;
            default:
        }
        header('Content-type: '.$ctype);
        // CREATE FILE PATH
        $file_path = $file.'.'.$output['filetype'];
        // =========================================== //
        // PLAN
        if($output['type'] === '1'){
            if(checkPlanAccess($output['image_key'])){
                if(file_exists($file_path)){
                    echo file_get_contents($file_path);
                }else{$error_code = 4;}
            }else{$error_code = 4;}
        }
        // PROFILE PICTURE
        elseif($output['type'] === '2' && $check_session){
            if(file_exists($file_path)){
                $image = file_get_contents($file_path);
                echo $image;
            }else{$error_code = 4;}
        }
        // COMPANY LOGO
        elseif($output['type'] === '3' && $check_session){
            if(file_exists($file_path)){
                echo file_get_contents($file_path);
            }else{$error_code = 4;}
        }
        // CUSTOMER LOGO
        elseif($output['type'] === '4'){
            if(checkCustomerAccess($output['image_key'])){
                if(file_exists($file_path)){
                    echo file_get_contents($file_path);
                }else{$error_code = 4;}
            }else{$error_code = 4;}
        }
        // CUSTOMER PROJECT IMAGES
        elseif($output['type'] === '5'){
            if(checkCustomerProjectAccess($output['image_key'])){
                if(file_exists($file_path)){
                    echo file_get_contents($file_path);
                }else{$error_code = 4;}
            }else{$error_code = 4;}
        }
        // SUPPLIER LOGO
        elseif($output['type'] === '6'){
            if(checkSupplierAccess($output['image_key'])){
                if(file_exists($file_path)){
                    echo file_get_contents($file_path);
                }else{$error_code = 4;}
            }else{$error_code = 4;}
        }else{
            $error_code = 4;
        }
    }else{
        $error_code = 4;
    }
}
die('1');
?>
Maksym Semenykhin
  • 1,924
  • 15
  • 26
  • I have tested both of these, and there is still the same output. See updated code for latest test. However, when I add the wrong file path I get the output `1` – Gjert Jul 05 '16 at 09:23