2

I am loading images from a MySQL database, to display them in an Web GUI.

This is pretty standard and worked pretty well, till I tried to install the software in russia...

Here a example of the code that loads the image:

// Load overview image
if ($global_mode == 'overview') {

    // Load the image from the database.
    mysql_select_db("$db_x");   
    $sql = "SELECT $db_x.sensor_images.image
    FROM $db_x.sensor_images
    WHERE $db_x.sensor_images.image_id = '" . $global_image_id . "'";
    $sql = mysql_query($sql); 
    $row = mysql_fetch_assoc($sql);

    // Image output.
    header('Content-type: image/jpeg');
    echo $row['image'];
}

I installed the software on many european based laptops and I never had the problem, that images were not displayed...

Apparently on russian laptops (Windows 7, XAAMP, MySQL) this was not the case, images were not displayed.

I started to do some research and found out (on my laptop, where images get displayed...), that if I change the Encoding of the php file (in this case the show_image.php), I could replicate the error I had on russian laptops.

enter image description here

If the encoding is set to ANSI, the images get displayed...

Here I have disabled the header, so the browser displays the binary data (the encoding of the PHP file is set to ANSI)...

EXAMPLE A

enter image description here

Now I set the Encoding of the PHP file to UTF-8

enter image description here

By doing this images do not get displayed any more...

This is the output when I try to display the data without the header...

EXAMPLE B

enter image description here

As you can see, the output is different...

On my laptop (european):

ANSI: images get displayed, the data (without header) looks like EXAMPLE A

UTF-8: images get not displayed, the data (without header) looks like EXAMPLE B

On russian laptops:

ANSI: images get not displayed, the data (without header) looks like EXAMPLE B

UTF-8: images get not displayed, the data (without header) looks like EXAMPLE B

I still don't understand why changing the encoding of a php file has an impact on the output of binary data, respectively an image...

On the russian laptops the PHP files get always interpreted as if the encoding was set to UTF-8, no matter if I set it to ANSI or something else...

Please help!

Thx.

Andreas
  • 545
  • 2
  • 11
  • 24

3 Answers3

2

In your IDE you see "UTF-8" and "UTF-8 without BOM". You're choosing UTF-8, which in this case means with BOM. The BOM is prepended to the file and is the first thing that's output. This may a) break the output of your header, thereby breaking the data display, and b) giving the browser a clue that the following data is supposedly UTF-8 encoded, hence the browser is interpreting the data as UTF-8, which results in a lot of UNICODE REPLACEMENT CHARACTERS �. Check your error logs, you should see PHP complain about Headers already sent.

The data you're sending is always the same, it's just interpreted in different encodings depending on the machine's default and the presence or absence of a UTF-8 BOM.

The only reason it breaks at all under any circumstances is that you're outputting the wrong headers and/or are sending additional content before or after the image data. Check with a low-level tool like curl what exactly is output, and find and remove anything that doesn't belong.

Community
  • 1
  • 1
deceze
  • 510,633
  • 85
  • 743
  • 889
  • Hello, it seems indeed to be the BOM problem. For any reason the webserver sends the data without BOM on my laptop and with BOM on russian laptops. Setting the encoding does of the PHP file does not effect the output on russian laptops, it is the webserber is always sending with BOM and thereby causing the error. Is there any way, to configure apache or php, that it shall always send without BOM? – Andreas Feb 12 '14 at 08:18
0

Save the php File that sends out the picture as "UTF-8 w/o BOM".
If there are any files inlcuded, it is mandatory that they are saved as either "ANSI" or "UTF-8 w/o BOM", too.
There also must be no space nor any text before the <?php -Tag. If you want to send any text, e.g. an error message because the picture file is non-existent, you need to send the
header("Content-Type: charset=utf-8"); right before the text in order to display all characters correctly - but not in combination with the image:

    <?php
    include "/someSafeDir/utils.inc.php";
    $pic= secureGet($_GET['pic']);
    $imagePath=/somePath/
    $picture=$imagePath.$pic;
    if (file_exists($picture)){
        if ($fd = fopen ($picture, "r")) {
            $fsize = filesize($picture);
            header ("Content-type: image/jpeg"); 
            header ("Content-length: $fsize");
            readfile($picture);
        } else 
            echo "File \"$pic\"  could not be opened.\n";
        fclose ($fd);
    } else {
        header("Content-Type: text/html; charset=utf-8");
        echo "File \"$pic\" not existent";
    }
    ?>  
Ronald
  • 11
  • 3
0

It could be that your PHP server charset is not the correct one.

In your php.ini file, try having the following directive:

default_charset = "UTF-8"

And restart your server.

Stephane
  • 11,836
  • 25
  • 112
  • 175